Remotion renders React components to MP4 by driving a headless Chrome, one time value at a time, capturing each frame. That model is what makes it deterministic and hash-reproducible — and also what draws its ceiling. Below are the seven walls it can't scale, each one demonstrated live in this page.
useCurrentFrame(). There is no now.A Remotion composition is a pure function (frame) → pixels. Any input that isn't part of the timeline — the user's camera, a websocket, a keypress, a mic — is invisible to it. The renderer sees only frame. That's the whole surface.
getUserMedia during render.Because rendering can be parallelized across workers, no useRef survives between frames on different processes. Simulations with feedback (fluids, boids, cloth) are impossible — you'd need a closed-form solution or accept a serial pipeline. Below, the left panel is closed-form (Remotion-friendly), the right is Verlet integration (needs previous-frame state).
Once encoded, the artifact is bytes. Interactive video (branching, scrubbable overlays, tooltips) needs an app, not an MP4. Remotion's <Player> component gives you playback, but not per-frame interaction.
Remotion drives a headless Chromium via @remotion/renderer. That means every render environment needs a working Chrome install, node_modules, and enough memory for 1080p frames. Serverless works — with cold starts and image bloat. Below: pure browser <canvas> + MediaRecorder renders to an actual video file with zero server.
// Node.js + Chrome install required import { renderMedia, selectComposition } from '@remotion/renderer'; const composition = await selectComposition({ serveUrl: './out', id: 'MyVideo', inputProps }); await renderMedia({ composition, serveUrl, codec: 'h264', outputLocation: './out.mp4' });
Every frame, Remotion re-renders the entire React tree. For scenes with hundreds of DOM/SVG nodes at 60fps, the reconciler cost eats the render window before the encoder does. Canvas escape-hatches exist — but you're no longer using React. Below: 5,000 particles under React (imaginary) vs. straight drawImage loop.
You pick fps: 30 or 60 and every frame is captured at that rate. Real cameras integrate light over shutter time — that's what makes moving objects look smooth. Remotion has to fake motion blur (compositing multiple sub-frames), which multiplies render cost. Below is a genuine per-sample accumulation you couldn't cheaply do in Remotion.
<Freeze> + averaged sub-frames — expensive.Remotion encodes video first, then remixes audio during muxing. Reactive audio (Web Audio API graphs, live filters, feedback loops, mic input) can't participate in the render — you can only supply <Audio src="…" /> and pray your offsets match your visual keyframes. Below: a real-time FFT visualizer that's inherently reactive.
None of these limits are bugs — they're the price of the guarantee. Remotion trades interactivity for reproducibility: the same code + same inputs = the exact same MP4 forever. That's a superpower for data-driven videos, marketing pipelines, weekly recaps, or anything you'll re-render as data changes. Web-native canvas trades the guarantee for immediacy: everything the browser can do, in the browser, live.