VideoFlowcodeGitHubTry itCoreRenderersReact Video EditorPlaygroundExamplesDocscodeGitHubTry it
← Back to Blog

How to Render MP4 from a Node API without FFmpeg

May 22, 2026 · By VideoFlowLearn how to build a high-performance video rendering API in Node.js using VideoFlow and WebCodecs, skipping the complexity of FFmpeg shell scripts.How to Render MP4 from a Node API without FFmpeg

Building a video rendering pipeline in Node.js has historically been a exercise in frustration. You usually end up spawning child processes to run FFmpeg, wrestling with string-concatenated shell commands, and managing complex binary dependencies in your Docker containers. It works, but it's brittle, hard to debug, and feels out of place in a modern, type-safe backend.

What if you could render an MP4 directly from your Node API using the same technologies that power the modern web, with zero FFmpeg required?

In this tutorial, we’ll show you how to use VideoFlow to build a high-performance video rendering endpoint. We’ll leverage WebCodecs inside a headless browser to generate professional-grade MP4s from pure TypeScript code.

The Problem with "Stringly-Typed" Video

Most video automation today relies on FFmpeg. While FFmpeg is an incredible piece of engineering, it wasn't designed for the way we build web applications. When you use it in a Node.js API, you're usually doing something like this:

  1. Generating a sequence of images (JPEGs or PNGs).
  2. Writing them to a temporary disk location.
  3. Piping those filenames into a massive FFmpeg string.
  4. Waiting for the re-encode to finish.

This "screenshot-and-re-encode" loop is slow. It introduces massive I/O overhead and forces you to maintain an FFmpeg installation that might differ between your local machine and your production environment. If you've ever read our guide on why your video pipeline should be type-safe, you know there's a better way.

A technical diagram showing a JSON object transforming into an MP4 through a headless browser pipeline

Enter VideoFlow: Rendering via WebCodecs

VideoFlow changes the architecture. Instead of piping frames to a separate binary, the @videoflow/renderer-server package drives a headless Chromium instance via Playwright. Inside that browser, it uses the WebCodecs API to encode the video directly to an MP4 buffer.

This approach has three massive advantages:

  1. Zero FFmpeg Dependency: By default, you don't even need FFmpeg installed. The browser handles everything.
  2. No Per-Frame Screenshot Overhead: Because the encoding happens inside the browser's memory, we skip the JPEG-to-disk roundtrip.
  3. Pixel-Perfect Parity: The video you render on the server is identical to what you see in the Playground or the live preview renderer.

Building the API Endpoint

Let’s build a simple Express endpoint that accepts some text and returns a rendered video. First, ensure you have the necessary packages:

npm install @videoflow/core @videoflow/renderer-server express
npx playwright install chromium

Now, let's write the handler. We'll use the fluent builder API to compose the scene and then render it to a buffer.

import express from 'express';
import VideoFlow from '@videoflow/core';
import '@videoflow/renderer-server'; // Registers the server renderer

const app = express();

app.get('/render', async (req, res) => {
  const name = (req.query.name as string) || 'Developer';

  // 1. Initialize the project
  const $ = new VideoFlow({
    width: 1280,
    height: 720,
    fps: 30,
    backgroundColor: '#0b0b1f'
  });

  // 2. Compose the scene
  const title = $.addText({
    text: `Hello, ${name}!`,
    fontSize: 8,
    color: '#FF5A1F',
    fontWeight: 700,
    position: [0.5, 0.4]
  });

  // Add a cinematic entrance
  title.fadeIn('800ms');
  
  // Wait for 3 seconds of screen time
  $.wait('3s');

  // 3. Render directly to a buffer
  const buffer = await $.renderVideo({
    outputType: 'buffer',
    verbose: true
  });

  // 4. Return the MP4
  res.setHeader('Content-Type', 'video/mp4');
  res.send(buffer);
});

app.listen(3000, () => console.log('API running on port 3000'));

Why This Scales

Because VideoFlow treats videos as portable JSON, your API doesn't have to be a monolith. You can generate the VideoJSON on one microservice and send it to a dedicated rendering worker that only carries the @videoflow/renderer-server and Chromium.

An illustration showing a code editor rendering a video frame in a glowing orange trail

This architecture is perfect for building social media automation factories or personalized video recaps. You get the full power of 42 GLSL effects and 27 transition presets without ever writing a line of Bash.

Next Steps

Rendering MP4s from a Node API shouldn't feel like a hack. By moving the rendering logic into a headless browser and using modern WebCodecs, VideoFlow gives you a clean, type-safe, and high-performance way to automate video creation.

Ready to build your own?

VideoFlow

Open-source toolkit for composing videos from code.

Product

CoreRenderersReact Video EditorPlayground

Learn

DocsAPI referenceExamplesvs. Remotionvs. FFmpeg

Project

GitHubLicenseContactTermsPrivacy

From the blog

All posts →How to Automate Loom-style Product Demos with TypeScriptAutomated Podcast Audiogram Generator: Turning Audio into Viral Video with TypeScriptAutomating Personalized Onboarding Videos with VideoFlow and TypeScriptAutomating YouTube Shorts: Build a Vertical Video Factory in 30 Lines of TypeScriptCinematic GLSL Effect Stacking: Building High-End Visuals with CodeHeadless Video Rendering in Node.js: No FFmpeg RequiredVideo as Data: Building an LLM-Powered Video Generation PipelineMastering Motion: A Deep Dive into VideoFlow Transitions and Easing
© 2026 VideoFlow. Apache-2.0 core.