Remotion Video Fundamentals
Remotion allows you to create videos programmatically using React. Unlike traditional video editing, Remotion treats video as a function of state and time, where every frame is rendered based on the current frame index.
Defining Compositions
The <Composition> is the entry point for any Remotion project. It defines the metadata and the React component that will be rendered.
import { Composition } from "remotion";
import { MyVideoComponent } from "./MyVideoComponent";
export const RemotionRoot = () => {
return (
<Composition
id="MainVideo"
component={MyVideoComponent}
durationInFrames={150} // 5 seconds at 30fps
fps={30}
width={1920}
height={1080}
defaultProps={{
title: "Welcome to Agent Board",
}}
/>
);
};
Key Metadata Fields
id: A unique identifier for the composition, used during rendering and in the Studio sidebar.durationInFrames: The total length of the video.fps: Frames per second. High values result in smoother motion but longer render times.width/height: The resolution of the output video.defaultProps: Initial data passed to your component. Must be JSON-serializable.
Handling Assets
Assets (images, videos, audio, fonts) should be placed in the public/ folder at the root of your project. To reference them safely across different environments, use the staticFile() helper.
import { Img, staticFile } from 'remotion';
export const Logo = () => {
return <Img src={staticFile('logo.png')} alt="Logo" />;
};
Note: Always use Remotion-specific tags like <Img>, <Video>, and <Audio> to ensure assets are fully pre-loaded before a frame is captured.
The Timeline and Hooks
Animations in Remotion are driven by the frame count. Two primary hooks provide the necessary context:
useCurrentFrame(): Returns the index of the frame currently being rendered (starting at 0).useVideoConfig(): Returns the composition's metadata (width,height,fps,durationInFrames).
Animation Rules
- Prohibited: CSS Transitions, CSS Keyframes, and Tailwind animation classes. These do not work because Remotion captures static snapshots of the DOM at specific frames.
- Required: Animations must be calculated values based on the current frame.
Interpolation and Spring Physics
Remotion provides utility functions to map the timeline to visual properties.
Linear Interpolation
Use interpolate to map a frame range to a value range (e.g., opacity, position).
import { interpolate, useCurrentFrame } from "remotion";
const frame = useCurrentFrame();
const opacity = interpolate(frame, [0, 30], [0, 1], {
extrapolateRight: 'clamp',
});
return <div style={{ opacity }}>Fading In</div>;
Spring Animations
Use spring for natural, physics-based motion.
import { spring, useCurrentFrame, useVideoConfig } from "remotion";
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const scale = spring({
frame,
fps,
config: {
stiffness: 100,
},
});
return <div style={{ transform: `scale(${scale})` }}>Bouncy Element</div>;
Media Elements
For video and audio, use the @remotion/media package. These components allow for precise control over trimming and volume curves.
import { Video, Audio } from "@remotion/media";
import { staticFile } from "remotion";
export const MediaLayer = () => {
return (
<>
<Video
src={staticFile("background.mp4")}
startFrom={30} // Start 1s into the source file
volume={0.8}
/>
<Audio
src={staticFile("music.mp3")}
placeholder={null}
/>
</>
);
};
Dynamic Metadata
If the duration or dimensions of your video depend on external data (like an API response or the length of a video file), use calculateMetadata.
const calculateMetadata = async ({ props }) => {
const data = await fetch(`https://api.example.com/metadata/${props.id}`)
.then(res => res.json());
return {
durationInFrames: Math.ceil(data.durationSeconds * 30),
props: {
...props,
videoUrl: data.url,
},
};
};
<Composition
id="DynamicComp"
component={MyComponent}
calculateMetadata={calculateMetadata}
// Default values acts as placeholders
durationInFrames={1}
fps={30}
width={1920}
height={1080}
/>
3D Content
When using Three.js or React Three Fiber, you must wrap your content in the <ThreeCanvas> component from @remotion/three.
- Animations: Do not use
useFrame()from R3F. UseuseCurrentFrame()to update object rotations, positions, or shader uniforms manually. - Sequencing: If using
<Sequence>inside<ThreeCanvas>, always setlayout="none".