Full FFmpeg CLI parity for React Native on iOS and Android. Wraps the vendored FFmpegKit full-gpl 6.0.2 binaries behind a clean TurboModule and a small TypeScript surface.
⚠️ GPL-3.0. This package bundlesfull-gplffmpeg builds (x264, x265, libvidstab, xvid, etc.) which inherit the GPLv3 license. Apps that ship this library must comply with GPLv3 — including providing source on request. If you need a permissive variant, vendor thefull(LGPL) builds yourself; the native API is the same.
- React Native ≥ 0.79 with the new architecture enabled (default in 0.79+, mandatory in 0.82+)
- iOS 12.1+
- Android API 24+
- Node 18+ at install time (postinstall script runs on
npm install)
npm install react-native-ffmpeg-lib
# or
yarn add react-native-ffmpeg-libA postinstall script fetches the FFmpegKit binaries (~210MB) from this package's own GitHub Release and verifies sha256 before unpacking. Override the source with FFMPEG_LIB_BINARIES_BASE_URL if you mirror them.
Then on iOS:
cd ios && pod installimport { FFmpeg, FFprobe, FFmpegPaths, FFmpegExport } from 'react-native-ffmpeg-lib';
const { cache } = FFmpegPaths.getDirectories();
const out = `${cache}/out.mp4`;
// Async — almost always what you want. Runs ffmpeg on a background thread.
const result = await FFmpeg.execute(
`-y -f lavfi -i testsrc=duration=3:size=640x480:rate=30 -c:v mpeg4 ${out}`
);
console.log(result.returnCode, `${result.durationMs}ms`);
// ffprobe → media info JSON
const info = await FFprobe.getMediaInfo(out);
// Native share sheet
await FFmpegExport.share(out);executeSync exists for parity with the FFmpegKit synchronous API. It blocks the JS thread for the entire ffmpeg run — no UI updates, no other JS, no timers. Use it only for sub-second operations:
import { FFmpeg } from 'react-native-ffmpeg-lib';
// OK: quick remux / metadata read — finishes in < 100ms.
const r = FFmpeg.executeSync(`-y -i in.mp4 -c copy out.mp4`);
// NOT OK: real transcoding will freeze the app for seconds.
// FFmpeg.executeSync(`-i big.mov -c:v libx264 out.mp4`); ← don'tFor anything that takes more than a frame, use FFmpeg.execute(...) instead.
| Symbol | Sync? | Description |
|---|---|---|
FFmpeg.execute(cmd) |
no | Returns Promise<ExecuteResult>. Runs on a background queue. |
FFmpeg.executeSync(cmd) |
yes | Returns ExecuteResult directly. Blocks the JS thread. |
FFmpeg.cancel(sessionId) |
yes | Cancels a running async session. |
FFprobe.getMediaInfo<T>(path) |
no | Promise<T> of parsed ffprobe JSON. |
FFmpegPaths.getDirectories() |
yes | { temp, cache, document } — instant, just returns platform constants. |
FFmpegExport.share(path) |
no | Presents the native share sheet (iOS) / chooser (Android). Promise<bool>. |
{
sessionId: number; // pass to cancel()
returnCode: number; // 0 = success, non-zero = ffmpeg error
output: string; // combined stdout + stderr from ffmpeg
durationMs: number;
}If pod install && xcodebuild fails with errors like:
fmt/include/fmt/format-inl.h:59:24: error: call to consteval function ... is not a constant expression
…add this patch to your app's ios/Podfile post_install block:
post_install do |installer|
# ... your existing react_native_post_install call ...
base_h = File.join(installer.sandbox.root, 'fmt', 'include', 'fmt', 'base.h')
if File.exist?(base_h)
contents = File.read(base_h)
unless contents.include?('FMT_USE_CONSTEVAL 0 /* patched */')
File.chmod(0644, base_h)
patched = contents.gsub(
/^(\s*#\s*define\s+FMT_USE_CONSTEVAL)\s+1\b/,
'\\1 0 /* patched */'
)
File.write(base_h, patched)
end
end
endThis is a workaround until React Native bumps fmt to 11.1+, which fixes the consteval evaluation under newer Apple Clang.
Set FFMPEG_LIB_BINARIES_BASE_URL to a mirror (corporate proxy, internal artifact store), then reinstall:
FFMPEG_LIB_BINARIES_BASE_URL=https://mirror.example.com/ffmpeg-lib npm installDrop the artifacts in place before running install and the postinstall will detect them and skip:
ios/Frameworks/ffmpegkit.xcframework/...
android/libs/ffmpeg-kit-full-gpl-6.0.aar
- Taner Sener / Arthenica — original FFmpegKit (archived 2025-06)
- FFmpeg — the engine itself
GPL-3.0. See LICENSE.