VideoFlowcodeGitHubTry itCoreRenderersReact Video EditorPlaygroundExamplesDocscodeGitHubTry it
Getting started
InstallationQuick startCore conceptsYour first video
Builder
Builder APITime formatsParallel & wait
Layers
TextImageVideoAudioCaptionsShapeGroups
Animation
Animate & keyframesEasing functionsTransitionsEffects
Renderers
Browser rendererServer rendererDOM preview
React Video Editor
QuickstartThemingUploadsCustom panelsHooks & commandsKeyboard shortcuts
API reference
Overview@videoflow/core@videoflow/renderer-browser@videoflow/renderer-server@videoflow/renderer-dom@videoflow/react-video-editor

Live preview with the DOM renderer

@videoflow/renderer-dom paints a running composition into a DOM element you own. It's what the playground and the React video editor use internally. Seekable, no recompilation on each edit, and completely isolated in a shadow root.

Minimal example

import DomRenderer from '@videoflow/renderer-dom';

const host = document.getElementById('player');
const r = new DomRenderer(host);

await r.loadVideo(videoJSON);
await r.play();                   // auto-loops

// Or scrub precisely:
await r.seek(42);                 // frame 42
await r.renderFrame(0);           // paint a single frame
r.stop();
r.destroy();

Methods

MethodEffect
new DomRenderer(host)Attach to a DOM element. Creates a shadow root internally.
.loadVideo(json)Load or swap in a VideoJSON. Resolves when media is ready.
.play()Start a rAF loop. Auto-loops by default.
.stop()Pause at the current frame.
.seek(frame)Jump to a specific frame (integer).
.renderFrame(frame)Paint a single frame without starting a play loop.
.destroy()Tear down. Call on unmount.

Properties & events

NameNotes
onFrame: (frame) => voidFires on every painted frame during playback. Use for a scrub bar.
currentFrameRead-only. Last painted frame.
durationComposition duration in seconds.
fpsFrom the loaded video.

Granular updates

Calling loadVideo() reloads everything. For typing-speed edits, use the incremental patch API — it skips decode for unchanged layers:

r.updateVideo({ duration: 4 });          // top-level patch
r.addLayer(newLayer);                    // append a layer
r.removeLayer(layerId);                  // drop one
r.updateLayer(layerId, { scale: 1.2 });  // patch props on an existing layer
r.reorderLayers([id3, id1, id2]);        // reorder
Use it as a headless player. Mount it in a hidden host, call renderFrame(n) to rasterise thumbnails, and read the canvas contents — no MP4 encode needed.
VideoFlow

Open-source toolkit for composing videos from code.

Product

CoreRenderersReact Video EditorPlayground

Learn

DocsAPI referenceExamplesvs. Remotionvs. FFmpeg

Project

GitHubLicenseContact

Legal

TermsPrivacy
© 2026 VideoFlow. Apache-2.0 core.