How to use Remotion agent skills with Claude Code: what we learned making five product films
Every film on our channel was written as React code by Claude Code with the Remotion skills loaded: a restaurant POS ad, a games promo, a studio showreel and two product films. The setup takes two commands. The lessons that made the renders reliable took longer, and they are below.
We make launch films for software. Not with a timeline editor: every frame is a React component, rendered by Remotion, and most of the code is written by Claude Code while we direct, review stills and fix what looks wrong.
This month alone that has produced a 68-second film for our restaurant POS, a 44-second promo for our free browser games, a 60-second studio showreel and two 30-second product films, plus vertical cuts of each. You can watch them in this playlist. Here is how the setup works and what broke along the way.
Step 1: install the Remotion skills
Agent skills are folders of instructions the agent loads when a task matches. Remotion publishes its own. From your project folder:
npx skills add remotion-dev/skills
Or install them as a Claude Code plugin, which bundles the same skills:
claude plugin marketplace add remotion-dev/claude-code-plugin
claude plugin install remotion@remotion
Restart Claude Code afterwards. In the desktop app the same plugin is under Customize, then Plugins, then Discover. Then start a session in the folder where the video should live and ask for it, for example /remotion:remotion-create Make a promo video for a record store.
The skill that matters most is remotion-best-practices. It is a set of rule files: animations, timing, sequencing, fonts, audio, transitions, captions and more. We have run with it since August. The first day it was installed, it found two real defects in a project Claude had already built. Those are lessons 1 and 2 below.
Step 2: give the agent a timeline, not a vibe
"Make a cool promo" gets you a generic promo. What works is a single file that says what happens on which frame, and everything else reads from it.
For the POS film that file is timeline.json: nine scenes with their start and end frames, plus every cue inside them (each tap on the till, each receipt print, each stamp). The React scenes read it to animate. The music script reads the same file to place every sound. So a tap lands on the frame the finger touches the button, by construction, and moving a cue moves both.
That one decision made the agent far more useful. Instead of "make the second scene snappier", the instruction becomes "move the receipt print from frame 142 to 136", and it can check its own work.
Step 3: film the real product, frame by frame
Screen recordings stutter, and AI-generated "app footage" shows an app that doesn't exist. We wanted real screens, perfectly smooth. So Claude Code wrote a small recorder that drives headless Chrome over the DevTools protocol:
- load the real page, block analytics so the recording never counts as a visit, and switch off CSS transitions;
- for each frame, set the state for that frame (type one more letter, move a slider one step, advance the game by exactly 1/60 s);
- wait two animation frames, take a screenshot, repeat.
Because time only moves when the script moves it, a slow laptop still produces perfect 60 fps footage. The CrewCalculator film's stair blueprint redraws live as the rise changes. That is the real site, filmed one frame at a time.
Step 4: make the music in code too
Every score on our channel is synthesised sample by sample from the same timeline: chords, bass, hats, a whoosh on each transition and a short sonic logo on the end card. Nothing is licensed, so nothing gets a Content ID claim, and the mix is mastered to -14 LUFS for YouTube. The Funeral Kit film is the exception on purpose: a quiet felt piano at -16 LUFS, because a gentle product should not sound like a launch party.
The lessons that cost us renders
None of these is in a tutorial. All of them happened to us.
1. Pin every Remotion package to the same exact version
One package had a caret (^4.0.504) and quietly floated to 4.0.506 while the rest stayed on 4.0.504. Remotion prints a warning about exactly this on every render, and we read it as noise for a whole session. Mismatched versions can break React context, hooks and renders in ways that are hard to trace. Remove every ^ from remotion and @remotion/*, reinstall, and run npx remotion versions, which should report that all packages match.
2. Premount every Sequence
Without premountFor, a scene's fonts and video start loading on the exact frame they must already be visible. That shows up as a flash or a frozen frame at the cut. Premount by a second's worth of frames and the cuts become clean.
3. Never put a font delayRender at module level
Our first POS render waited for fonts in a module-level delayRender. It timed out three times mid-render, at frames 685, 451 and 214, once a long render recycled a browser tab, even with the fonts embedded. What fixed it: embed the font files as base64, do the wait inside each composition, and render at concurrency 3.
4. Clean up the temp folders, or lose your disk
Every render bundles your project, including a full copy of public/, into the system temp folder, and the copy stays there afterwards. We found 134 of them, 10.5 GB, on a laptop with a nearly full drive. Videos you place with OffthreadVideo get copied too: one stills session left 5.5 GB. Our render scripts now delete their own bundle in a finally block, and we sweep old remotion-* temp folders after each release.
5. Check helpers that clamp before their start frame
A small easing helper of ours returned its start value for every frame before the animation began. A flash overlay built on it was therefore "on" for every future flash at once, and the render came out with white frames. The fix is one line: return nothing until the cue's frame. The lesson is to look at stills from before each effect, not only during it.
6. Let Chrome pick its own debugging port
Two recordings started at once picked the same random fixed port. Both scripts silently drove the same tab, so we got doubled events and interleaved frames. Start Chrome with --remote-debugging-port=0 and read the port it actually chose from DevToolsActivePort.
How we review without watching a render 50 times
A full render takes minutes. A still takes seconds. So the loop is: render 10 to 20 stills at the moments that matter (each cue, each cut, the frame before each effect), lay them out on a contact sheet, fix, repeat. We only render the full film once the stills are right, and then check loudness and true peak with ffmpeg before anything is uploaded.
The agent writes the code. The timeline, the stills and the honesty rules are what make the film good. On ours, every product is real, every number is checked against the product, and nothing is shown that the software can't do today.
The films
- Pixel & Oak POS, 68 s: the restaurant till, a live orders board, an online order and offline billing
- Pixel & Oak Games, 44 s: real gameplay recorded frame by frame
- CrewCalculator, 30 s: a stair blueprint redrawn live from the real site
- Funeral Kit, 33 s: the quiet one
- Studio showreel, 60 s: all of the above