State-Driven Video: Syncing Your React UI with a Programmatic Timeline
May 22, 2026 · By VideoFlowLearn how to sync your React UI with a video timeline using VideoFlow's renderer-dom and editor hooks. Build frame-accurate, data-driven video experiences.
State-Driven Video: Syncing Your React UI with a Programmatic Timeline
When building video-first applications, the biggest hurdle isn't just rendering the pixels—it's keeping the rest of your application in sync with those pixels. If you've ever tried to build a dashboard where a chart updates as a video plays, or a multi-track editor where the UI has to reflect a frame-perfect playhead, you know the pain of state drift.
Traditional video players are black boxes. They emit events, but they don't share their internal clock or state in a way that modern reactive frameworks like React can easily consume. This leads to "jittery" UIs where the data lags behind the visuals, or worse, completely disconnected experiences.
VideoFlow changes this by treating video as a first-class citizen of your application state. By leveraging the @videoflow/renderer-dom and the hooks provided by the React Video Editor, you can build truly immersive, state-driven video experiences where the UI and the timeline are one and the same.
The Reactive Playhead
In most video apps, you have to set up complex requestAnimationFrame loops or poll a <video> element's currentTime to update your UI. In VideoFlow, the playhead is just another piece of state you can subscribe to.
Using the usePlayhead hook from the @videoflow/react-video-editor package, your components can react to every frame change with zero manual plumbing. This is essential for building custom overlays, dynamic captions, or progress indicators that feel native to the video.

import { usePlayhead } from '@videoflow/react-video-editor';
function FrameCounter() {
const { frame, playing } = usePlayhead();
return (
<div className="status-bar">
<span>Current Frame: {frame}</span>
<span>Status: {playing ? 'Playing' : 'Paused'}</span>
</div>
);
}
This pattern allows you to treat the video timeline like a global state provider. When the user scrubs the timeline in the Playground or your custom editor, every subscribed component updates instantly.
The Renderer Bridge: Programmatic Control
Sometimes you need to go the other way: your UI needs to tell the video renderer exactly what to do. This is where the Bridge API comes in. The bridge is the direct link between your React code and the underlying DomRenderer instance.
Through the bridge, you can programmatically seek to specific frames, trigger renders, or even manipulate the rendering environment in real-time. This is particularly powerful for building "Step-by-Step" tutorials or interactive video experiences where user actions outside the video canvas must be reflected inside the frame.

import { useEditorStore } from '@videoflow/react-video-editor';
function JumpToChapter({ chapterFrame }) {
const { bridge } = useEditorStore((s) => s.state);
const handleJump = async () => {
// Frame-accurate seek and re-render
await bridge.seek(chapterFrame);
await bridge.renderFrame(chapterFrame);
};
return <button onClick={handleJump}>Go to Chapter</button>;
}
This level of control is what makes VideoFlow a superior Remotion alternative. While other tools might feel like they are "wrapping" a video, VideoFlow exposes the rendering pipeline directly to your application logic.
Building a Data-Driven Player
Imagine a SaaS dashboard for a logistics company. You want to show a video of a delivery route while simultaneously updating a map and a speed graph. In a legacy setup, this would require complex synchronization logic across multiple libraries.
With VideoFlow, you can use the Three-Renderer Rule to share the same VideoJSON across your preview, your editor, and your server-side export. Because the DomRenderer is frame-accurate, you can use the current frame index to look up data in a linked array or database.
function AnalyticsSync({ telemetryData }) {
const { frame } = usePlayhead();
const currentData = telemetryData[frame];
return (
<div className="analytics-overlay">
<Sparkline data={telemetryData} highlightIndex={frame} />
<p>Speed at this moment: {currentData.speed} km/h</p>
</div>
);
}
How VideoFlow Handles the Sync
Under the hood, VideoFlow's @videoflow/renderer-dom uses a specialized Shadow DOM implementation to isolate video layers while maintaining a high-performance update loop. When you use the React hooks provided in the editor package, you are tapping into a Zustand-based store that is optimized for high-frequency updates.
This architecture ensures that even with dozens of layers and GLSL effects, your UI remains responsive. The renderer handles the heavy lifting of compositing frames, while the React bridge ensures your application state is never more than one frame behind.
If you're ready to build video experiences that are truly integrated with your app's UI, check out our hooks and commands guide or dive into the source on GitHub.
Next Steps
- Explore the Core Concepts to understand how VideoJSON works.
- Try syncing your own UI in the interactive Playground.
- See how to automate these renders on the server in our guide on rendering without FFmpeg.