High-performance vertical video feed for React Native, built on FlashList v2. Optional prefetch, poster-first, quality ladders, and RN Video disk cache for Instagram-like swipe UX.
- FlashList v2 snap paging (New Architecture)
- Auto play/pause from viewability + single-tap pause
- Double-tap like, mute controls, optional progress bar
- Opt-in HTTP/poster prefetch with directional warm-up
- Opt-in poster / blur-first until the first frame
- Opt-in RN Video disk cache (
videoCacheEnabled) - Optional progressive quality ladder / HLS-ready ABR docs
- Custom overlay and video engine via render props
- Decoder preload window to cap concurrent players
| Package | Version |
|---|---|
@shopify/flash-list |
>= 2.0.0 |
react-native-video |
>= 6.0.0 |
react-native-reanimated |
>= 4.0.0 |
react-native-worklets |
>= 0.12.0 |
react-native-gesture-handler |
>= 2.0.0 |
Requires the React Native New Architecture.
npm install react-native-flash-reels @shopify/flash-list react-native-video react-native-reanimated react-native-worklets react-native-gesture-handleryarn add react-native-flash-reels @shopify/flash-list react-native-video react-native-reanimated react-native-worklets react-native-gesture-handlerSee the installation guide for Babel / gesture-handler setup (and the optional iOS video-cache Podfile flag).
import {
FlashReels,
useFlashReels,
MuteButton,
} from 'react-native-flash-reels';
import type { ReelData } from 'react-native-flash-reels';
type Reel = ReelData & { username: string; caption: string };
const data: Reel[] = [
{
id: '1',
videoUri: 'https://example.com/one.mp4',
posterUri: 'https://example.com/one.jpg',
duration: 12.5,
username: 'maya',
caption: 'Golden hour',
},
];
function Overlay({ item }: { item: Reel }) {
const { isMuted } = useFlashReels();
return (
<>
<MuteButton />
<Text>@{item.username}</Text>
<Text>{item.caption}</Text>
<Text>{isMuted ? 'Muted' : 'Sound on'}</Text>
</>
);
}
export function ReelsScreen() {
return (
<FlashReels
data={data}
defaultMuted
showProgressBar
prefetchEnabled
prefetchWindowSize={2}
showPosterUntilReady
videoCacheEnabled
onLike={(item) => console.log('liked', item.id)}
renderOverlay={(item) => <Overlay item={item} />}
/>
);
}All of these default off so existing apps stay unchanged:
| Prop | What it does |
|---|---|
preloadWindowSize |
How many neighbors mount a real Video decoder (default 1) |
prefetchEnabled |
Warms posters + a tiny HTTP Range of upcoming URIs (no extra decoders) |
prefetchWindowSize / prefetchStrategy |
How far / how to bias prefetch (directional or symmetric) |
showPosterUntilReady / posterBlurRadius |
Keep posterUri visible until the first frame |
videoCacheEnabled / bufferConfig.cacheSizeMB |
RN Video disk cache (Android runtime; iOS needs Podfile flag) |
Pass posterUri when using showPosterUntilReady. Rank feeds on your backend and optionally set prefetchPriority on items.
Full guide: Performance.
Full API reference, guides, and examples are available on the official documentation website.
See CHANGELOG.md for release history (0.3.0).
Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.
- Report bugs in the Issue Tracker.
- Report security issues via SECURITY.md.
MIT


