How to Render MP4s in a Node.js API Without FFmpeg
May 21, 2026 · By VideoFlowLearn how to build a high-performance video rendering API in Node.js using VideoFlow and WebCodecs, completely bypassing the need for manual FFmpeg management.
How to Render MP4s in a Node.js API Without FFmpeg
For years, the standard way to programmatically generate video in Node.js has been a variation of the same theme: spawning a child process, concatenating a massive string of FFmpeg flags, and crossing your fingers that the server environment has the right binaries installed. It’s a workflow that is fragile, difficult to debug, and nearly impossible to scale without significant infrastructure overhead.
But what if you could treat video like any other part of your TypeScript stack? What if you could render an MP4 as easily as you render a JSON response or a React component?
In this guide, we’ll look at how VideoFlow lets you build a high-performance video rendering API in Node.js using WebCodecs and headless Chromium, completely bypassing the need for manual FFmpeg management.
The "No-FFmpeg" Architecture
Traditional video pipelines rely on FFmpeg to handle everything from frame composition to encoding. VideoFlow takes a different approach. By leveraging the VideoFlow renderers, specifically @videoflow/renderer-server, you can drive a headless browser instance (via Playwright) to perform frame-accurate rendering.

This architecture uses WebCodecs for hardware-accelerated encoding directly within the browser context. When you run this on a server, VideoFlow manages a pool of Chromium instances that consume a portable VideoJSON document and output a binary MP4 buffer. No shell scripts, no complex codec flags, just pure TypeScript.
Setting Up the Server Renderer
To get started, you'll need the core library and the server-side renderer. Unlike traditional tools, you don't need to install FFmpeg on your host machine; you just need Playwright's Chromium binary.
npm install @videoflow/core @videoflow/renderer-server
npx playwright install chromium
Once installed, you simply import the renderer to register it with the core VideoFlow engine. The engine will then automatically resolve to the server renderer whenever you call renderVideo in a Node.js environment.
Building the Video API
Let’s build a simple Express-style endpoint that takes a name as a query parameter and returns a personalized 5-second video. This pattern is perfect for personalized video at scale, such as automated welcome messages or data-driven recaps.
import VideoFlow from '@videoflow/core';
import '@videoflow/renderer-server'; // Registers the Node renderer
export async function handleVideoRequest(req, res) {
const { name = 'Developer' } = req.query;
// 1. Initialize the project
const $ = new VideoFlow({ width: 1280, height: 720, fps: 30 });
// 2. Compose the scene
const bg = $.addShape(
{ width: 100, height: 100, fill: '#1a1a1a' },
{ shapeType: 'rectangle' }
);
const title = $.addText({
text: `Hello, ${name}`,
fontSize: 8,
color: '#FF5A1F', // VideoFlow Orange
position: [0.5, 0.5],
});
// 3. Add cinematic motion
title.fadeIn('600ms', 'easeOut');
$.wait('3s');
title.fadeOut('400ms');
// 4. Render to a Buffer
const buffer = await $.renderVideo({
outputType: 'buffer',
verbose: true
});
// 5. Send the response
res.setHeader('Content-Type', 'video/mp4');
res.setHeader('Content-Disposition', 'attachment; filename="video.mp4"');
res.send(buffer);
}
This approach is significantly cleaner than the "shell out to FFmpeg" alternative. If you want to experiment with different layouts or effects before deploying, you can drop your logic into the VideoFlow Playground to see it in action instantly.
Why JSON Portability Wins
One of the biggest advantages of VideoFlow over alternatives like Remotion is that your video isn't locked into a React runtime. When you call $.compile(), you get a plain VideoJSON object.

This portability means you can:
- Store the video state in a database (like a Postgres JSONB column).
- Version control your video templates.
- Preview the video in a React app using
@videoflow/renderer-domand then render the exact same JSON on the server for the final export.
For a deeper dive into how this compares to traditional methods, check out our guide on FFmpeg vs VideoFlow or read about moving beyond the shell.
Conclusion
Rendering video on the server doesn't have to be a DevOps nightmare. By treating video as data and leveraging modern browser APIs like WebCodecs, you can build scalable, maintainable, and cinematic video pipelines using the tools you already know.
Ready to build your first automated video factory? Head over to the VideoFlow Documentation to get started, or star the project on GitHub to follow our progress.