remotion-video-toolkit
Programmatic video creation with React using Remotion. Use when a user asks to create videos with code, generate personalized videos, build animated data visualizations, add TikTok-style captions, render video programmatically, or automate video production. Supports CLI rendering, AWS Lambda, and Google Cloud Run deployment.
Usage
Getting Started
- Install the skill using the command above
- Open your AI coding agent (Claude Code, Codex, Gemini CLI, or Cursor)
- Reference the skill in your prompt
- The AI will use the skill's capabilities automatically
Example Prompts
- "Process all PDFs in the uploads folder and extract invoice data"
- "Set up a workflow that converts uploaded spreadsheets to formatted reports"
Documentation
Overview
Create videos programmatically using React and Remotion. Build reusable video templates as React components, render them to MP4/WebM via CLI or cloud infrastructure, and generate personalized videos at scale. Ideal for automated social media content, animated data visualizations, and dynamic video production pipelines.
Instructions
When a user asks to create programmatic video, determine the task:
Task A: Set up a Remotion project
# Create a new Remotion project
npx create-video@latest my-video
cd my-video
npm start # Opens the Remotion Studio at http://localhost:3000
Project structure:
my-video/
src/
Root.tsx # Register all compositions
MyComposition.tsx # Your video component
remotion.config.ts # Render settings
Task B: Create a video composition
Every Remotion video is a React component that uses useCurrentFrame() and useVideoConfig():
import { AbsoluteFill, useCurrentFrame, useVideoConfig, interpolate, spring } from "remotion";
interface MyVideoProps {
title: string;
subtitle: string;
bgColor: string;
}
export const MyVideo: React.FC<MyVideoProps> = ({ title, subtitle, bgColor }) => {
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
// Animate title sliding in
const titleY = spring({ frame, fps, from: -100, to: 0, durationInFrames: 30 });
// Fade in subtitle after 20 frames
const subtitleOpacity = interpolate(frame, [20, 40], [0, 1], {
extrapolateRight: "clamp",
});
return (
<AbsoluteFill style={{ backgroundColor: bgColor, justifyContent: "center", alignItems: "center" }}>
<h1 style={{ fontSize: 80, color: "white", transform: `translateY(${titleY}px)` }}>
{title}
</h1>
<p style={{ fontSize: 36, color: "rgba(255,255,255,0.8)", opacity: subtitleOpacity }}>
{subtitle}
</p>
</AbsoluteFill>
);
};
Register the composition in Root.tsx:
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}
defaultProps={{ title: "Hello World", subtitle: "Made with Remotion", bgColor: "#1a1a2e" }}
/>
);
};
Task C: Add TikTok-style animated captions
import { AbsoluteFill, useCurrentFrame, Sequence } from "remotion";
interface CaptionWord {
text: string;
startFrame: number;
durationInFrames: number;
}
const captions: CaptionWord[] = [
{ text: "This", startFrame: 0, durationInFrames: 15 },
{ text: "is", startFrame: 15, durationInFrames: 10 },
{ text: "amazing!", startFrame: 25, durationInFrames: 20 },
];
export const CaptionOverlay: React.FC = () => {
const frame = useCurrentFrame();
const activeWord = captions.find(
(c) => frame >= c.startFrame && frame < c.startFrame + c.durationInFrames
);
return (
<AbsoluteFill style={{ justifyContent: "flex-end", alignItems: "center", paddingBottom: 120 }}>
{activeWord && (
<div style={{
fontSize: 64,
fontWeight: "bold",
color: "white",
textShadow: "2px 2px 8px rgba(0,0,0,0.8)",
backgroundColor: "rgba(0,0,0,0.5)",
padding: "8px 24px",
borderRadius: 12,
}}>
{activeWord.text}
</div>
)}
</AbsoluteFill>
);
};
Task D: Render videos
# Render locally via CLI
npx remotion render MyVideo out/video.mp4
# Render with custom props
npx remotion render MyVideo out/video.mp4 --props='{"title":"Custom Title"}'
# Render a still frame (for thumbnails)
npx remotion still MyVideo out/thumbnail.png --frame=45
# Render with specific codec and quality
npx remotion render MyVideo out/video.mp4 --codec=h264 --crf=18
For batch rendering at scale:
# Render on AWS Lambda
npx remotion lambda render MyVideo --props='{"title":"Video 1"}'
# Render on Google Cloud Run
npx remotion cloudrun render MyVideo --props='{"title":"Video 1"}'
Task E: Animated data visualizations
import { AbsoluteFill, useCurrentFrame, interpolate } from "remotion";
interface DataPoint { label: string; value: number; color: string; }
export const BarChart: React.FC<{ data: DataPoint[] }> = ({ data }) => {
const frame = useCurrentFrame();
const maxVal = Math.max(...data.map((d) => d.value));
return (
<AbsoluteFill style={{ padding: 80, justifyContent: "flex-end", backgroundColor: "#0f0f23" }}>
<div style={{ display: "flex", alignItems: "flex-end", gap: 20, height: "70%" }}>
{data.map((point, i) => {
const height = interpolate(frame, [i * 10, i * 10 + 30], [0, (point.value / maxVal) * 100], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
return (
<div key={i} style={{ flex: 1, textAlign: "center" }}>
<div style={{
height: `${height}%`,
backgroundColor: point.color,
borderRadius: "8px 8px 0 0",
transition: "height 0.3s",
}} />
<p style={{ color: "white", marginTop: 12, fontSize: 24 }}>{point.label}</p>
</div>
);
})}
</div>
</AbsoluteFill>
);
};
Examples
Example 1: Personalized welcome video
User request: "Generate a welcome video for each new user with their name"
# Generate videos from a JSON list of users
for user in $(jq -r '.[] | @base64' users.json); do
name=$(echo "$user" | base64 -d | jq -r '.name')
npx remotion render WelcomeVideo "out/welcome_${name}.mp4" \
--props="{\"userName\":\"${name}\"}"
done
Example 2: Animated sales dashboard
User request: "Create a video showing our quarterly metrics animating in"
Build a composition using the BarChart component with quarterly data, render with:
npx remotion render SalesDashboard out/q4_report.mp4 \
--props='{"quarter":"Q4","revenue":1250000,"growth":12.5}'
Example 3: Social media content with captions
User request: "Add animated captions to a video for TikTok"
Combine the CaptionOverlay with an OffthreadVideo source:
import { OffthreadVideo } from "remotion";
<AbsoluteFill>
<OffthreadVideo src="https://example.com/clip.mp4" />
<CaptionOverlay />
</AbsoluteFill>
Guidelines
- Use
useCurrentFrame()andinterpolate()for all animations; avoid CSS transitions. - Keep compositions pure: pass all dynamic data as props for easy batch rendering.
- Use
<Sequence>to organize sections of your video timeline. - Prefer
<OffthreadVideo>over<Video>for better performance with video sources. - Set
crf(Constant Rate Factor) between 16-20 for good quality-to-size ratio. - For Lambda rendering, keep compositions under 120 seconds to avoid timeout issues.
- Test in Remotion Studio before rendering to catch layout issues early.
- Use
staticFile()to reference assets in thepublic/folder.
Information
- Version
- 1.0.0
- Author
- terminal-skills
- Category
- Automation
- License
- Apache-2.0