VideoFlowcodeGitHubTry itCoreRenderersReact Video EditorPlaygroundExamplesDocscodeGitHubTry it
← Back to Blog

The Three-Renderer Rule: Why Your Video Pipeline Needs a Browser, a Server, and a DOM

August 22, 2026 · By VideoFlowLearn why a modern video-as-code architecture requires three distinct renderers for live preview, zero-cost browser export, and headless server automation.The Three-Renderer Rule: Why Your Video Pipeline Needs a Browser, a Server, and a DOM

The Three-Renderer Rule: Why Your Video Pipeline Needs a Browser, a Server, and a DOM

Building a video pipeline usually starts with a single question: "How do I turn this data into an MP4?" But as soon as you move beyond simple automation and into building real products—SaaS dashboards, in-app editors, or AI-driven creative tools—that single question becomes a complex architectural challenge.

You don't just need an MP4. You need to show the user what they are building in real-time. You need to let them export that video without waiting for a server queue. And you need a way to render batch jobs at scale in the cloud.

At VideoFlow, we solved this by implementing the Three-Renderer Rule. In this post, we’ll explore why having three distinct, byte-for-byte identical renderers is the secret to a modern video-as-code architecture.

The Three-Renderer Architecture

The Problem with Single-Target Rendering

Most video libraries are built for a single environment. FFmpeg is built for the server. Lottie is built for the browser. Remotion is built for React.

When your rendering engine is tied to a specific runtime, you're forced to make compromises. If you use an FFmpeg-based API, your users can't preview their changes without a round-trip to the server. If you use a browser-only library, you're stuck when you need to generate 10,000 personalized videos in a background job.

VideoFlow's core philosophy is that the VideoJSON is the source of truth. Because our scenes are portable JSON documents, we can render them anywhere.

1. The DOM Renderer: Frame-Accurate Live Preview

For any application that includes a user interface—like an embeddable video editor—the first requirement is a live preview.

@videoflow/renderer-dom is designed for this exact purpose. It doesn't encode video; it renders the VideoJSON directly to a DOM target at a fluid 60 fps. It allows for frame-accurate scrubbing, playback, and real-time property updates.

When a user moves a slider in the VideoFlow Playground, the DOM renderer updates the scene instantly. There is no encoding overhead, no lag, and no server cost.

2. The Browser Renderer: Zero-Server-Cost Export

Once the user is happy with their creation, they need to download the MP4. Traditionally, this meant uploading the project to a server, waiting in a queue, and paying for cloud compute.

With @videoflow/renderer-browser, we use the WebCodecs API to encode the MP4 directly in the user's browser tab. We've written before about how this enables zero-server-cost video rendering, and it remains one of VideoFlow's most powerful features.

import BrowserRenderer from '@videoflow/renderer-browser';
import VideoFlow from '@videoflow/core';

const $ = new VideoFlow({ width: 1920, height: 1080, fps: 30 });
$.addText({ text: 'Client-Side Export' }).fadeIn('500ms');
$.wait('2s');

const json = await $.compile();
const blob = await BrowserRenderer.render(json);

This renderer runs inside a Web Worker, ensuring the UI stays responsive while the video encodes. It’s the ultimate way to scale your video features without scaling your infrastructure bill.

3. The Server Renderer: Headless Automation

There are times when the browser isn't enough. Maybe you're building a YouTube Shorts factory that generates videos on a cron job, or a SaaS that emails personalized recaps to users every Monday morning.

@videoflow/renderer-server brings the same rendering engine to Node.js. It uses Playwright to drive a headless Chromium instance, ensuring that the visual output is identical to what the user saw in the preview.

The Rendering Pipeline

Crucially, VideoFlow renders on the server without an ffmpeg dependency by default. We use a specialized muxing layer called MediaBunny inside the browser to produce the MP4. This makes deployment to serverless environments like AWS Lambda or Vercel Functions significantly easier.

import ServerRenderer from '@videoflow/renderer-server';

// Render to a buffer for S3 upload
const buffer = await ServerRenderer.render(videoJSON, {
  outputType: 'buffer',
  onProgress: (p) => console.log(`Progress: ${p * 100}%`)
});

Why Identity Matters

The "Rule" isn't just about having three packages. It's about identity.

If you use a transition like blurResolve or an effect like chromaticAberration, it must look exactly the same in the DOM preview, the browser export, and the server render.

VideoFlow achieves this by sharing the same GLSL shader library and layout engine across all three renderers. Whether you are using @videoflow/core to build a scene or building a custom integration, you can trust that what you see is what you get.

Conclusion: Choosing Your Renderer

A modern video pipeline shouldn't be a monolith. By decoupling the scene definition (VideoJSON) from the rendering environment, VideoFlow gives you the flexibility to choose the right tool for the job:

  • Building an editor? Use the DOM renderer for the canvas.
  • Saving on cloud costs? Use the Browser renderer for user exports.
  • Automating at scale? Use the Server renderer for background jobs.

Ready to see the Three-Renderer Rule in action? Head over to our documentation to get started, or explore the VideoFlow GitHub repository to see how it's built.

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 →Building an AI Video Agent: How to Generate MP4s from LLM Prompts with VideoJSONAutomating E-commerce: How to Generate 1,000 Product Videos with TypeScriptThe Blueprint for Automated Video: Building a Reusable Component LibraryThe Art of Layering: Building Cinematic Programmatic Video with VideoFlowThe Math of Motion: Mastering Easings and Keyframes in VideoFlowGoodbye Shell Scripts: Migrating Your FFmpeg Pipeline to Type-Safe JSONHow to Render MP4 in Node.js Without FFmpeg DependenciesStop Calculating Pixels: Mastering Resolution-Independent Video with VideoFlow
© 2026 VideoFlow. Apache-2.0 core.