Scripted short-video renderer for developers who'd rather write markdown than
open DaVinci. script.md in → rendered vertical video out.
The bundled examples/hello-bench episode — five scenes rendered entirely
from markdown + SVG placeholders. This strip is actual output.
- Rust orchestrates everything (
videoeditor, one binary). - Web tech does the animation: scenes are HTML templates rendered
frame-by-frame by headless Chrome as pure functions of
(data, t). - ffmpeg does the heavy lifting; ElevenLabs voices the narration.
- Built to be driven by Claude Code — scaffolds wire the session up automatically.
With nix (preferred — pins the binary, ffmpeg, and the render browser from the committed lockfile; details and every run variant in docs/nix.md):
curl -fsSL https://install.determinate.systems/nix | sh -s -- install # once
nix profile install github:security-union/videoeditorWithout nix: cargo install videoeditor, then bring ffmpeg
(brew/apt/dnf install ffmpeg) and Chrome (system install is auto-detected;
CHROME_BIN overrides). macOS and Linux; on Windows use WSL.
Voicing needs an ELEVENLABS_API_KEY
(elevenlabs.io → profile → API keys; free tier is
plenty). Everything except tts/analyze runs keyless.
videoeditor new my-first-short # runnable scaffold, placeholder assets included
cd my-first-short && claude # then type /directNo Claude? The manual loop: edit script.md, then
videoeditor build . (tts → render → assemble) and open build/final.mp4.
Iterate one piece at a time: tts . --clip name --force re-rolls one voice
take, render . --scene name re-renders one scene, assemble . re-mixes in
seconds. videoeditor guide prints the full rulebook.
The tool wires Claude Code up by itself: every scaffold carries a CLAUDE.md,
videoeditor -h points agents at the embedded rulebook (videoeditor guide),
and /direct — dropped into every episode — runs the wizard: it interviews
you (format, topic, real data for the receipts, tone, assets, voice), then
drives script → voice → render → final.mp4 with approval checkpoints before
anything costs money. Or skip the wizard and ask in your own words:
"Make a 25-second short: Rust vs Go parsing a 1GB JSON file. Run a real benchmark first, then script it, voice it, render it, and QA the frames."
script.md ──parse──► timeline plan
│
├─ videoeditor tts [CLIP:] → ElevenLabs → audio/clips/ + audio/clips.json
├─ videoeditor render [SCENE:] → Chrome frames → ffmpeg → build/scenes/
└─ videoeditor assemble concat + narration@offsets + music → build/final.mp4
A scene names a template and a duration; [DATA:] feeds the template;
[CLIP:] blocks carry narration placed at exact offsets. The engine warns
when narration overlaps (fit-check) or a template clips its content — and
the whole render is deterministic: same inputs, same pixels.
It's a five-crate Rust workspace, ffmpeg-style (thin CLI over focused libraries) — the crate map lives in CLAUDE.md.
Browse the repertoire: videoeditor templates lists every scene template
with its data keys; videoeditor preview renders each one's demo into a
contact-sheet PNG so you can see the motion before using it.
Your look doesn't live in the engine: each episode can carry its own
templates, and shared packs carry a channel's identity across videos —
layered resolution, most specific wins. videoeditor pack init scaffolds
one, including the authoring contract Claude follows (compose the proven
animation blocks in _lib/scene.js; never hand-roll curves). Full guide:
docs/templates.md.
| Where | What |
|---|---|
videoeditor guide |
the embedded rulebook: grammar, director loop, craft rules |
| docs/templates.md | organizing templates: per-video, packs, machine-wide |
| docs/nix.md | deterministic installs, dev shell, releases |
| CLAUDE.md | contributor + agent operations: crate map, commands, invariants |
| examples/hello-bench | the end-to-end example episode |
MIT licensed. Syntax highlighting via highlight.js (BSD-3-Clause, vendored).