react-native-flash-reels
v0.3.0
Published
Lightweight, customizable vertical video feed for React Native built on FlashList v2
Maintainers
Readme
Demo
Features
- 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
Requirements
| 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.
Installation
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).
Quick Start
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} />}
/>
);
}Prefetch & performance (opt-in)
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.
Documentation
Full API reference, guides, and examples are available on the official documentation website.
Changelog
See CHANGELOG.md for release history (0.3.0).
Contributing
Contributions are welcome! Please read CONTRIBUTING.md before submitting a pull request.
- Report bugs in the Issue Tracker.
- Report security issues via SECURITY.md.
License
MIT
