VideoFlowcodeGitHubTry itCoreRenderersReact Video EditorPlaygroundExamplesDocscodeGitHubTry it
@videoflow/core · Apache-2.0

The JSON at the heart of every video.

A fluent, sequential TypeScript builder. Add layers, group them, chain animations, run branches in parallel, attach transition presets and GLSL effects — then compile the whole flow into a portable VideoJSON that any VideoFlow renderer can play.$ npm install @videoflow/corecode Source on GitHubAPI reference →
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();
Layer types

Six building blocks.

TypeMethodKey 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
Layer groups

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' });
  },
);
Two card scenes with a nested badge group.
27 transition presets

Enter and leave with character.

Eight presets, back-to-back, on the same layer.

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' },
  },
);
All transitions →
42 GLSL effects

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' },
);
All effects →
Bloom, glitch, and frosted-glass passes — three panels back-to-back.
Time formats

Say time however feels natural.

InputMeaning
55 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.

API referenceTry it live
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.