Vawe

Introduction

Vawe turns one self-describing JSON file into one rendered video, deterministically. Here is what that means and why it is built this way.

Vawe reads a single JSON file and renders a video from it. No timeline, no editor, no dragging clips around. You describe the scene, and the engine draws every frame.

./bin/vawe formats/scene/sample.json
# → out/sample.mp4

That is the whole loop. The JSON is the source of truth; the mp4 is a build artifact you can delete and regenerate at any time.

What makes it different

Two ideas do most of the work.

Everything is one open canvas. There is exactly one module, scene, and it is a vocabulary of composable primitives: text, images, captured UI, charts, cards, cursors, shaders, backgrounds, cuts, and stings. There are no templates to pour data into. You compose each video from the layer vocabulary, the same way you would compose a page out of HTML elements.

Every frame is a pure function of its number. renderFrame(n) depends only on n. A virtual clock coerces Date, requestAnimationFrame, timers, and Math.random to frame time, so there is no wall clock and no unseeded randomness anywhere. The same JSON produces byte-identical frames no matter what order they render in. That is what lets frames shard across parallel headless Chrome tabs, and it is what makes a video reproducible and diff-able. Read more in Determinism.

How a render actually works

data.json
  → cmd/render (Go)
  → chromedp: N headless Chrome tabs, each seeks renderFrame(n) → PNG
  → internal/encode: ffmpeg stitches the PNG sequence → H.264, adds film grain
  → internal/audio: a Go PCM mixer builds music + sound effects + voiceover
  → out/<name>.mp4

The output is a 30fps H.264 mp4 with AAC audio, in portrait (1080×1920), landscape (1920×1080), or square. One source can render every aspect ratio in a single pass.

Where to go next

These docs describe what the engine does today, drawn straight from the code. The source is not public yet, so nothing here links into it. Everything on these pages runs in the editor in the meantime, on the same engine.

On this page