A video component for React Native desktop platforms (macOS, Windows, Linux) with a react-native-video compatible API.
react-native-video-desktop provides native video playback capabilities for React Native desktop applications. It's designed to be a drop-in replacement for react-native-video on desktop platforms, offering a familiar API while leveraging native video frameworks.
| Platform | Status | Framework |
|---|---|---|
| macOS | ✅ Implemented | AVKit |
| Windows | 🚧 Planned | Media Foundation |
| Linux | 🚧 Planned | GStreamer |
- ✅ Native video playback using platform-specific frameworks
- ✅ Compatible with
react-native-videoAPI - ✅ Support for local and remote video files
- ✅ Playback controls (play, pause, seek)
- ✅ Video styling (resize modes)
- ✅ Event callbacks (onLoad, onProgress, onEnd, etc.)
- ✅ TypeScript support
npm install @jdboivin/react-native-video-desktop
# or
yarn add @jdboivin/react-native-video-desktop
# or
pnpm add @jdboivin/react-native-video-desktopAfter installing the package, you need to install the CocoaPods dependencies:
cd macos && pod installThen rebuild your app:
npm run macos
# or
react-native run-macosComing soon
Coming soon
import React from "react"
import { View, StyleSheet } from "react-native"
import Video from "@jdboivin/react-native-video-desktop"
function App() {
return (
<View style={styles.container}>
<Video
source={{ uri: "https://example.com/video.mp4" }}
style={styles.video}
controls={true}
resizeMode="contain"
repeat={true}
onLoad={(data) => console.log("Video loaded", data)}
onProgress={(data) => console.log("Progress", data)}
onEnd={() => console.log("Video ended")}
/>
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
},
video: {
width: "100%",
height: 400,
},
})
export default Appsource: {
uri: string; // URL or local file path
headers?: object; // HTTP headers (for remote videos)
}| Prop | Type | Default | Description |
|---|---|---|---|
paused |
boolean | false |
Controls whether the media is paused |
repeat |
boolean | false |
Repeat the video when it ends |
rate |
number | 1.0 |
Playback rate (0.5 = half speed, 2.0 = double speed) |
volume |
number | 1.0 |
Volume level (0.0 to 1.0) |
muted |
boolean | false |
Mutes the audio |
controls |
boolean | false |
Show native playback controls |
seek |
number | - | Seek to specified time in seconds |
| Prop | Type | Default | Description |
|---|---|---|---|
resizeMode |
'contain' | 'cover' | 'stretch' | 'contain' |
How the video fits in the container |
style |
ViewStyle | - | Style for the video container |
poster |
string | - | Image to show before video loads |
| Callback | Description |
|---|---|
onLoad(data) |
Called when video loads successfully |
onProgress(data) |
Called periodically during playback |
onEnd() |
Called when video reaches the end |
onError(error) |
Called when an error occurs |
onBuffer(isBuffering) |
Called when buffering state changes |
onReadyForDisplay() |
Called when video is ready to be displayed |
onLoad:
{
duration: number // Video duration in seconds
currentTime: number // Current playback position
naturalSize: {
width: number
height: number
}
}onProgress:
{
currentTime: number // Current playback position
playableDuration: number
seekableDuration: number
}A complete sample macOS app is available in the sample directory. This demonstrates all features and serves as a reference implementation.
To run the sample app:
cd sample
npm install
npm run pods:macos
npm run macosThe sample app includes:
- Video playback with event logging
- All event handlers demonstrated
- Seek functionality
- Production build scripts (unsigned and signed)
See sample/README.md for more details.
This library aims to maintain API compatibility with react-native-video. However, some features may not be available on all platforms. The following table shows the current implementation status:
| Feature | macOS | Windows | Linux |
|---|---|---|---|
| Basic playback | ✅ | 🚧 | 🚧 |
| Controls | ✅ | 🚧 | 🚧 |
| Seeking | ✅ | 🚧 | 🚧 |
| Volume control | ✅ | 🚧 | 🚧 |
| Playback rate | ✅ | 🚧 | 🚧 |
| Resize modes | ✅ | 🚧 | 🚧 |
| Subtitles | ⏳ | 🚧 | 🚧 |
| DRM | ⏳ | 🚧 | 🚧 |
| Picture-in-Picture | ⏳ | 🚧 | 🚧 |
Legend: ✅ Implemented | 🚧 Planned | ⏳ Under consideration
The sample app uses Fastlane for building and code signing:
Unsigned Build (for testing):
cd sample
bundle install
bundle exec fastlane mac test_buildSigned Build with Fastlane Match (for distribution):
cd sample
bundle install
bundle exec fastlane mac releaseThis project uses Fastlane Match for code signing, which:
- ✅ Stores certificates in a git repository
- ✅ Syncs across team members and CI/CD
- ✅ Eliminates manual certificate management
See docs/CODE_SIGNING_FASTLANE.md for complete setup instructions.
The GitHub Actions workflow automatically builds and signs the sample app on every release:
- Set up Fastlane Match following docs/CODE_SIGNING_FASTLANE.md
- Configure GitHub secrets (Match repo URL, SSH key, passwords)
- Push to main - workflow automatically uses signed builds if Match is configured
- Node.js 18+
- React Native development environment set up for your target platform
- For macOS: Xcode and CocoaPods
git clone https://github.com/starburst997/react-native-video-desktop.git
cd react-native-video-desktop
npm install
npm run preparecd example
npm install
npm run macosContributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
See CONTRIBUTING.md for more details.
We're especially looking for contributors to help with:
- Windows implementation using Media Foundation
- Linux implementation using GStreamer
- Additional features (subtitles, DRM, etc.)
- Bug fixes and testing
MIT License - see the LICENSE file for details.
- Inspired by react-native-video
- Built for the react-native-macos community
- react-native-video - The original React Native video component for iOS and Android
- react-native-macos - React Native for macOS
- react-native-windows - React Native for Windows