interpolate(). Bouncy/physical feel → spring(). Never hand-roll animation with setState or CSS transitions inside a composition.<OffthreadVideo>, not <Video>/HTML5 <video> — frame extraction accuracy matters once you're capturing frames server-side, not just playing back interactively.public/ folder, use staticFile(). Never hardcode a relative path.calculateMetadata() on <Composition> instead of hardcoding durationInFrames/width/height.delayRender() + continueRender(). Skip it entirely for anything that only affects the Studio/Player preview, since it's a no-op there anyway.<Sequence> for explicit offsets, <Series> when scenes just play back-to-back.| Option | Control | Scalability | Best for |
|---|---|---|---|
renderMedia() (self-hosted) | Highest (full machine control) | Manual (you scale it) | Custom codecs/GPU, on-prem constraints |
Lambda (@remotion/lambda) | Managed | Highest, official fastest option | Production rendering at scale on AWS |
Cloud Run (@remotion/cloudrun) | Managed | High | Teams already on Google Cloud |
| Studio / Player | None (preview only) | N/A — not a render | Local dev feedback loop, embedding interactive preview |
@remotion/player's <Player>.renderMedia() locally, or Lambda/Cloud Run in the cloud).useCurrentFrame() — no Date.now(), no setInterval, no external mutable state.delayRender()/continueRender(), not assumed to "just be ready."staticFile(), not ad-hoc paths.<OffthreadVideo> for anything that will actually be rendered, not just previewed.@remotion/transitions@remotion/sfx@remotion/captions (+ @remotion/whisper-web or ElevenLabs integration to generate them)@remotion/shapes, path helpers → @remotion/paths@remotion/media-parser@remotion/webcodecs@remotion/lottie / @remotion/rive@remotion/recorder