VideoFlowcodeGitHubTry itCoreRenderersReact Video EditorPlaygroundExamplesDocscodeGitHubTry it
← Back to Blog

Building Reusable Programmatic Video Components with Layer Groups

July 8, 2026 · By VideoFlowLearn how to build reusable programmatic video components using VideoFlow's Layer Groups. Master composition, nested timelines, and encapsulated animations.Building Reusable Programmatic Video Components with Layer Groups

When you're building a simple video script, you can get away with a flat list of layers. But as soon as you move into building a programmatic video engine—like an automated social media factory or a personalized SaaS dashboard—your code starts to look like spaghetti. You find yourself manually calculating frame offsets for twenty different layers just to move a single 'card' across the screen.

This is where the architecture of your video pipeline matters. To scale, you need reusable programmatic video components. In VideoFlow, this is achieved through Layer Groups—a powerful primitive that lets you encapsulate logic, timing, and cinematic effects into portable, nestable blocks.

Architecture of nested layer groups forming a video output

The Problem with Flat Timelines

Most video-as-code tools force you to think in global coordinates and global timestamps. If you want to create a 'User Profile' widget with an avatar, a name, and a background, you have to position each layer relative to the main canvas. If you decide to move that widget 100 pixels to the left, you're updating three different position properties.

Even worse is timing. If your widget has a subtle entrance animation, and you want to delay the entire widget by 2 seconds, you're manually adding 2.0 to every layer's startTime. This approach is fragile, hard to debug, and makes code reuse nearly impossible.

Encapsulation with Layer Groups

VideoFlow's Layer Group guide introduces $.group(). A group is a container that creates a private, project-sized surface. Everything inside the group is composited onto this surface first, and then the group itself is treated as a single visual layer by the parent project.

This provides three massive advantages for building reusable components:

  1. Local Coordinates: Children are positioned relative to the group's internal surface.
  2. Relative Timing: A child's startTime of 0 means the exact moment the group begins, not the start of the video.
  3. Atomic Transforms: You can rotate, scale, or apply a GLSL effect to the entire group as if it were a single image.

Pattern: The 'Card' Component

Let's look at how to wrap this into a reusable function. This pattern allows you to stamp out dozens of identical widgets with different data.

import VideoFlow from '@videoflow/core';

function createStatCard($, { label, value, x, color }) {
  return $.group(
    { position: [x, 0.5], scale: 1 },
    {
      transitionIn: { transition: 'overshootPop', duration: '600ms' },
      transitionOut: { transition: 'fade', duration: '400ms' },
    },
    (group) => {
      // Background
      $.addShape(
        { width: 30, height: 20, fill: '#1c2233', cornerRadius: 2 },
        { shapeType: 'rectangle' }
      );

      // Label text
      $.addText({
        text: label,
        fontSize: 1.5,
        color: '#94a3b8',
        position: [0.5, 0.35]
      });

      // Value text
      $.addText({
        text: value,
        fontSize: 5,
        color: color,
        position: [0.5, 0.6]
      });

      $.wait('3s');
    }
  );
}

Isometric view of UI components being duplicated and modified

Orchestrating the Flow

Once you have your component function, you can orchestrate complex scenes using the VideoFlow Core builder. Because groups return a layer instance, you can still animate the entire component from the outside.

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

// Stagger three cards
const cardA = createStatCard($, { label: 'REVENUE', value: '$12k', x: 0.25, color: '#FF5A1F' });
$.wait('200ms');
const cardB = createStatCard($, { label: 'USERS', value: '4.2k', x: 0.50, color: '#4ecdc4' });
$.wait('200ms');
const cardC = createStatCard($, { label: 'CHURN', value: '0.8%', x: 0.75, color: '#a78bfa' });

// Apply a global drift to one specific card without touching its children
cardB.animate(
  { rotation: -2 },
  { rotation: 2 },
  { duration: '4s', easing: 'easeInOut', wait: false }
);

In this example, cardB drifts back and forth. The text and shape inside the group stay perfectly aligned because they are part of the group's local coordinate system. If you were doing this without groups, you would have to calculate the sine-wave rotation for every individual layer in the widget.

Why This Beats React-based Approaches

If you're coming from a Remotion background, you might be used to using React components for this. While React is great for UI, it couples your video logic to a specific UI library and a heavy runtime.

VideoFlow's approach uses standard JavaScript functions and a portable VideoJSON schema. This means you can build your component library once and use it anywhere: in a high-concurrency Node.js backend using @videoflow/renderer-server, or directly in a customer's browser via @videoflow/renderer-browser for zero-server-cost exports.

Start Building Your Library

Treating your video layers as components isn't just about cleaner code—it's about building a scalable asset library. By encapsulating complex animations and GLSL stacks into simple function calls, you turn a complex rendering task into a simple composition exercise.

Ready to try it out? Head over to the VideoFlow Playground and try nesting a few $.group() calls. You'll quickly see how much faster it is to build cinematic scenes when you aren't fighting global coordinates.

For a deeper dive into the API, check out the official documentation or join the community on GitHub.

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 →Browser-Side Video Export: Zero-Server Rendering with WebCodecsCinematic GLSL: Stacking Effects for a Retro VHS Look in VideoFlowHow to Generate Personalized Video Ads from a CSV with TypeScriptBeyond the Prompt: Why LLMs Need Portable VideoJSONHow to Render MP4 Videos in Node.js without FFmpegBuilding Reusable Programmatic Video Components with Layer GroupsThe Three-Renderer Rule: Unifying Your Video Rendering PipelineVideoFlow vs Remotion: The Open Source Alternative for Video as Code
© 2026 VideoFlow. Apache-2.0 core.