remotion-best-practices
Skill0 starsChanged 3 months agoMITView on GitHub
Best practices for Remotion - Video creation in React
149 other projects use a version of this, 104 of them edited.
Adopted by
Most recently taken up by
- anyreachai/claude-skillsedited, first seen Nov 8, 2026
- mia-cx/skillstheir own version, first seen Nov 8, 2026
- mxrsv/agents-skillstheir own version, first seen Nov 8, 2026
- HeteroCat/heterocat-skillsedited, first seen Nov 8, 2026
- insight68/Skillsedited, first seen Nov 8, 2026
- OpenMontageInc/OpenMontageedited, first seen Nov 8, 2026
Used with
Projects with it also use ltx2, canvas-procedural-animation and 10 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
LinHao-citySkillltx2
AI video generation with LTX-2.3 22B — text-to-video, image-to-video clips for video production. Use when generating video clips, animating images, creating b-roll, animated backgrounds, or motion content. Triggers include video generation, animate image, b-roll, motion, video clip, text-to-video, image-to-video.
Also in 6 projects that use this
LinHao-citySkillcanvas-procedural-animation
Use p5.js/canvas for local procedural character effects: particles, weather, squash/stretch, walk cycles, and environmental motion.
Also in 5 projects that use this
OpenAISkillremotion-saas
Build an app with Remotion
Also in 21 projects that use this
OpenAISkillremotion-maps
Remotion Map animation knowledge
Also in 17 projects that use this
mia-cxSkillremotion-license
Find Remotion license information, FAQs, terms, and where to buy a license.
Also in 4 projects that use this
- +5 more from openai
- +2 more from LinHao-city
Other versions149 projects use a version of this.
Word for word · 0
None found.
Edited · 104
- calesthio/OpenMontage★ 78k96% same
- OpenMontageInc/OpenMontage★ 78k96% same
- vercel-labs/json-render★ 19k97% same
- netease-youdao/LobsterAI★ 6.2k95% same
- KurtGokhan/tegaki★ 3.3k20% same
- chmod777john/agent-wechat★ 1.5k86% same
- chmod777john/swarm-ide★ 1.5k86% same
- dtsola/xiaoyaosearch★ 1k85% same
- freestylefly/wesight★ 96995% same
- kapishdima/soundcn★ 86498% same
94 more not listed
Wrote their own version · 45
- openai/plugins★ 7.8ksame name
- remotion-dev/skills★ 6.6ksame name
- composio-community/open-claude-cowork★ 4.3ksame name
- ComposioHQ/open-claude-cowork★ 4.3ksame name
- digitalsamba/claude-code-video-toolkit★ 2.5ksame name
- remotion-dev/claude-code-plugin★ 79same name
- PinkR1ver/vibe-roast★ 49same name
- anton-abyzov/vskill★ 47same name
- doggy8088/agentready★ 34same name
- STARDUSTLC666/dsh-remotion★ 34same name
35 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository23 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- add-inspirationSkill
- brandSkill
- craft-contentSkill
- draft-articleSkill
- draft-carouselSkill
- draft-diagramSkill
- draft-imagesSkill
- draft-videoSkill
- heygen-avatarSkill
- heygen-videoSkill
- humanizerSkill
- ingestSkill
- initSkill
- linkedin-postSkill
- lintSkill
- listenSkill
- meetingSkill
- voiceSkill
- wikiSkill
- youtube-descriptionSkill
- youtube-shortSkill
- youtube-uploadSkill
The file
Show its rules and text
We split this skill into the rules it gives an agent
16 rules. 1 is common, 9 are distinctive, and 6 are very specific to this project.
1
Common
Most of the 146 edited versions we read keep these.
9
Distinctive
This author's own choices. Worth a look.
6
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Common: line 10
Use this skill whenever you are dealing with Remotion code to obtain the domain-specific knowledge.
- Very specific: line 16
Use
<Series>for sequential shots: Never compute frame offsets manually with <Sequence>. - Very specific: line 18
Use
<Video>from@remotion/mediafor video playback: Never use plain HTML <video> tags (they don't sync with Remotion's timeline). - Very specific: line 20
Import JSON data at build time: Never use useDelayRender() + fetch() for data the composition needs.
- Distinctive: line 26
Caption timing must come from transcription, not estimation: Never divide duration evenly across words.
- Distinctive: line 30
After generating or regenerating audio (ElevenLabs, HeyGen, etc.), transcribe it for word-level caption timing.
- Distinctive: line 53
When dealing with captions or subtitles, load the ./rules/subtitles.md file for more information.
- Distinctive: line 61
When needing to visualize audio (spectrum bars, waveforms, bass-reactive effects), load the ./rules/audio-visualization.md file for more …
- Distinctive: line 65
When needing to use sound effects, load the ./rules/sound-effects.md file for more information.
- Very specific: line 71
Always render with
--image-format png --video-bitrate 20M: Default JPEG screenshots at 80% quality add visible compression. - Distinctive: line 75
Pre-upscale source videos with FFmpeg lanczos when needed: If source video is lower resolution than the composition, upscale it before …
- Distinctive: line 89
Always follow this pipeline when producing a final video:
- Very specific: line 108
After every HeyGen video generation, compare audio and video durations.
- Very specific: line 117
Whisper splits words unpredictably: Check caption JSON for split tokens like "hol " + "istically." or "Sc " + "reenshot ".
- Distinctive: line 127
When generating avatar clips with HeyGen for use in Remotion:
- Distinctive: line 143
Read individual rule files for detailed explanations and code examples:
“Common” is measured: kept by at least 6 in 10 of the 146 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
When to use
Use this skill whenever you are dealing with Remotion code to obtain the domain-specific knowledge.
Hard Rules
These rules are non-negotiable. Every composition must follow them. They exist because we've hit these problems in production.
- Use
<Series>for sequential shots. Never compute frame offsets manually with<Sequence>.<Series>handles sequencing correctly and avoids React strict mode issues. - Use
<Video>from@remotion/mediafor video playback. Never use plain HTML<video>tags (they don't sync with Remotion's timeline). Never use<OffthreadVideo>— it works for CLI rendering but fails silently in Studio preview. - Import JSON data at build time. Never use
useDelayRender()+fetch()for data the composition needs. If the fetch hangs, the Studio white-screens with no error. Import JSON files directly:import data from './data.json'. - Spread empty props on Remotion components. Remotion 4.0.431 has a bug where
React.createElement(Component, null)crashes the Studio. Add{...{}}to<Series>,<TransitionSeries>, and any Remotion component that would otherwise have no explicit props. - Always test in the Studio preview, not just CLI render.
npx remotion renderandnpx remotion stilluse different code paths than the Studio. A composition can render fine via CLI but white-screen in the Studio. - Caption timing must come from transcription, not estimation. Never divide duration evenly across words. Always transcribe audio with Whisper (
@remotion/install-whisper-cpp) for word-level timestamps, then use@remotion/captionswithcreateTikTokStyleCaptions()to display them.
Whisper Transcription Workflow
After generating or regenerating audio (ElevenLabs, HeyGen, etc.), transcribe it for word-level caption timing. Never estimate timing manually.
# Transcribe any technique audio (pass number as arg, defaults to 4):
node tools/transcribe.mjs <clip-name>
# For HeyGen talking head clips, extract audio first:
ffmpeg -i public/<slug>/<clip>.mp4 -vn -ar 16000 -ac 1 /tmp/clip.wav
# Then run the transcribe script pointed at the wavThe script uses @remotion/install-whisper-cpp with the medium.en model, extracts word-level tokens, merges punctuation with previous words, and outputs a caption JSON array. Caption format:
{ "text": "word ", "startMs": 100, "endMs": 300, "timestampMs": 100, "confidence": 1 }After transcription, always check for:
- Split words (e.g.
"hol "+"istically.") — merge them manually - Punctuation-only tokens that didn't get merged
- Timestamps that look wrong (first word should start near 0-200ms, not at 0ms exactly)
Captions
When dealing with captions or subtitles, load the ./rules/subtitles.md file for more information.
Using FFmpeg
For some video operations, such as trimming videos or detecting silence, FFmpeg should be used. Load the ./rules/ffmpeg.md file for more information.
Audio visualization
When needing to visualize audio (spectrum bars, waveforms, bass-reactive effects), load the ./rules/audio-visualization.md file for more information.
Sound effects
When needing to use sound effects, load the ./rules/sound-effects.md file for more information.
Render Quality
These rules prevent blurry video output. They exist because we spent hours debugging quality loss.
- Always render with
--image-format png --video-bitrate 20M. Default JPEG screenshots at 80% quality add visible compression. PNG is lossless. 20Mbps prevents h264 from softening the output. - Never embed videos at a resolution lower than the composition. Chromium's CSS upscaling (bilinear interpolation) produces noticeably soft/blurry video compared to the source. A 720p video in a 1080p composition will always look bad.
- Pre-upscale source videos with FFmpeg lanczos when needed. If source video is lower resolution than the composition, upscale it before Remotion sees it:
Lanczos produces significantly sharper upscales than Chromium's bilinear.ffmpeg -i input.mp4 -vf "scale=1080:-2:flags=lanczos" -c:v libx264 -crf 12 -preset slow -c:a copy output.mp4 - Generate HeyGen videos at 4k (2160x3840) for 1080p compositions. Downscaling is free quality. Use
dimension: { width: 2160, height: 3840 }in the v2 API. The v3 API acceptsresolution: "4k". <OffthreadVideo>does NOT improve quality. It extracts frames via FFmpeg as images, which actually upscale worse than the browser's native<Video>element. Stick with<Video>from@remotion/media.- Audio
playbackRateraises pitch — voices sound tinny and unnatural. Remotion's<Audio playbackRate={1.1}>speeds up playback but boosts high frequencies, making voices sound thin and high-pitched. There is no pitch-correction in Remotion. FFmpegatempopreserves pitch but breaks HeyGen lip sync. To get tighter pacing without ruining voice quality, use a playback rate constant (e.g.TECHNIQUE_PLAYBACK_RATE = 1.1) to shorten shotdurationInFramesonly:Math.round((seconds * FPS) / TECHNIQUE_PLAYBACK_RATE). Keep<Audio>and<SyncedCaptions>at 1x so audio plays at natural pitch and captions stay in sync. Align visual animations (terminal line reveals, agent spawn delays) to 1x audio timestamps:frame = audioMs * FPS / 1000.
Render Pipeline
Always follow this pipeline when producing a final video:
- Render at 2x scale for sharp output:
npx remotion render CompositionId --image-format png --video-bitrate 20M --scale 2 - Two-pass loudness normalization to -14 LUFS (LinkedIn/YouTube standard):
# Pass 1: measure ffmpeg -i raw.mp4 -af loudnorm=I=-14:TP=-1:LRA=11:print_format=json -f null - # Pass 2: apply (use measured values from pass 1) ffmpeg -y -i raw.mp4 -af loudnorm=I=-14:TP=-1:LRA=11:measured_I=X:measured_TP=Y:measured_LRA=Z:measured_thresh=W:offset=O:linear=true -c:v copy output.mp4 - Save to vault, not amplify repo. Output to
Stories/{slug}/assets/.
ElevenLabs Audio Speed
- Without HeyGen (terminal visuals, no lip sync): Speed audio to 1.1x with
ffmpeg -filter:a "atempo=1.1"after generation. Adjust caption timestamps by dividing allstartMs/endMs/timestampMsby 1.1. Cut scene durations by 0.5s to match. - With HeyGen (avatar lip sync): Keep audio at 1x. HeyGen lip sync breaks at non-1x speeds.
HeyGen Drift Check
After every HeyGen video generation, compare audio and video durations. If drift > 0.1s, regenerate (up to 3 attempts). Only the v3 API (/v3/videos) should be used — never v2.
const drift = Math.abs(audioDuration - videoDuration);
if (drift > 0.1) { /* regenerate */ }Caption Sync
- Whisper splits words unpredictably. Check caption JSON for split tokens like
"hol "+"istically."or"Sc "+"reenshot ". Merge them manually — each token renders as a separate word in captions. - Synthetic/estimated caption timing drifts. Evenly-spaced timestamps (e.g. 334ms per word) don't match natural speech cadence. Later sentences accumulate error and captions appear before the voice. Always use real Whisper transcription.
- When passing
playbackRatetoSyncedCaptions, it must match the<Audio>playbackRate. If audio plays at 1x, captions must track at 1x. Mismatched rates cause progressive drift. - Visual animations must be timed to audio, not to fixed frame numbers. Convert audio timestamps to frames:
frame = audioMs * FPS / 1000. When audio plays at 1x in a shortened shot, use actual audio timestamps for animation delays.
HeyGen Integration
When generating avatar clips with HeyGen for use in Remotion:
- Always use the v3 API via
createHeyGenClient()fromsrc/studio/heygen.ts. Never use v2 endpoints (/v2/video/generate) — they produce lower quality avatars. Never usev3/video-agents— that adds its own editing, captions, and cuts that conflict with Remotion. - Always generate at 4k (
dimension: { width: 2160, height: 3840 }for vertical). Downscaling to 1080p in Remotion preserves sharpness. Generating at 720p and upscaling produces blurry output. - Use ElevenLabs for voice, not HeyGen TTS. Generate audio with ElevenLabs (your cloned voice), upload to HeyGen as an audio asset, then generate the avatar video with lip sync. This gives better voice quality and your actual voice.
- Do not speed up audio before HeyGen lip sync. HeyGen lip sync fails at non-1x speeds (e.g. 1.1x via FFmpeg atempo). Keep audio at natural speed for HeyGen, and use
TECHNIQUE_PLAYBACK_RATEon shot duration only for pacing. - Add SSML
<break>at the end of scripts to prevent abrupt cutoffs:"Your script text. <break time=\"1.5s\"/>" - After generating, always: extract audio → transcribe with Whisper → import captions JSON at build time → merge any split tokens → display with synced captions.
How to use
Read individual rule files for detailed explanations and code examples:
- rules/3d.md - 3D content in Remotion using Three.js and React Three Fiber
- rules/animations.md - Fundamental animation skills for Remotion
- rules/assets.md - Importing images, videos, audio, and fonts into Remotion
- rules/audio.md - Using audio and sound in Remotion - importing, trimming, volume, speed, pitch
- rules/calculate-metadata.md - Dynamically set composition duration, dimensions, and props
- rules/can-decode.md - Check if a video can be decoded by the browser using Mediabunny
- rules/charts.md - Chart and data visualization patterns for Remotion (bar, pie, line, stock charts)
- rules/compositions.md - Defining compositions, stills, folders, default props and dynamic metadata
- rules/extract-frames.md - Extract frames from videos at specific timestamps using Mediabunny
- rules/fonts.md - Loading Google Fonts and local fonts in Remotion
- rules/get-audio-duration.md - Getting the duration of an audio file in seconds with Mediabunny
- rules/get-video-dimensions.md - Getting the width and height of a video file with Mediabunny
- rules/get-video-duration.md - Getting the duration of a video file in seconds with Mediabunny
- rules/gifs.md - Displaying GIFs synchronized with Remotion's timeline
- rules/images.md - Embedding images in Remotion using the Img component
- rules/light-leaks.md - Light leak overlay effects using @remotion/light-leaks
- rules/lottie.md - Embedding Lottie animations in Remotion
- rules/measuring-dom-nodes.md - Measuring DOM element dimensions in Remotion
- rules/measuring-text.md - Measuring text dimensions, fitting text to containers, and checking overflow
- rules/sequencing.md - Sequencing patterns for Remotion - delay, trim, limit duration of items
- rules/tailwind.md - Using TailwindCSS in Remotion
- rules/text-animations.md - Typography and text animation patterns for Remotion
- rules/timing.md - Interpolation curves in Remotion - linear, easing, spring animations
- rules/transitions.md - Scene transition patterns for Remotion
- rules/transparent-videos.md - Rendering out a video with transparency
- rules/trimming.md - Trimming patterns for Remotion - cut the beginning or end of animations
- rules/videos.md - Embedding videos in Remotion - trimming, volume, speed, looping, pitch
- rules/parameters.md - Make a video parametrizable by adding a Zod schema
- rules/maps.md - Add a map using Mapbox and animate it
- rules/voiceover.md - Adding AI-generated voiceover to Remotion compositions using ElevenLabs TTS
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

