| name | video-generation |
| description | Create videos programmatically using Remotion (React + TypeScript). Use when the user wants to generate videos from code, create animated presentations, motion graphics, social media clips, data visualization videos, or mentions Remotion, programmatic video, or 'video from code'. Also trigger for animated explainers, promotional videos, or any task where video is the output format and code-based generation is appropriate. |
Video Generation with Remotion
Remotion renders React components as video frames -- write React, get MP4. Every frame is a function of the current time, giving precise control over every pixel at every moment.
Setup
npx create-video@latest my-video
cd my-video
npm start
Core Concepts
Composition (Video Definition)
import { Composition } from 'remotion';
export const RemotionRoot: React.FC = () => {
return (
<Composition
id="MyVideo"
component={MyVideo}
durationInFrames={300} // 10 seconds at 30fps
fps={30}
width={1920}
height={1080}
/>
);
};
useCurrentFrame & useVideoConfig
import { useCurrentFrame, useVideoConfig } from 'remotion';
const MyVideo: React.FC = () => {
const frame = useCurrentFrame();
const { fps, width, height, durationInFrames } = useVideoConfig();
const progress = frame / durationInFrames;
return (
<div style={{ opacity: progress }}>
Frame {frame} of {durationInFrames}
</div>
);
};
Sequences (Timing Sections)
import { Sequence } from 'remotion';
const MyVideo: React.FC = () => {
return (
<>
<Sequence from={0} durationInFrames={90}>
<TitleSlide />
</Sequence>
<Sequence from={90} durationInFrames={120}>
<ContentSlide />
</Sequence>
<Sequence from={210} durationInFrames={90}>
<OutroSlide />
</Sequence>
</>
);
};
Animation
interpolate (Linear Mapping)
import { interpolate, useCurrentFrame } from 'remotion';
const MyComponent: React.FC = () => {
const frame = useCurrentFrame();
const opacity = interpolate(frame, [0, 30], [0, 1], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
});
const translateX = interpolate(frame, [0, 30], [-100, 0], {
extrapolateRight: 'clamp',
});
return (
<div style={{ opacity, transform: `translateX(${translateX}%)` }}>
Hello
</div>
);
};
spring (Physics-Based)
import { spring, useCurrentFrame, useVideoConfig } from 'remotion';
const MyComponent: React.FC = () => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const scale = spring({
frame,
fps,
config: {
damping: 10,
stiffness: 100,
mass: 1,
},
});
return <div style={{ transform: `scale(${scale})` }}>Bounce!</div>;
};
Easing Functions
import { interpolate, Easing } from 'remotion';
const value = interpolate(frame, [0, 60], [0, 1], {
easing: Easing.bezier(0.25, 0.1, 0.25, 1),
});
Media
import { Img, Video, Audio, OffthreadVideo, staticFile } from 'remotion';
<Img src={staticFile('logo.png')} style={{ width: 200 }} />
<OffthreadVideo src={staticFile('background.mp4')} />
<Audio src={staticFile('music.mp3')} volume={0.5} />
<Img src="https://example.com/image.jpg" />
Common Patterns
Slide Show
const slides = ['Intro', 'Problem', 'Solution', 'CTA'];
const framesPerSlide = 90;
const SlideShow: React.FC = () => {
return (
<>
{slides.map((text, i) => (
<Sequence key={i} from={i * framesPerSlide} durationInFrames={framesPerSlide}>
<Slide text={text} />
</Sequence>
))}
</>
);
};
Data-Driven Charts
const AnimatedBar: React.FC<{ value: number; delay: number }> = ({ value, delay }) => {
const frame = useCurrentFrame();
const height = interpolate(frame - delay, [0, 30], [0, value], {
extrapolateLeft: 'clamp',
extrapolateRight: 'clamp',
});
return <div style={{ height: `${height}%`, width: 40, background: '#3B82F6' }} />;
};
Text Reveal (Character by Character)
const TextReveal: React.FC<{ text: string }> = ({ text }) => {
const frame = useCurrentFrame();
const charsToShow = Math.floor(interpolate(frame, [0, 60], [0, text.length], {
extrapolateRight: 'clamp',
}));
return <span>{text.slice(0, charsToShow)}</span>;
};
Rendering
npx remotion render MyVideo out/video.mp4
npx remotion render MyVideo out/video.mp4 --frames=0-90
npx remotion render MyVideo out/video.webm --codec=vp8
npx remotion render MyVideo out/video.mov --codec=prores
npx remotion render MyVideo out/animation.gif
npx remotion render MyVideo out/video.mp4 --scale=0.5
npx remotion preview
Performance Tips
- Use
React.memo() on components that don't change every frame
- Use
staticFile() for assets in the public/ folder (optimized loading)
- Use
OffthreadVideo instead of Video for background videos
- Use
prefetch() for remote assets to avoid loading delays
- Keep expensive calculations outside the render function
- Use
delayRender() / continueRender() for async data loading