VideoFlowcodeGitHubTry itCoreRenderersReact Video EditorPlaygroundExamplesDocscodeGitHubTry it
← Back to Blog

How to Render MP4s in Node.js without Installing FFmpeg

May 22, 2026 · By VideoFlowLearn how to build a high-performance video rendering pipeline in Node.js without FFmpeg. Use VideoFlow and WebCodecs to export professional MP4s directly from code.How to Render MP4s in Node.js without Installing FFmpeg

How to Render MP4s in Node.js without Installing FFmpeg

If you have ever tried to build a video automation pipeline in Node.js, you have likely hit the "FFmpeg wall." You start by spawning shell commands, then you're wrestling with static builds, environment variables, and the overhead of re-encoding raw frames into H.264. It is fragile, difficult to scale, and a nightmare to debug.

But what if you didn't need FFmpeg at all?

With VideoFlow and its headless server-side renderer, you can generate professional MP4s directly from code without a single binary dependency on the host machine. By leveraging WebCodecs inside a headless browser, VideoFlow bypasses the traditional per-frame screenshot bottleneck, delivering a modern, high-performance alternative to legacy shell-scripted pipelines.

The Problem with Legacy Video Pipelines

Traditional programmatic video tools (and many modern ones) rely on a pattern of "screenshot and pipe." They render a frame in a browser, take a snapshot, and pipe that raw image data into FFmpeg.

This approach has three major flaws:

  1. High Overhead: The round-trip between the browser and the host process for every single frame is slow.
  2. Re-encoding Penalty: FFmpeg has to re-encode every incoming frame, consuming massive CPU cycles.
  3. Deployment Friction: You have to ensure FFmpeg is installed and correctly configured in every environment (Docker, Lambda, CI/CD).

Headless browser as a film projector

Enter @videoflow/renderer-server

The VideoFlow server-side renderer takes a different path. Instead of capturing screenshots, it launches a headless Chromium instance and executes the render logic inside the browser using WebCodecs.

The browser handles the frame composition, audio mixing, and MP4 muxing internally. When the render is complete, the finished MP4 bytes are sent back to your Node.js process as a simple buffer. No FFmpeg, no per-frame overhead, and byte-for-byte identical output to what you see in the Playground.

Step-by-Step: Rendering Your First Video

To get started, you only need two packages: @videoflow/core for building the video and @videoflow/renderer-server for the export.

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

1. Define the Video in Code

Using the VideoFlow core builder API, we can compose a scene with just a few lines of TypeScript. Note how we use the two-argument pattern to separate animatable properties from static settings like the image source.

import VideoFlow from '@videoflow/core';

const $ = new VideoFlow({ width: 1080, height: 1080, fps: 30 });

// Add a background image
const bg = $.addImage(
  { fit: 'cover', opacity: 0.8 },
  { source: 'https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe' }
);

// Add a title with a built-in transition
const title = $.addText(
  {
    text: 'HEADLESS RENDER',
    fontSize: 8,
    color: '#FF5A1F',
    fontWeight: 800,
    position: [0.5, 0.5]
  },
  {
    transitionIn: { transition: 'blurResolve', duration: '800ms' }
  }
);

$.wait('3s');
title.fadeOut('500ms');

2. Trigger the Headless Render

Once your project is defined, you simply call renderVideo. By default, VideoFlow uses the WebCodecs pipeline, meaning it won't look for an FFmpeg binary on your system.

import '@videoflow/renderer-server';

// This will launch headless Chromium, render the project,
// and save the final MP4 to disk.
await $.renderVideo({
  outputType: 'file',
  output: './headless-output.mp4',
  verbose: true,
});

Comparison of shell scripts vs JSON

Why This Matters for SaaS and Automation

If you are building a platform that generates personalized videos—such as weekly user recaps, automated e-commerce trailers, or LLM-powered video pipelines—deployment simplicity is key.

Using the headless browser approach allows you to:

  • Scale on Serverless: Run renders in environments like AWS Lambda or Google Cloud Run where installing custom binaries is a chore.
  • Reduce Costs: Faster render times mean lower compute bills.
  • Maintain Sanity: Stop debugging complex FFmpeg flags and start writing clean, typed TypeScript.

Compared to Remotion alternatives, VideoFlow's approach is entirely open-source (Apache-2.0) and produces a portable VideoJSON document. This means you can define your video in any language and send it to a Node.js worker for the final render.

Wrapping Up

Moving away from FFmpeg doesn't just simplify your stack; it unlocks a more robust way to build video products. Whether you are migrating from FFmpeg shell scripts or building a new automation factory, the headless renderer provides the performance and reliability needed for production-grade video.

Ready to see it in action? Head over to the VideoFlow documentation to explore the full range of transitions and effects, or check out the source on GitHub to see how the renderer works under the hood.

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 →Video as Data: Building an LLM-Powered Video Generation PipelineGlobal by Default: Automating Video Localization with TypeScriptHow to Render MP4s in Node.js without Installing FFmpegThe Three-Renderer Rule: Preview, Export, and Automate with VideoFlowBeyond Opacity: How to Use BlendModes for Programmatic Motion GraphicsThe Headless Video Playbook: Scaling Your Rendering APIBeyond Node.js: Generating Programmatic Video from Python, Go, and RustHow to Build a 'Spotify Wrapped' Style Video Recap for Your SaaS
© 2026 VideoFlow. Apache-2.0 core.