Component-Driven Video: Mastering Layer Groups and Composition
May 14, 2026 · By VideoFlowLearn how to use VideoFlow layer groups and timing primitives to build modular, component-driven video pipelines that scale with your application.
Component-Driven Video: Mastering Layer Groups and Composition
Building a simple video with code is easy. Building a complex, data-driven video pipeline that stays maintainable as your project grows is a different challenge altogether. When you're managing dozens of layers, overlapping animations, and dynamic content, a flat list of commands quickly becomes a bottleneck for development.
In this guide, we'll explore how to apply component-driven video principles using VideoFlow. By mastering layer groups and timing primitives, you can transform a monolithic script into a modular, scalable architecture.
The Power of the Group Primitive
At the heart of VideoFlow's composition model is the $.group() method. Unlike simple folders in a traditional video editor, a group in VideoFlow is a first-class container that treats a sub-tree of layers as a single visual entity.
When you wrap layers in a group, they are composited onto a private surface. This allows you to apply transforms, effects, and transitions to the entire group at once. If you need to move a complex UI card, you don't animate the position of every text element and shape individually; you simply animate the group.

const card = $.group(
{ position: [0.5, 0.5] },
{
transitionIn: { transition: 'overshootPop', duration: '600ms' },
},
() => {
$.addShape({ width: 50, height: 30, fill: '#1c2233', cornerRadius: 2 }, { shapeType: 'rectangle' });
$.addText({ text: 'User Profile', fontSize: 3, position: [0.5, 0.4] });
$.wait('2s');
}
);
// Animate the whole composite card
card.animate({ rotation: -2 }, { rotation: 2 }, { duration: '2s', wait: false });
This approach mirrors modern frontend development. Just as you build React components to encapsulate logic and UI, you can use $.group() to encapsulate video scenes and reusable layouts.
Building Reusable Video Components
Because VideoFlow is just TypeScript, you can easily wrap these groups in standard functions. This is the essence of component-driven video. Imagine building a "Notification" component that you can call multiple times with different data:
function Notification($, message, color = '#FF5A1F') {
return $.group({ position: [0.8, 0.2], scale: 0.8 }, { transitionIn: { transition: 'slideRight' } }, () => {
$.addShape({ width: 30, height: 10, fill: color, cornerRadius: 1 }, { shapeType: 'rectangle' });
$.addText({ text: message, fontSize: 2, color: '#fff' });
$.wait('3s');
});
}
// Usage in your main flow
Notification($, 'New Sale!', '#4ecdc4');
$.wait('1s');
Notification($, 'New Subscriber!');
By abstracting your visual logic into functions, your main timeline becomes a high-level orchestration of events rather than a mess of coordinate math. You can find more patterns like this in our guide to layer groups.
Orchestrating Timing with Parallelism
Complexity in programmatic video often comes from timing. When should an element appear? How long should it stay? VideoFlow uses two primary timing primitives: $.wait() and $.parallel().
- Sequential Flow: By default, every call to
.animate()or$.wait()pushes the internal flow pointer forward. - Parallel Flow:
$.parallel()lets you run multiple branches of code starting at the same point in time. The main flow pointer only advances once the longest branch in the parallel block is finished.

This mental model is crucial for building complex overlays. You might want a background video to play while multiple text elements animate in at staggered intervals. You can see this in action in the VideoFlow Playground, where you can live-edit timing and see the results at 60 fps.
How VideoFlow Handles Composition
VideoFlow's architecture is built specifically for this type of modularity. When you call $.compile(), the fluent builder API in @videoflow/core resolves all your groups, parallel branches, and relative waits into a flat, portable VideoJSON document.
This document is the single source of truth for your video. Because it's pure JSON, it is resolution-agnostic and renderer-independent. You can preview it instantly in the browser, export it as an MP4 using @videoflow/renderer-browser, or send it to a headless Node.js server for high-volume batch processing. For a deeper look at why this portability matters, check out our post on the Three-Renderer Rule.
Conclusion
Moving to a component-driven video workflow changes how you think about automated content. Instead of writing one-off scripts, you're building a library of visual components that can be composed, tested, and reused across different projects.
Ready to start building your own video components? Head over to the official documentation to explore the full API, or dive into the source code on GitHub to see how the core engine handles complex compositions.