You can make the same kind of clip that went around after the Opus 5.5 launch. It is not a video model. You clone a starter kit, open it in Claude Code, and ask Opus 5.5 for a fifteen-second cartoon. The model writes a storyboard, paints frames in JavaScript, and a render script turns those frames into out/video.mp4.
This guide follows ClaudeAnimationBase, the MIT kit John Heibel published from the P(doom) music video. His README is one prompt and two commands. The rest of this page is what to do when that prompt runs, what to check before you wait on a full encode, and the failures that show up on a Mac or a machine without a GPU.
The Western civilization montage is a separate viral caption. How that tweet spread is in the clip write-up. Use this page when you want a file on disk.
What you are making
| Question | Answer |
|---|---|
| End file | out/video.mp4, a 1920×1080 cartoon |
| First prompt | A 15-second Clawd film. The kit's example is a butterfly chase |
| Model | Claude Opus 5.5 in Claude Code. Heibel's tests used xhigh |
| Install | Node.js, Google Chrome, ffmpeg |
| Repo | JohnHeibel/ClaudeAnimationBase |
| You review | STORYBOARD.md, then a contact sheet, then the MP4 |
| You do not need | Sora, Veo, stock footage, or an image generator |
Clawd is the painted lobster already in the kit: five views, 31 emotions, hats, and emotes. You can swap the character later. Do not start there.
Step 1 — Install the three tools and render the demo
You need Node.js, Google Chrome, and ffmpeg on the PATH. Check them before you open Claude:
node -v
ffmpeg -version
Chrome has to be the real Google Chrome (or Chromium), because the renderer drives it headless. Then:
git clone https://github.com/JohnHeibel/ClaudeAnimationBase.git
cd ClaudeAnimationBase
npm install
node render.mjs --clip --out=out/video.mp4
That command renders the bundled 11-second demo in src/scenes/demo.js. If out/video.mp4 plays, the pipeline works and Claude has not been asked to invent one. If it does not play, fix Chrome and ffmpeg now. Debugging a model and a missing binary at the same time is how an afternoon disappears.
Open studio.html in Chrome and scrub. ?t=2.5 jumps to a time. ?loop=emotions and ?loop=views show the model sheets. If Chrome is not in a standard location, pass --chrome= or set CHROME_PATH.
On Linux the script adds --no-sandbox, because Ubuntu 23.10 and later block Chrome's sandbox in headless use. It will also look for a Chromium that Playwright installed. With no GPU, add --soft-gl so WebGL runs in software. Watercolour fills get slow in that mode. On a headless NVIDIA box, --gpu-angle=gl-egl (or vulkan) is the kit's documented switch. node gpu_probe.mjs prints which renderer a flag set actually gets.
A Mac port of the original music-video renderer failed with "Error creating webgl context" because it passed --use-angle=d3d11 (Direct3D, Windows). The fix there was --use-angle=metal and the macOS Chrome binary. If the starter kit's demo dies the same way, that is the flag to change. Do not re-prompt the model until a frame renders.
Watercolour fills are the slow part. Heibel measures them in seconds per frame on integrated graphics. If you are on a laptop GPU, tell the model to skip watercolour fill and use flat washes. The look is less soft. The render finishes.
Step 2 — Open the folder in Claude Code on Opus 5.5
claude
/model should be Opus 5.5. Heibel says the reasoning level tracks how ornate the picture gets, and that his test videos were Opus 5.5 on xhigh in Claude Code. For a first 15-second film, xhigh is the setting the kit was exercised on. If xhigh stalls or burns the session, drop to high for the storyboard only, then come back. Do not start on a smaller model and hope the brushes match. The prompting guide covers how Opus 5.5 treats a long structured brief. This job is that kind of brief.
Paste the README's prompt, unchanged, the first time:
Read ANIMATION_GUIDE.md, then make a 15-second video of Clawd trying to catch a butterfly.
That one sentence is doing more work than it looks. ANIMATION_GUIDE.md is the director's rulebook: handmade brush strokes, something happening in every shot, no captions, a transition on every cut, and a storyboard before any scene code. The subject ("catch a butterfly") is yours. The how is the file.
Step 3 — Stop the model after the storyboard
The guide's workflow has four beats. You only need to intervene on the first and the third.
1. Storyboard. The model should write STORYBOARD.md before it touches src/scenes/. The format it is supposed to use is a logline (Clawd wants something, but something, so something), a world, a motif, an emotion arc, and a shot list. Each shot has a start, an end, a transition, an event, and a list of "reads" — the things a viewer has to understand, with times that do not overlap.
Read that file yourself. Check four things the guide uses as a gate:
- Every shot has an event. "Clawd stands in a meadow" is not a shot.
- No two important reads occupy the same seconds.
- Every seam has a transition, including into the first shot and out of the last.
- There is no text. A sign that says "I'm lost" is the failure mode the guide names. Lost has to be acted: look left, look right, map upside down.
If the storyboard is a paragraph of vibes, say so and ask for the shot list with times. Do not let it write src/scenes/my_video.js yet. The music video that this kit was extracted from took two generations. The storyboard was the point of the first one.
2. Build. After you accept the storyboard, it sets duration and bpm in src/config.js, adds a scene file, and replaces the demo.js script tag in studio.html with that file. Scenes are functions of time. A shot is fn(t, lt, dur): video time, time inside the shot, shot length. The same t must paint the same frame every time. No Math.random(), no counter that survives from the previous frame, no physics that integrates step by step. Boil (the hand-drawn wobble) is reseeded 12 times a second on purpose. Anything that must stay put, like a star, uses hash(i).
You do not have to write that function. You do have to reject a scene that stores state in a variable outside the function. Parallel render will call frame 40 before frame 39, and a counter will lie.
3. Look. This is the step people skip, and it is why the MP4 comes out wrong.
node render.mjs --sheet=0.1,0.8,1.6,2.4,3.1,3.9 --cols=6 --w=320 --out=out/check/sheet.jpg
node render.mjs --strip=2.1:2.6 --cols=6 --w=320 --out=out/check/strip.jpg
node render.mjs --sheet=2.3,2.4 --crop=760,420,500,400 --w=500 --out=out/check/face.jpg
Open the JPEGs. The sheet is the shape of the film: first, middle, and last of each shot. The strip is every frame of one motion, which is the only way to see a pop or a missing anticipation. The crop is the face at full resolution. Contact sheets are cheap next to a full encode. The guide's budget is at least one sheet per shot, a strip for every key motion and transition, and a crop for every face that carries the story.
Ask Claude to read those images and name what failed. If image upload is rejected, do not keep saying "look again." The frames are on disk. A reviewer that can see, or your own eyes, is the fallback. Pixel stats (mean color, bright-pixel share, bounding box) catch a blank frame. They do not catch a butterfly that never gets caught.
4. Render only after the sheet looks like the storyboard.
node render.mjs --clip --out=out/video.mp4
For anything past about fifteen seconds, the guide's other path is resumable:
node render.mjs --frames --workers=4
node render.mjs --encode --out=out/video.mp4
--frames writes JPEGs under out/frames with several Chrome workers. A crash continues. --encode makes the MP4 from those stills. Add audio on the encode step when you have a track (--audio=assets/song.mp3 is the flag the music-video pipeline used). Confirm it in render.mjs --help or the README of the commit you cloned. Flags move.
One ffmpeg trap from the music-video build: -shortest can hang forever if the input still has a subtitle stream. Pass an explicit -t duration instead.

Step 4 — Change the film without starting over
Once the butterfly plays, edit the storyboard, not the tweet.
| You want | Do this |
|---|---|
| A different gag | Change the logline. Keep the 15-second cap until the review loop is boring |
| Your own character | Ask it to replace Clawd, and give it a reference image. The guide says no design in the kit is final |
| A new emotion or hat | Ask for it as a drawn view, not a 3D spin. The kit forbids perspective and rotateY |
| Music | Put a file in assets/ and point PROJECT.audio at it. Hits belong on PROJECT.bpm |
| A longer film | Split shots across files only after the short one encodes. Chapter agents should not edit shared helpers |
| Flat color, faster renders | Tell it to avoid watercolour fill on integrated graphics |
The guide's medium is specific, and fighting it is how the film starts looking like old Flash. Paint goes through paint() and inkLine(), not raw rect and ellipse. Linework is supposed to boil. Faces change through emotions(), which anticipates and overshoots, instead of swapping a mouth between two frames. Clawd in a medium shot is large (u around 20–28). A tiny character for the whole video reads as a bug.
No captions, titles, or speech bubbles. Reactions are painted marks: !, ?, sweat, a heart. If your idea truly needs one word, the guide's letter() paints it into the scene, once, one or two words. A history montage full of dates is a different film from this kit. You can demand the words. Expect to re-render the cards.
What the viral clips were, in this same pipeline
You do not need this history to finish step 3. It explains why a 2-minute tweet is a bad first target.
PDoomVideo is a 156.6-second lyric video. The published account is two generations in Claude Code: Opus 5.5 at medium, then again at the default effort. The human asked for the Clawd character and a visual on every lyric line. The model wrote the stage play, including a thermometer that climbs 8, 34, 61, 86, 99.9. Nine chapter files, parallel subagents, an animation guide that told each agent not to patch shared files. At 24 fps that is about 3,760 frames. Heibel then lifted the engine into ClaudeAnimationBase so the next person would not reconstruct it from a music-video repo.
A second public film, Peter Kim Frank's explainer about its own making, forked that renderer. Draft 2 was 3,224 frames at 30 fps (107.5 seconds) across four Chrome workers. A reviewer scored one draft-1 frame 4/10 because the thing being graded was still a placeholder. That note is the review loop in the wild.
A third film, a three-minute history of AI, used Remotion (React) instead of p5.js: on the order of 7,400 lines, SVG and canvas, an open-source voice, a Python score, about an hour, and about 7% of a weekly Claude limit. Same idea, different host. Do not start on Remotion unless you already render Remotion compositions. The p5 kit is the one with the storyboard gate written down.
The Western civilization clip is the one with millions of views. The poster called it one shot. Nobody has published that session. The repos that did publish sessions show a storyboard and a second pass. Copy the repos.
Cost and when to stop
The render is Chrome and ffmpeg. The model bill is the storyboard, the scene file, and the repair turns after you look at the sheet. A 15-second first film should be a small slice of a session. The hour-and-7% figure is one builder's three-minute Remotion film, not the butterfly.
List prices for the tokens themselves are in the Opus 5.5 launch notes. Run /usage at the end if you want the session receipt. Re-rendering frame 400 does not re-bill the model. Asking the model to "make it better" without a sheet attached does.
Stop when the contact sheet matches the storyboard and the MP4 plays. A second gag is a new storyboard, not another hour on the same file.
If you already have footage
This pipeline draws pictures that do not exist yet. video-use cuts footage you already shot, from a transcript. Sora, Runway, and Kling are the diffusion path, when you want photographed pixels and will accept that you cannot diff them. HTML canvas is the drawing surface underneath the kit, if you want to read paint() as a canvas API instead of as a magic prompt.
Related on explainx.ai
- The Western civilization clip, as a news post rather than a tutorial
- Opus 5.5 launch benchmarks and list prices
- Opus 5.5 prompting guide
- What builders shipped in the first day
- HTML canvas
- video-use, for cutting footage
- Sora, Runway, and Kling
Kit: ClaudeAnimationBase and PDoomVideo. The storyboard format, review commands, and demo render are from ANIMATION_GUIDE.md and the README in that repo.
Commands match ClaudeAnimationBase as of September 27, 2026. Read render.mjs in the commit you cloned before you trust a flag, including the ones printed here.
