react-native-view-recorder
v0.4.0
Published
Record any React Native view to MP4 video. Captures views (including Skia canvases) frame-by-frame using native APIs and encodes with hardware-accelerated H.264/HEVC. No FFmpeg, no GPL.
Maintainers
Readme
Features
- View-level capture: record a specific view, not the entire screen
- Works with Skia: captures
@shopify/react-native-skiacanvases and TextureViews - Hardware-accelerated: AVAssetWriter on iOS, MediaCodec on Android
- Audio support: mux audio files or generate samples per-frame via JS callback
- HEVC support: H.264, H.265, and HEVC with alpha (iOS)
- Snapshots: capture any view as a PNG or JPEG image (file or base64)
- Tiny footprint: ~90 KB of native code, zero third-party binaries
- MIT licensed: no GPL/LGPL concerns (unlike FFmpeg-based solutions)
- New Architecture: Fabric native component + TurboModule
Documentation
For full docs, examples, and API reference, visit react-native-view-recorder.awingender.com.
Installation
# expo
npx expo install react-native-view-recorder
# npm
npm install react-native-view-recorder
# bun
bun add react-native-view-recorderExpo Go does not support native modules. You need a development build.
Quick start
import { useState } from "react";
import { Button, Text, View } from "react-native";
import * as FileSystem from "expo-file-system";
import { RecordingView, useViewRecorder } from "react-native-view-recorder";
export default function App() {
const recorder = useViewRecorder();
const [frame, setFrame] = useState(0);
const handleRecord = async () => {
await recorder.record({
output: FileSystem.cacheDirectory + "video.mp4",
fps: 30,
totalFrames: 150,
onFrame: async ({ frameIndex }) => setFrame(frameIndex),
});
};
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<RecordingView
sessionId={recorder.sessionId}
style={{ width: 300, height: 200, backgroundColor: "#111" }}
>
<Text style={{ color: "#fff", fontSize: 48 }}>{frame}</Text>
</RecordingView>
<Button title="Record 5s" onPress={handleRecord} />
</View>
);
}Snapshot
Capture a single frame as an image:
const uri = await recorder.snapshot({
output: FileSystem.cacheDirectory + "photo.png",
format: "png",
});Works with the same RecordingView, no extra setup needed. Supports PNG, JPEG, custom dimensions, and base64 output.
Skia support
Record Skia canvases using useSkiaViewRecorder and SkiaRecordingView:
import { SkiaRecordingView, useSkiaViewRecorder } from "react-native-view-recorder";
import { Canvas, Circle } from "@shopify/react-native-skia";
function SkiaExample() {
const recorder = useSkiaViewRecorder();
return (
<SkiaRecordingView sessionId={recorder.sessionId} viewRef={recorder.viewRef}>
<Canvas style={{ width: 300, height: 300 }}>
<Circle cx={150} cy={150} r={100} color="cyan" />
</Canvas>
</SkiaRecordingView>
);
}Sponsoring
If this library helps you, particularly if you are a big company, consider sponsoring me. Helps a ton, thank you!
License
MIT
