| name | remotion |
| description | Expert guidance for Remotion video creation in React. Use when creating videos programmatically, setting up Remotion projects, building video components, rendering videos, or working with Remotion Studio/Player. |
What is Remotion?
Remotion is a framework for creating videos programmatically using React. It allows you to leverage React's component model, composition, and ecosystem to create sophisticated videos with code.
When to Use Remotion
- Creating dynamic, data-driven videos
- Generating personalized videos at scale
- Building video templates with code
- Automating video production workflows
- Creating marketing videos programmatically
- Building video-based applications
- Generating year-in-review or personalized content
Key Concepts
- Compositions: React components that define video content
- Frames: Individual images that make up the video (0 to durationInFrames - 1)
- Video properties: width, height, durationInFrames, fps
- React hooks: useCurrentFrame(), useVideoConfig(), etc.
- Rendering: Converting compositions to video files (MP4, GIF, etc.)
Installation and Setup
Creating a New Remotion Project
npm create video@latest my-video
cd my-video
npm install
npm start
Adding Remotion to Existing React Project
npm install remotion
npm install @remotion/cli
Basic Project Structure
my-video/
├── src/
│ ├── Root.tsx # Register compositions
│ ├── Composition.tsx # Video components
│ └── ...
├── package.json
├── remotion.config.ts # Configuration
└── public/ # Static assets
Core Concepts
React Components in Remotion
Remotion gives you a frame number and a blank canvas to render anything using React:
import { AbsoluteFill, useCurrentFrame } from "remotion";
export const MyComposition = () => {
const frame = useCurrentFrame();
return (
<AbsoluteFill style={{
justifyContent: "center",
alignItems: "center",
fontSize: 100,
backgroundColor: "white"
}}>
The current frame is {frame}.
</AbsoluteFill>
);
};
Video Properties
A video has 4 properties:
- width: Width in pixels
- height: Height in pixels
- durationInFrames: Total number of frames
- fps: Framerate
import { AbsoluteFill, useVideoConfig } from 'remotion';
export const MyComposition = () => {
const { fps, durationInFrames, width, height } = useVideoConfig();
return (
<AbsoluteFill style={{
justifyContent: 'center',
alignItems: 'center',
fontSize: 60,
backgroundColor: 'white'
}}>
This {width}x{height}px video is {durationInFrames / fps} seconds long.
</AbsoluteFill>
);
};
Compositions
A composition is a React component combined with video metadata:
import { Composition } from "remotion";
import { MyVideo } from "./MyVideo";
export const RemotionRoot: React.FC = () => {
return (
<>
<Composition
id="MyVideo"
component={MyVideo}
durationInFrames={150}
fps={30}
width={1920}
height={1080}
/>
</>
);
};
Common Hooks
useCurrentFrame()
Returns the current frame number (0-indexed):
const frame = useCurrentFrame();
useVideoConfig()
Returns video configuration:
const { width, height, fps, durationInFrames } = useVideoConfig();
useCurrentFrameInVideo()
Returns the current frame across all sequences:
const frame = useCurrentFrameInVideo();
interpolate()
Interpolate values between frames:
import { interpolate, useCurrentFrame } from "remotion";
const frame = useCurrentFrame();
const opacity = interpolate(frame, [0, 30], [0, 1]);
spring()
Spring animations:
import { spring, useCurrentFrame } from "remotion";
const frame = useCurrentFrame();
const scale = spring({
frame,
fps: 30,
config: { damping: 10, mass: 1, stiffness: 100 },
});
Audio
import { Audio, useCurrentFrame } from "remotion";
<Audio src="music.mp3" />
Animation Techniques
Basic Animation
import { AbsoluteFill, useCurrentFrame, interpolate } from "remotion";
export const AnimatedText = () => {
const frame = useCurrentFrame();
const opacity = interpolate(frame, [0, 30], [0, 1]);
const x = interpolate(frame, [0, 150], [0, 500]);
return (
<AbsoluteFill style={{ backgroundColor: "white" }}>
<div style={{
opacity,
transform: `translateX(${x}px)`,
fontSize: 60
}}>
Animated Text
</div>
</AbsoluteFill>
);
};
Sequence
Play content for a specific duration:
import { Sequence, useCurrentFrame } from "remotion";
export const SequencedContent = () => {
return (
<AbsoluteFill style={{ backgroundColor: "white" }}>
<Sequence from={0} durationInFrames={60}>
<div>First part (0-60)</div>
</Sequence>
<Sequence from={60} durationInFrames={60}>
<div>Second part (60-120)</div>
</Sequence>
</AbsoluteFill>
);
};
Loop
Repeat content:
import { Loop, useCurrentFrame } from "remotion";
export const LoopedContent = () => {
return (
<Loop durationInFrames={30}>
<div>Loops every 30 frames</div>
</Loop>
);
};
Spring Animations
import { spring, useCurrentFrame } from "remotion";
export const SpringAnimation = () => {
const frame = useCurrentFrame();
const scale = spring({
frame,
fps: 30,
from: 0,
to: 1,
config: { damping: 10, mass: 1, stiffness: 100 },
});
return (
<div style={{ transform: `scale(${scale})` }}>
Spring Animated
</div>
);
};
Working with Assets
Images
import { Img } from "remotion";
<Img src="image.png" />
Videos
import { Video } from "remotion";
<Video src="background.mp4" />
Audio
import { Audio } from "remotion";
<Audio src="music.mp3" />
Offthreading
Offload heavy computations:
import { OffthreadVideo } from "remotion";
<OffthreadVideo src="heavy-video.mp4" />
Data-Driven Videos
Passing Props to Compositions
<Composition
id="MyVideo"
component={MyVideo}
durationInFrames={150}
fps={30}
width={1920}
height={1080}
props={{ title: "Hello World", color: "blue" }}
/>
type Props = {
title: string;
color: string;
};
export const MyVideo: React.FC<Props> = ({ title, color }) => {
return (
<AbsoluteFill style={{ backgroundColor: color }}>
<h1>{title}</h1>
</AbsoluteFill>
);
};
Dynamic Data from API
import { useEffect, useState } from "react";
import { AbsoluteFill } from "remotion";
export const DataDrivenVideo = () => {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://api.example.com/data')
.then(res => res.json())
.then(setData);
}, []);
if (!data) return null;
return (
<AbsoluteFill>
<h1>{data.title}</h1>
</AbsoluteFill>
);
};
Rendering Videos
Using Remotion CLI
npx remotion render src/Root.tsx MyVideo out/video.mp4
npx remotion render src/Root.tsx MyVideo out/video.mp4 --codec=h264 --crf=18
npx remotion render src/Root.tsx MyVideo out/video.gif --format=gif
Using Remotion Studio
npm start
Opens Remotion Studio for previewing and editing.
Configuration (remotion.config.ts)
import { Config } from "@remotion/cli/config";
const config: Config = {
outDir: "out",
codec: "h264",
crf: 18,
pixelFormat: "yuv420p",
};
export default config;
Best Practices
Performance
- Use
OffthreadVideo for heavy video assets
- Preload assets when possible
- Use
Sequence to avoid rendering unnecessary frames
- Optimize images and videos before use
- Use appropriate resolution (not always 4K)
Code Organization
- Keep compositions focused and reusable
- Extract common UI components
- Use TypeScript for type safety
- Organize by feature or video type
- Use consistent naming conventions
Animation
- Use spring animations for natural motion
- Use interpolate for linear transitions
- Avoid too many simultaneous animations
- Test at different framerates
- Consider performance impact of complex animations
Asset Management
- Optimize images (WebP, appropriate sizes)
- Use compressed audio
- Consider using CDNs for assets
- Keep assets in public/ directory
- Use relative paths
Common Gotchas
Frame Counting
- First frame is 0, last is durationInFrames - 1
- Be careful with off-by-one errors
- Use
useCurrentFrameInVideo() for sequences
Performance Issues
- Large videos can cause memory issues
- Too many simultaneous animations slow rendering
- High resolution increases render time significantly
- Use
OffthreadVideo for background videos
Audio Sync
- Audio starts at frame 0 by default
- Use
Audio component for background music
- Use
Sequence to time audio with visuals
- Be aware of audio/video sync at different framerates
TypeScript
- Always type your component props
- Use Remotion's built-in types
- Type your configuration
- Use strict mode for better safety
Integration with Other Tools
With Figma
- Export assets from Figma
- Use Figma designs as reference
- Import Figma components to React
With Data Sources
- Fetch data from APIs
- Use real-time data for live videos
- Connect to databases for dynamic content
With CI/CD
- Automate video rendering in pipelines
- Use GitHub Actions for automated generation
- Deploy videos to CDNs automatically
When to Use Alternatives
Consider alternatives when:
- You need simple video editing (use traditional editors)
- You need real-time video processing (use FFmpeg directly)
- You need complex video effects (use After Effects)
- Performance is critical and video is very complex
Keep Remotion when:
- You need programmatic video generation
- You want to leverage React ecosystem
- You need data-driven videos
- You want to automate video production