How to Use FFmpeg with Node.js (No Installation Required)

You need to process video in your Node.js app. Maybe you're building a SaaS that generates thumbnails, transcoding user uploads, or automating video workflows. The first thing you Google is "ffmpeg node.js." And that's where the pain starts.
FFmpeg is the most capable video processing tool out there. But getting it to work reliably in a Node.js environment means dealing with binary dependencies, platform-specific builds, memory management, and deployment headaches. There are several ways to approach this, each with real tradeoffs.
Using child_process.spawn with FFmpeg
The most direct approach. Install FFmpeg on your system, then call it from Node.js:
const { spawn } = require('child_process');
const ffmpeg = spawn('ffmpeg', [
'-i', 'input.mp4',
'-c:v', 'libx264',
'-crf', '23',
'-preset', 'medium',
'-c:a', 'aac',
'-b:a', '192k',
'output.mp4'
]);
ffmpeg.stderr.on('data', (data) => {
console.log(`FFmpeg: ${data}`);
});
ffmpeg.on('close', (code) => {
console.log(`FFmpeg exited with code ${code}`);
});
This works fine. But you're responsible for everything: installing FFmpeg on every machine that runs your code, parsing stderr for progress, handling errors when the binary isn't found, and making sure the right codecs are compiled in. On Docker, you're adding 80-200MB to your image just for the FFmpeg binary.
Using fluent-ffmpeg in Node.js
fluent-ffmpeg is the most popular Node.js wrapper for FFmpeg, with over 2 million weekly npm downloads. It gives you a chainable API instead of raw command-line arguments:
const ffmpeg = require('fluent-ffmpeg');
ffmpeg('input.mp4')
.videoCodec('libx264')
.audioCodec('aac')
.size('1280x720')
.on('end', () => console.log('Done'))
.on('error', (err) => console.error('Error:', err.message))
.save('output.mp4');
The API is cleaner, but fluent-ffmpeg still requires FFmpeg installed on the host machine. It's a wrapper, not a replacement. You'll also run into maintenance concerns. The GitHub repo has hundreds of open issues and updates are infrequent.
Running FFmpeg in the Browser with ffmpeg.wasm
ffmpeg.wasm compiles FFmpeg to WebAssembly, so it runs entirely in the browser or in Node.js without a native binary:
const { FFmpeg } = require('@ffmpeg/ffmpeg');
const ffmpeg = new FFmpeg();
await ffmpeg.load();
await ffmpeg.writeFile('input.mp4', inputData);
await ffmpeg.exec(['-i', 'input.mp4', '-c:v', 'libx264', 'output.mp4']);
const data = await ffmpeg.readFile('output.mp4');
No installation needed. But the tradeoffs are significant: processing speed is 10-20x slower than native FFmpeg, memory is limited (large files will crash the tab), and not all codecs are available in the WASM build. It works for lightweight client-side operations like trimming a clip or extracting a frame. Don't try to transcode a 2GB file with it.
Processing Video with a Cloud API (Zero Install)
If you don't want to manage FFmpeg binaries at all, you can offload video processing to a cloud API. FFmpeg Micro gives you full FFmpeg capabilities through simple HTTP requests:
const response = await fetch('https://api.ffmpeg-micro.com/v1/transcodes', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
inputs: [{ url: 'https://example.com/input.mp4' }],
outputFormat: 'mp4',
preset: { quality: 'high', resolution: '1080p' }
})
});
const job = await response.json();
console.log(`Job ${job.id} queued, status: ${job.status}`);
No binary to install. No Docker image bloat. No memory management. You send a URL, pick your output format, and get results back. For advanced use cases, pass raw FFmpeg options instead of presets:
const response = await fetch('https://api.ffmpeg-micro.com/v1/transcodes', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
inputs: [{ url: 'https://example.com/input.mp4' }],
outputFormat: 'webm',
options: [
{ option: '-c:v', argument: 'libvpx-vp9' },
{ option: '-crf', argument: '30' },
{ option: '-b:v', argument: '0' }
]
})
});
The API handles scaling, codec management, and infrastructure. You write a fetch call.
Which Approach Should You Use
child_process.spawn if you need full control and you're comfortable managing FFmpeg installations across all your environments.
fluent-ffmpeg if you want a nicer API on top of child_process and don't mind the native FFmpeg dependency.
ffmpeg.wasm if you need client-side processing for small files and can accept slower performance.
A cloud API like FFmpeg Micro if you want zero operational overhead, your app processes video at any scale, or you're deploying to serverless environments where installing FFmpeg isn't practical.
Common Pitfalls with FFmpeg in Node.js
Binary not found errors. The most common issue. Your code works locally but fails in CI or production because FFmpeg isn't in the PATH. With child_process and fluent-ffmpeg, always verify the binary exists before processing.
Memory spikes on large files. Spawning FFmpeg as a child process for a 2GB video can spike your Node.js process memory. Stream the output instead of buffering it all at once.
Codec mismatches. Your local FFmpeg build might include libx265 but the production server's build doesn't. Always run ffmpeg -codecs on your deployment target to confirm.
Silent failures. FFmpeg writes most of its output to stderr, not stdout. If you're only listening to stdout, you'll miss errors entirely.
Frequently Asked Questions
Do I need to install FFmpeg to use it with Node.js?
It depends on the approach. child_process and fluent-ffmpeg both require FFmpeg installed on the machine. ffmpeg.wasm bundles a WebAssembly version so no install is needed, but it's 10-20x slower. Cloud APIs like FFmpeg Micro handle processing entirely server-side, so your Node.js app never touches FFmpeg.
Is fluent-ffmpeg still maintained?
fluent-ffmpeg has over 2 million weekly npm downloads, but the GitHub repository has limited recent activity and hundreds of open issues. It works for common use cases, but you may hit edge cases that won't get patched quickly.
Can I use FFmpeg in a serverless function like AWS Lambda?
You can bundle a static FFmpeg binary in your deployment package. But Lambda functions have memory limits (256MB-10GB), execution time limits (15 minutes max), and cold start penalties from the large binary. A cloud API is a better fit for serverless architectures because you offload the heavy processing entirely.
What's the fastest way to add video processing to a Node.js app?
A cloud API gets you from zero to processing video in under 10 minutes. One fetch call. No installation, no configuration, no infrastructure. FFmpeg Micro's free tier gives you enough processing time to build and test your integration. For a deeper look at FFmpeg concepts, check out the Learn FFmpeg course.
About Javid Jamae
Founder & CEO at FFmpeg Micro
Javid is a software engineer, author, and entrepreneur with over 25 years of professional software development experience across enterprise, startup, and consulting environments. He founded FFmpeg Micro to make video processing accessible to developers through a simple, automation-first REST API.
You might also like

How to Use FFmpeg in Python Without Installing It
Learn how to use FFmpeg in Python without installing the binary. Use a cloud API instead of subprocess for serverless-friendly video processing.

What Is an FFmpeg API? (And How to Use One Without Installing FFmpeg)
Learn what an FFmpeg API is, how it works, and how to use FFmpeg Micro's REST API to process video without installing FFmpeg or managing servers.

Getting Started with FFmpeg Micro: 5 API Examples
Learn how to use the FFmpeg Micro API with 5 practical examples: transcode video, resize to 720p, extract audio, add watermarks, and generate thumbnails.
Ready to process videos at scale?
Start using FFmpeg Micro's simple API today. No infrastructure required.
Get Started Free