Remotion Skill for Claude Code: Finished Shorts From One JSON File, Checked Before Render An open-source, MIT-licensed Remotion skill for Claude Code lets coding agents produce finished vertical shorts for TikTok, Instagram Reels and YouTube Shorts from a single JSON file of scenes. The bundled Remotion project handles text fitting, scene timing, review-sheet generation and MP4 rendering, and the skill checks its own output before the user approves posting; it also works in Codex, Cursor and OpenClaw. The project ships six scene types, five themes and a layout engine that keeps text clear of platform UI overlays using the strictest published safe-area figures. Remotion skill for Claude Code, open source and MIT licensed: Remotion Shorts Skill lets your agent turn a topic, an article, a dataset or a changelog into a finished vertical short for TikTok, Instagram Reels and YouTube Shorts. It also works in Codex, Cursor and OpenClaw. The agent writes one JSON file of scenes. A bundled Remotion project lays out every word, times every scene, renders review sheets and then the MP4, and the agent can post it after you say yes. This post covers how to use it, then the parts that are code: how text is fitted, how timing is decided, and how the skill checks its own output before you see it. npx skills add social-media-skills/remotion-shorts-skill -g -a claude-code -y Repo: github.com/social-media-skills/remotion-shorts-skill https://github.com/social-media-skills/remotion-shorts-skill Frames from the two examples in the repo. Figures in the water short come from the USGS Water Science School; the Earth image is NASA's Blue Marble 2012. Both scripts were written by an AI agent with the skill; no endorsement by USGS or NASA is implied. A Remotion skill is an agent skill a folder with a SKILL.md and supporting files that tells a coding agent like Claude Code how to make video with Remotion https://www.remotion.dev , the React framework for programmatic video. Most Remotion skills teach the agent to write Remotion components. This one works the other way round. The Remotion project is already written and tested, and the agent only writes the script. You get one job done well: kinetic-text shorts big animated words, stat count-ups, top-N lists, quotes, launch and changelog videos at 1080x1920. npx skills add social-media-skills/remotion-shorts-skill and pick yours, or openclaw skills install @social-media-skills/remotion-shorts-skill . setup.mjs , which copies the Remotion project, installs pinned packages and downloads the headless browser Remotion renders with 1 to 3 minutes . short.json node render.mjs short.json --stills to get review sheets in a few seconds. Here is the exchange from the water example in the README, shortened: You: Make a short about how much of Earth's water is fresh. Use real numbers. Ocean colours. Agent: Using the USGS Water Science School figures. Review sheets are ready: 8 scenes, 22.3 seconds, no warnings. You: Looks good. Render it. Coding agents can write Remotion components from scratch, and for a one-off motion piece that is the right approach. For shorts posted every week it causes problems. Each video is new code, so each video can have new bugs. Nothing checks that text stays out from under the app's buttons. And nobody decides how long a scene should stay up, so the timing is whatever the agent guessed. This skill splits the job. The Remotion project is fixed: six scene types hook , text , stat , item , quote , end , five themes and a layout engine. The agent writes only the script: { "theme": "ocean", "footer": "Data: USGS. Earth image: NASA", "scenes": { "type": "hook", "big": "2.5%", "text": "of Earth's water is fresh", "image": "earth.jpg" }, { "type": "stat", "value": "96.5", "suffix": "%", "label": "is salt water in the oceans" }, { "type": "stat", "value": "68.7", "suffix": "%", "label": "of the fresh water is locked in ice and glaciers", "highlight": "ice and glaciers" }, { "type": "end", "text": "Save this for trivia night", "highlight": "Save this" } } The agent's effort goes into what each screen says, which is the part that decides whether people keep watching. TikTok, Reels and Shorts all draw on top of the video: search and tabs at the top, the caption, username and music line at the bottom, like and share buttons on the right. Text under any of them is lost. Only Meta publishes numbers keep the top 14%, the bottom 35% and 6% on each side clear . TikTok ships overlay files and YouTube shows its safe area as an image. The template takes the strictest edge of the three on a 1080x1920 frame: js // src/theme.ts export const SAFE = { top: 288, bottom: 672, left: 96, right: 192 }; That leaves 792x960 pixels for text. Centred text uses 192 px on both sides so it sits on the frame's centre line. Photos and backgrounds still fill the frame; only text stays inside. calculateMetadata runs in the headless browser before any frame renders, so it can measure text with the real fonts. measureText from @remotion/layout-utils measures every word once at 100 px; widths then scale linearly, and the layout searches sizes from the scene's maximum down to a readable floor. The biggest size that fits is not always the best. A seven-word hook at maximum size can come out as four lines with one word stranded on the last. So each candidate a size plus a line count gets a cost: js // src/layout.ts const lonely = words.length 2 ? lines.filter l = l.length === 1 .length 0.2 : 0; const widow = lines.length 1 && lines lines.length - 1 .length === 1 && words.length 2 ? 0.1 : 0; const cost = max - size / max + 0.3 Math.max 0, lines.length - 3 + lonely + widow + 0.05 ragged; Bigger is better, more than 3 lines costs extra, a one-word line costs extra more so on the last line , and ragged penalises lines of very different length. For each line count it binary-searches the narrowest measure that still gives that many lines, which balances them. Three details keep text inside the box: 96.5% sets the suffix at 0.62 em and the digits with tabular-nums , so the measurement uses the same parts. A single word too wide for the screen at the smallest size is an error, not a warning. --force can override warnings but never puts text off screen. Each scene stays up long enough to read, and no longer: js const CPS = 17; // characters per second const PER WORD = 0.3; // seconds per word const read = s = Math.max s.length / CPS, countWords s PER WORD ; const needed = ENTRY + 0.4 reveal + hold; The numbers come from subtitle practice: BBC guidance of about 0.33 seconds per word and Netflix's 17 to 20 characters per second for adults, slightly faster here because the text is the whole picture. People read while the words rise into place, so only 40% of the reveal time is added on top. Stats get time for the count; the small line under a list item counts at 60%, because it is skimmed. In practice a hook lands in 2 to 3 seconds, a stat in 2.5 to 4 and a list item in 2 to 3. The water example is 8 scenes in 22 seconds. With a bpm , every cut moves to the next beat, never an earlier one, so snapping cannot cut a scene short of its reading time. TikTok and Reels show frame 0 in the profile grid, and it is the first thing a scroller sees. So the first scene is fully set on frame 0, and only the highlight wipe and the punch move after it. Every later scene starts already moving, so no cut lands on an empty frame. Words rise from behind a mask instead of fading, so no frame shows grey, half-transparent text. The highlighted run is drawn twice: the normal colour underneath and the accent-text colour on top, clipped by the same edge as the wiping block, so the text is readable at every frame of the wipe. node render.mjs short.json --stills runs in a few seconds and writes: sheet.jpg : the last frame of every scene, with the safe area marked by a thin dashed line; cuts.jpg : frame 0 and the frames around every cut; cover.jpg : the hook once it has landed; report.json : the plan, line breaks and warnings. The agent opens both sheets before rendering the video. Warnings stop the render with exit code 2: text too long for one screen, a hook over about 10 words, a highlight that is not in the text, a scene too fast to read, a short over 59 seconds YouTube blocks Shorts over a minute worldwide if any copyright claim lands on them . The sheets are Remotion compositions too: a grid of