VideoFlowcodeGitHubTry itCoreRenderersReact Video EditorPlaygroundExamplesDocscodeGitHubTry it
← Back to Blog

Mastering Flow: How to Use $.wait, $.parallel, and $.group in VideoFlow

August 12, 2026 · By VideoFlowLearn how to move beyond manual frame math. Master VideoFlow's timing primitives like $.wait, $.parallel, and $.group to build complex, maintainable video timelines.Mastering Flow: How to Use $.wait, $.parallel, and $.group in VideoFlow

Mastering Flow: How to Use $.wait, $.parallel, and $.group in VideoFlow

Most video-as-code libraries force you to think in absolute frames or manual timestamps. You find yourself calculating that "Layer B should start at frame 120 because Layer A lasts 4 seconds at 30fps." This brittle approach breaks the moment you change a single duration.

In VideoFlow, we treat video like a program. Instead of manual frame math, you use high-level flow primitives—$.wait, $.parallel, and $.group—to compose complex timelines that are readable, maintainable, and resolution-agnostic.

The Sequential Default

By default, the @videoflow/core builder operates sequentially. When you add a layer or call an animation method, the internal "flow pointer" advances.

import VideoFlow from '@videoflow/core';

const $ = new VideoFlow();

// 1. Text appears and we wait 2 seconds
$.addText({ text: 'Step One' });
$.wait('2s');

// 2. This text starts exactly at the 2s mark
$.addText({ text: 'Step Two' });

This is intuitive for simple slideshows, but real-world videos require overlapping elements and complex compositions. This is where parallelism comes in.

Branching the Timeline with $.parallel

If you want to trigger multiple actions at the exact same time without advancing the main flow pointer, use $.parallel. This is essential for creating "scenes" where a background appears while multiple text elements animate in simultaneously.

Parallel tracks in VideoFlow

$.parallel(($) => {
  // These two layers start at the same timeline position
  $.addText({ text: 'Left Side', position: [0.2, 0.5] });
  $.addText({ text: 'Right Side', position: [0.8, 0.5] });
});

// The flow pointer hasn't moved! 
// The next element still starts at the same time as the parallel block.
$.addShape({ fill: '#FF5A1F' }, { shapeType: 'rectangle' });

In this example, both text layers and the rectangle start at the same time. The $.parallel block acts as a "snapshot" point where you can stack as many layers as you need without pushing the rest of your video later into the timeline.

Encapsulation with $.group

As your project grows, you'll want to treat multiple layers as a single entity. The $.group method creates a GroupLayer that acts as a container. Children inside the group use coordinates and timing relative to the group itself.

VideoFlow Grouping

Groups are incredibly powerful because you can apply transitions and effects to the entire group at once. If you apply a blurResolve transition to a group, every child inside that group will blur in together as a single composite unit.

const card = $.group(
  { opacity: 0.8 },
  { transitionIn: { transition: 'blurResolve', duration: '800ms' } },
  ($) => {
    $.addShape({ fill: '#222' }, { shapeType: 'rectangle' });
    $.addText({ text: 'Grouped Title', fontSize: 5 });
  }
);

Why Your Video Pipeline Should Be Programmable

By using these primitives, you move away from the "After Effects mindset" of static layers and toward a dynamic, data-driven architecture. This is why VideoFlow is the preferred choice for developers building automated content factories or SaaS recap videos.

Unlike Remotion, which ties your scene logic to a React component tree, VideoFlow compiles your builder calls into a portable VideoJSON document. This JSON can be rendered identically across our three official renderers: in the browser via WebCodecs, on the server via headless Chromium, or as a live preview in your React app.

Summary: The Three-Step Timing Rule

  1. Use $.wait for sequential storytelling.
  2. Use $.parallel to stack independent layers at the same timestamp.
  3. Use $.group to encapsulate complex sub-scenes and apply shared effects.

You can experiment with these patterns right now in the VideoFlow Playground or dive deeper into the Parallel and Wait guide in our documentation.

Ready to build? Check out the source on GitHub and start composing your next video with code.

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 →The 50-Line YouTube Shorts Factory: Programmatic Video with VideoFlowMastering Motion: How to Animate Effect Parameters in VideoFlowMastering Flow: How to Use $.wait, $.parallel, and $.group in VideoFlowParallel vs Sequential: Mastering the VideoFlow Timing ModelOne JSON, Three Renderers: Mastering the VideoFlow LifecycleGenerating Multi-Language Video at Scale: The Localization PlaybookBrowser-Side Video Export: Zero-Server Rendering with WebCodecsHow to Build a Dynamic Video Editor in React in 10 Minutes
© 2026 VideoFlow. Apache-2.0 core.