Video

Video reference

Composition model, SDK surfaces, DSL fields, and renderer options for Cuitty Video.

Video reference

Cuitty Video has four core surfaces:

SurfacePackagePurpose
SDK@cuitty/videoBuild a composition in TypeScript and export Composition IR.
DSL@cuitty/video-dslParse YAML or JSON into the same Composition IR.
Renderer@cuitty/video-renderRender frames with Playwright and encode with FFmpeg.
Player@cuitty/video-playerPreview Composition IR in the browser.

The CLI and server are thin workflow layers over those packages.

Composition IR

Every composition resolves to the same shape:

FieldTypeNotes
idstringStable composition identifier.
widthnumberOutput width in pixels.
heightnumberOutput height in pixels.
fpsnumberFrames per second.
durationInFramesnumberTimeline length after duration parsing.
layersLayerIR[]Ordered visual layers.
audioTracksAudioIR[]Optional audio tracks.
transitionsTransitionIR[]Optional clip transitions.

Layers contain clips. Clips define startFrame, endFrame, renderType, renderProps, and optional animation metadata.

TypeScript SDK

Use the SDK when composition data comes from code:

import { composition, tween, Easing } from "@cuitty/video";
import { render } from "@cuitty/video-render";

const video = composition({
  id: "status-report",
  width: 1920,
  height: 1080,
  fps: 30,
  durationInFrames: 180,
});

video.layer("title").clip({
  startFrame: 0,
  endFrame: 120,
  render: (ctx) => {
    const opacity = tween(ctx.frame, [0, 30], [0, 1], {
      clamp: true,
      easing: Easing.out(Easing.cubic),
    });

    return `<h1 style="opacity:${opacity}">Weekly status</h1>`;
  },
});

await render({
  composition: video,
  outputPath: "./output/status-report.mp4",
  codec: "h264",
  crf: 18,
});

YAML DSL

Use the DSL when a composition should be editable as data:

composition:
  id: status-report
  width: 1920
  height: 1080
  fps: 30
  duration: 6s

layers:
  - id: title
    clips:
      - id: headline
        start: 0s
        end: 4s
        render:
          type: text
          text: "Weekly status"
          fontSize: 72
          color: "#ffffff"
        animate:
          - property: opacity
            from: 0
            to: 1
            start: 0s
            duration: 1s
            easing: cubic-out

The DSL accepts YAML or JSON. duration, start, and end can be frame numbers or time strings such as 500ms, 2s, or 00:00:02.

Render options

OptionDefaultNotes
outputPathRequiredFinal output file path.
codech264Supports h264, h265, vp9, prores, and gif.
crf18Lower is higher quality for CRF-based codecs.
concurrencyCPU-dependentParallel frame rendering.
onProgressNoneReceives frame count, total frames, and render FPS.

Server workflow

The render server accepts composition payloads, creates jobs, reports status, and runs the same render pipeline behind an HTTP boundary. Use it when renders should be queued or called by another service instead of run directly in the CLI.

Observe integration

Video render jobs can emit progress, failure, and encoding metadata into Observe. The standalone Video product owns authoring and rendering; the existing Video module remains the Observe module for browser-session recording job metadata.