Static FFmpeg binaries and development libraries for Node.js, packaged as platform-specific npm modules.
This repository builds and distributes FFmpeg with comprehensive codec support (H.264, H.265, VP9, AV1, SVT-AV1, Opus, MP3, AAC, FLAC, and more) as:
- Runtime packages:
@pproenca/ffmpeg-*— FFmpeg binaries for direct use - Development packages:
@pproenca/ffmpeg-dev-*— Static libraries + headers for native addon compilation - Main package:
@pproenca/ffmpeg— Meta-package with automatic platform detection - Hardware acceleration packages: Optional GPU-accelerated builds (VA-API, NVENC, VideoToolbox, DXVA2)
Built following the sharp-libvips distribution model.
npm install @pproenca/ffmpeg# Install dev package for your platform
npm install --save-dev @pproenca/ffmpeg-dev-linux-x64-glibcconst { ffmpegPath, ffprobePath } = require('@pproenca/ffmpeg');
const { execSync } = require('child_process');
// Get FFmpeg version
const version = execSync(`"${ffmpegPath}" -version`, { encoding: 'utf8' });
console.log(version);
// Transcode video
execSync(`"${ffmpegPath}" -i input.mp4 -c:v libx264 output.mp4`);{
'targets': [{
'target_name': 'addon',
'sources': ['addon.cc'],
'include_dirs': [
'<!@(node -p "require(\'path\').join(require.resolve(\'@pproenca/ffmpeg-dev-linux-x64-glibc/package.json\'), \'..\', \'include\')")',
],
'libraries': [
# Link directly against static libraries (no pkg-config needed)
'<!@(node -p "require(\'path\').join(require.resolve(\'@pproenca/ffmpeg-dev-linux-x64-glibc/package.json\'), \'..\', \'lib\')")/libavcodec.a',
'<!@(node -p "require(\'path\').join(require.resolve(\'@pproenca/ffmpeg-dev-linux-x64-glibc/package.json\'), \'..\', \'lib\')")/libavformat.a',
'<!@(node -p "require(\'path\').join(require.resolve(\'@pproenca/ffmpeg-dev-linux-x64-glibc/package.json\'), \'..\', \'lib\')")/libavutil.a',
# Add other FFmpeg libraries as needed (libswscale.a, libswresample.a, etc.)
],
}],
}Or set FFMPEG_ROOT in your environment for easier linking:
export FFMPEG_ROOT="$(npm root)/@pproenca/ffmpeg-dev-linux-x64-glibc"
# In your binding.gyp, reference libraries via environment variable
# libraries: ['<(FFMPEG_ROOT)/lib/libavcodec.a', ...]
npm run buildFor GPU-accelerated encoding/decoding (5-15x faster), install a hardware acceleration variant:
# Linux with Intel/AMD GPU
npm install @pproenca/ffmpeg-linux-x64-glibc-vaapi
# Linux with NVIDIA GPU
npm install @pproenca/ffmpeg-linux-x64-glibc-nvenc
# Windows with GPU decode
npm install @pproenca/ffmpeg-windows-x64-dxva2Use with the hardwareAccel option:
const { getBinaryPath } = require('@pproenca/ffmpeg');
// Use hardware acceleration if available, fall back to software
const ffmpegPath = getBinaryPath('ffmpeg', { hardwareAccel: 'vaapi' });Note: macOS builds include VideoToolbox hardware acceleration by default (no separate package needed).
See: HARDWARE.md for detailed setup, usage examples, and performance comparisons.
| Platform | Runtime Package | Dev Package |
|---|---|---|
| darwin-x64 | @pproenca/ffmpeg-darwin |
@pproenca/ffmpeg-dev-darwin |
| linux-x64 (glibc) | @pproenca/ffmpeg-linux-x64-glibc |
N/A |
| linux-x64 (musl) | @pproenca/ffmpeg-linux-x64-musl |
N/A |
| linux-arm64 (glibc) | @pproenca/ffmpeg-linux-arm64-glibc |
N/A |
| linux-arm64 (musl) | @pproenca/ffmpeg-linux-arm64-musl |
N/A |
| linux-arm (glibc) | @pproenca/ffmpeg-linux-armv7-glibc |
N/A |
| win32-x64 | @pproenca/ffmpeg-windows-x64 |
N/A |
1 Universal binary (x64 + ARM64) with built-in VideoToolbox hardware acceleration
| Platform | Runtime Package | Description |
|---|---|---|
| Linux VA-API | @pproenca/ffmpeg-linux-x64-glibc-vaapi |
Intel/AMD GPU acceleration (5-8x faster) |
| Linux NVENC | @pproenca/ffmpeg-linux-x64-glibc-nvenc |
NVIDIA GPU acceleration (10-15x faster) |
| Windows DXVA2 | @pproenca/ffmpeg-windows-x64-dxva2 |
Windows GPU decode acceleration |
See HARDWARE.md for hardware acceleration setup and usage.
Requirements:
- macOS: 11.0 (Big Sur) or later
- Linux (glibc): Ubuntu 24.04 or equivalent (glibc 2.35+)
- Linux (musl): Alpine 3.21 or later
- Windows: Windows 10 or later (x64)
- ARM platforms: Raspberry Pi 2/3/4/5, AWS Graviton, NVIDIA Jetson
| Codec | Library | License | Description |
|---|---|---|---|
| H264 | libx264 | GPL-2.0-or-later | H.264/AVC - Most widely supported video codec |
| H265 | libx265 | GPL-2.0-or-later | H.265/HEVC - Better compression than H.264 |
| VP8 | libvpx | BSD-3-Clause | VP8 - WebM video codec |
| VP9 | libvpx | BSD-3-Clause | VP9 - Improved WebM codec (shares libvpx with VP8) |
| AV1 | libaom | BSD-2-Clause | AV1 - Royalty-free next-gen codec (reference encoder) |
| SVT-AV1 | libsvtav1 | BSD-2-Clause | SVT-AV1 - Intel's optimized AV1 encoder (faster than libaom) |
| THEORA | libtheora | BSD-3-Clause | Theora - Legacy Ogg video codec |
| XVID | libxvid | GPL-2.0-or-later | Xvid - MPEG-4 ASP codec |
| Codec | Library | License | Description |
|---|---|---|---|
| OPUS | libopus | BSD-3-Clause | Opus - Best quality/bitrate for voice and music |
| MP3 | libmp3lame | LGPL-2.1-or-later | MP3 - Universal audio codec (LAME encoder) |
| AAC | native | LGPL-2.1-or-later | AAC - FFmpeg native encoder |
| FDK-AAC | libfdk-aac | Non-free | fdk-aac - High-quality AAC encoder (better than native) |
| FLAC | libflac | BSD-3-Clause | FLAC - Lossless audio compression |
| SPEEX | libspeex | BSD-3-Clause | Speex - Speech codec (optimized for voice) |
| VORBIS | libvorbis | BSD-3-Clause | Vorbis - Ogg audio codec |
- libass (ISC) - Advanced subtitle rendering
- libfreetype (FreeType License) - Font rendering
See CODECS.md for detailed licensing and codec information.
- Binaries: ffmpeg, ffprobe (statically linked, self-contained)
- Static Libraries: libx264.a, libx265.a, libvpx.a, libaom.a, libopus.a, libmp3lame.a, etc.
- Headers: Include files for all libraries (libavcodec, libavformat, libavutil, etc.)
- PKGConfig files (.pc): Not needed for static builds; removed to avoid path issues
- Libtool files (.la): Can cause relocation issues; removed
- CMake files: Build-time only; removed from distribution
This project distributes ready-to-use FFmpeg binaries, not development libraries. All dependencies are statically linked into the final binaries, making them completely self-contained with no external dependencies.
- macOS: Xcode Command Line Tools, Homebrew
- Linux: Docker (for reproducible builds)
- All: Node.js 20+, Git
# Clone repository
git clone https://github.com/pproenca/ffmpeg-prebuilds.git
cd ffmpeg-prebuilds
# Install dependencies
npm install
# Build for your current platform
./build/orchestrator.sh darwin-arm64 # macOS ARM64
./build/orchestrator.sh linux-x64-glibc # Linux (Docker)
# Verify build
./build/verify.sh darwin-arm64
# Create npm packages
npm run packagegit tag v8.0.0
git push --tags
# GitHub Actions will build all platforms in parallelAll codec versions are centralized in versions.properties:
FFMPEG_VERSION=n8.0
X264_VERSION=stable
X265_VERSION=4.0
LIBVPX_VERSION=v1.15.2
LIBAOM_VERSION=v3.12.1
# ... etcTo update dependencies:
- Run
npm run fetch-versionsto preview updates - Update
versions.properties(or runnpm run fetch-versions:write) - Bump
CACHE_VERSIONto invalidate CI cache - Run builds locally to test
- Create a git tag and push to trigger release
The repository uses GitHub Actions for automated builds:
- build.yml: Matrix builds for all platforms (parallel, ~30min total)
- release.yml: Publishes to npm on version tags (
v*)
Tag Push (v8.0.0)
↓
Matrix Build (darwin-x64, darwin-arm64, linux-x64-glibc, linux-x64-musl)
↓
Create npm packages (runtime + dev)
↓
Publish to npm (@pproenca scope)
↓
Create GitHub Release (with binary tarballs)
# Build one platform
./build/orchestrator.sh darwin-arm64
# Verify output
ls -lh artifacts/darwin-arm64/
# Create packages
npm run package
# Test package installation
cd /tmp
npm install /path/to/ffmpeg-prebuilds/npm-dist/@pproenca/ffmpeg-darwin-arm64
# Verify binary works
node -e "console.log(require('@pproenca/ffmpeg').ffmpegPath)"- Create
platforms/<new-platform>/Dockerfile(for Docker-based builds) - Add platform to
PLATFORMSarray inscripts/package-npm.ts - Update
build/orchestrator.shrouting logic - Add matrix entry to
.github/workflows/build.yml - Test build locally
- Update this README
ffmpeg-prebuilds/
├── build/
│ ├── orchestrator.sh # Delegates to platform scripts
│ ├── macos.sh # macOS native builds
│ ├── linux.sh # Docker-based Linux builds
│ └── verify.sh # ABI validation
├── platforms/
│ ├── linux-x64-glibc/Dockerfile
│ ├── linux-x64-musl/Dockerfile
│ └── darwin-*/README.md # Native runner docs
├── scripts/
│ └── package-npm.ts # Creates npm packages from artifacts
├── versions.properties # Single source of truth for versions
└── .github/workflows/
├── build.yml # Parallel matrix builds
└── release.yml # npm publishing
GPL-2.0-or-later
This package includes FFmpeg with x264 and x265, which are licensed under GPL v2+. Therefore, the entire distribution must be GPL v2 or later.
Individual codec licenses:
- FFmpeg: LGPL v2.1+ or GPL v2+ (we distribute GPL version)
- x264, x265: GPL v2+
- libvpx, libaom, Opus, Vorbis, Ogg: BSD
See LICENSE for full details.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Test builds on your platform
- Commit changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
When reporting bugs, please include:
- Platform (macOS/Linux, architecture, libc variant)
- FFmpeg version (from
versions.properties) - Full error output
- Steps to reproduce
- node-webcodecs - W3C WebCodecs API for Node.js (uses these prebuilts)
- sharp-libvips - Inspiration for this distribution model
- FFmpeg - The multimedia framework we're packaging
- FFmpeg team for the amazing multimedia framework
- Lovell Fuller for the sharp-libvips distribution pattern
- VideoLAN for x264
- MulticoreWare for x265
- Google/Chromium for libvpx
- Alliance for Open Media for libaom
- Issues: GitHub Issues
- Discussions: GitHub Discussions