Skip to content
GTHome
All projects

Developer (Solo) · 2026

Open Source

motion-studio

A studio for making motion graphics with Claude, where every video is a program: a frame-accurate renderer, synthesized scores, automated checks on every film, a Claude Code skill that runs the whole pipeline, and an eight-lesson course with a companion website.

Next.jsTypeScriptPlaywrightFFmpegPythonClaude Code
motion-studio preview
motion-studio screenshot
motion-studio screenshot
motion-studio screenshot

Problem

Motion videos made with Claude were all over my feed, but the guides behind them mixed real technique with claims nobody had checked, and a model that can't watch video or hear audio has no way to tell whether its own film is in sync or readable on a phone.

Approach

Built a small studio where each film is a web page with one pure function, seek(t), that paints the exact frame for time t. Playwright's Chromium renders every frame and FFmpeg encodes them, scores are synthesized on the film's own beat grid, and every claim from the article I learned from was checked against primary sources across eight lessons.

Tech highlights

A renderer with parallel workers, a network sandbox and explicit BT.709 color, streaming frames straight into FFmpeg; tools/check.py measures determinism, per-cue audio and visual sync, loudness, text clipping and minimum text size on phones; closed-form springs tested against the ODE; a determinism hook and a /motion-film skill for Claude Code. The companion site is a static Next.js export generated from the repo: films with their check reports, lessons with quizzes, and a page on what each test proves and what it doesn't.

Results

Four films, the latest a 32 s Safari OS launch film rendered at 16:9, 9:16 and 1:1 from one timeline with all 51 sound cues landing within one frame of the picture. The code, course and films are open source, and the site is live.

Challenges

A check only proves what it measures: several bugs passed every automated check until a person looked or a new check was written, from text clipped inside passing shapes to a render that only failed in a fresh clone.

More like this