The JSON at the heart of every video.
import VideoFlow from '@videoflow/core';
const $ = new VideoFlow({
name: 'Demo',
width: 1920,
height: 1080,
fps: 30,
});
const bg = $.addImage(
{ fit: 'cover', effects: [{ effect: 'bloom', params: { intensity: 0.6 } }] },
{ source: 'https://videoflow.dev/samples/sample.jpg' },
);
bg.animate({ filterBlur: 0 }, { filterBlur: 10 }, { duration: '5s', wait: false });
const title = $.addText({
text: 'Hello!',
fontSize: 2.5, fontWeight: 800, color: '#fff',
}, {
transitionIn: { transition: 'overshootPop', duration: '500ms' },
transitionOut: { transition: 'blurResolve', duration: '400ms' },
});
$.wait('3s');
const json = await $.compile();Six building blocks.
| Type | Method | Key properties |
|---|---|---|
| text | $.addText() | text, fontSize, fontWeight, color, letterSpacing, position |
| image | $.addImage() | source, fit, position, filterBlur, filterBrightness |
| video | $.addVideo() | source, sourceStart, speed, volume, fit |
| audio | $.addAudio() | source, volume, sourceStart, fadeIn, fadeOut |
| captions | $.addCaptions() | captions[], fontSize, color, position |
| shape | $.addShape() | shapeType, width, height, fill, strokeColor, cornerRadius |
Composite a sub-tree as one.
$.group() nests layers inside a container that has its own transform, transitions, and effects. Inside the callback the flow's time pointer resets to 0, so children's timing is authored relative to the group. The group itself is a visual layer — animate scale or rotation on the group and the entire composited tree comes along.
Auto-derived timing: startTime defaults to the current flow time and sourceDuration defaults to the latest child's end. Nest groups inside groups for badges, cards, and scene units.
// Composite a sub-tree as one — transform, transition, animate together.
$.group(
{ position: [0.5, 0.5], scale: 1 },
{
transitionIn: { transition: 'slideLeft', duration: '600ms' },
transitionOut: { transition: 'zoom', duration: '600ms' },
},
(card) => {
card.animate({ scale: 1 }, { scale: 1.04 }, { duration: '2.5s', wait: false });
$.addImage({ fit: 'cover', opacity: 0.55 }, { source: 'https://videoflow.dev/samples/sample.jpg' });
$.addText({ text: 'Composite as one', fontSize: 4, color: '#fff' });
},
);Enter and leave with character.
Attach a transition to any layer with one line. The preset library spans CSS-only transforms (fade, slideUp, overshootPop, rotate3dY) and WebGL passes (blurResolve, glitchResolve, radialZoom, lightSweepReveal, noiseDissolve) — all rendered identically across the three backends.
// 27 presets — fade, slideUp, zoom, overshootPop, blurResolve,
// glitchResolve, rotate3dY, lightSweepReveal, sliceAssemble, and more.
$.addText(
{ text: 'Hello', fontSize: 4 },
{
transitionIn: { transition: 'overshootPop', duration: '500ms' },
transitionOut: { transition: 'blurResolve', duration: '400ms' },
},
);Cinema-grade looks, declared as data.
Stack effects on any layer's effects array and animate their parameters with the dot-path notation (effects.bloom.intensity). The presets cover bloom, glow, motion blur, color grading, frosted glass, prism split, VHS, halftone, light leaks, shockwave, and more — 42 in total.
Set enabled: false to keep an effect's configuration while skipping its pass — useful when iterating in the editor or A/B-ing looks.
// 42 GLSL effects — bloom, glow, motionBlur, chromaticAberration, vignette,
// lightSweep, frostedGlass, vhsDistortion, prismSplit, halftone, lightLeak…
$.addImage(
{
fit: 'cover',
effects: [
{ effect: 'colorGrade', params: { saturation: 0.4, temperature: 0.4 } },
{ effect: 'bloom', params: { threshold: 0.6, intensity: 0.9 } },
{ effect: 'vignette', params: { intensity: 0.6, radius: 0.85 } },
],
},
{ source: 'https://videoflow.dev/samples/sample.jpg' },
);Say time however feels natural.
| Input | Meaning |
|---|---|
5 | 5 seconds |
"5s" | 5 seconds |
"500ms" | 500 milliseconds |
"2m" | 2 minutes |
"120f" | 120 frames |
"01:30" | 1 min 30 sec |
"01:02:30:15" | hh:mm:ss:ff |
Explore the full API.
Layer methods, keyframe semantics, parallel branches, group composition, transition + effect registries — all documented with types you can trust.