Learn-skills.dev remotion
Use when generating or modifying Remotion video code, creating demo videos, or working with the demo-video/ directory
install
source · Clone the upstream repo
git clone https://github.com/NeverSight/learn-skills.dev
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/NeverSight/learn-skills.dev "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/skills-md/0xaxiom/appfactory/remotion" ~/.claude/skills/neversight-learn-skills-dev-remotion && rm -rf "$T"
manifest:
data/skills-md/0xaxiom/appfactory/remotion/SKILL.mdsource content
Remotion Video Generation Skills
App Factory includes an integrated Remotion video pipeline for generating demo videos of built applications.
When This Skill Applies
- Working with files in
directorydemo-video/ - Running
command/factory video - Creating or modifying Remotion compositions
- Debugging video rendering issues
- Understanding frame-based animations
Project Structure
demo-video/ ├── src/ │ ├── index.ts # Remotion entry point │ ├── Root.tsx # Composition registry │ ├── compositions/ │ │ └── AppFactoryDemo.tsx # Main demo video (10s, 1920x1080) │ └── components/ │ ├── Title.tsx # Animated title │ ├── BulletPoints.tsx # Staggered highlights │ ├── VerificationBadge.tsx # PASS badge │ └── Footer.tsx # UTC timestamp ├── remotion.config.ts # Remotion configuration └── package.json # Dependencies (Remotion v4.x)
Critical Rules (MUST FOLLOW)
1. Frame-Based Animations ONLY
// CORRECT: Use useCurrentFrame() for all animations const frame = useCurrentFrame(); const opacity = interpolate(frame, [0, 30], [0, 1], { extrapolateRight: 'clamp', }); // FORBIDDEN: CSS animations/transitions // Never use: animation:, transition:, @keyframes
2. Interpolate with Clamping
// ALWAYS use extrapolation clamping const value = interpolate(frame, [0, 60], [0, 100], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', });
3. Spring Animations
// Use spring() for physics-based animations const springValue = spring({ fps, frame, config: { damping: 200, stiffness: 100 }, durationInFrames: 40, });
4. Determinism Requirements
- Timestamps MUST be input props, never
new Date() - Use
for all date formattingtimeZone: 'UTC' - No
or non-deterministic valuesMath.random() - Same props must produce identical video output
5. Component Structure
// All compositions must follow this pattern export const MyComposition: React.FC<Props> = (props) => { const frame = useCurrentFrame(); const { fps, width, height, durationInFrames } = useVideoConfig(); return ( <AbsoluteFill style={{ backgroundColor: '#000' }}> {/* Sequenced content */} <Sequence from={0} durationInFrames={60}> <Scene1 /> </Sequence> <Sequence from={60} durationInFrames={60}> <Scene2 /> </Sequence> </AbsoluteFill> ); };
Pipeline Integration
Auto-Generation Flow
- Local Run Proof verification runs
created withRUN_CERTIFICATE.jsonstatus: "PASS"- Hook triggers
post-run-certificate-video.mjs - Demo video rendered to
demo/out/<slug>.mp4
Manual Rendering
# Basic usage node scripts/render-demo-video.mjs --cwd ./my-app --slug my-app # With custom highlights node scripts/render-demo-video.mjs \ --cwd ./my-app \ --slug my-app \ --title "My Amazing App" \ --highlights '["Feature 1", "Feature 2", "Feature 3"]'
Props Schema
interface AppFactoryDemoProps { title: string; // App name slug: string; // URL-safe identifier verifiedUrl: string; // Localhost URL that passed health check timestamp: string; // ISO 8601 timestamp (UTC) highlights: string[]; // 4-6 bullet points certificateHash: string; // SHA256 of RUN_CERTIFICATE.json }
Debugging
# Preview in Remotion Studio cd demo-video && npm run studio # Render specific composition npx remotion render src/index.ts AppFactoryDemo output.mp4 # Check for TypeScript errors npx tsc --noEmit
Common Patterns
Fade In/Out
const fadeIn = interpolate(frame, [0, 30], [0, 1], { extrapolateRight: 'clamp', }); const fadeOut = interpolate(frame, [duration - 30, duration], [1, 0], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', }); const opacity = fadeIn * fadeOut;
Staggered Animation
items.map((item, index) => { const delay = index * 10; // 10 frames between each const itemOpacity = interpolate( frame, [delay, delay + 20], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } ); return <Item key={index} style={{ opacity: itemOpacity }} />; });
Scale with Spring
const scaleSpring = spring({ fps, frame: frame - startFrame, config: { damping: 80, stiffness: 200 }, }); const scale = interpolate(scaleSpring, [0, 1], [0.8, 1]);
Error Codes
| Code | Meaning | Resolution |
|---|---|---|
| FAC-006 | Video render failed | Check Remotion logs, verify ffmpeg installed |
| FAC-007 | Certificate missing | Run Local Run Proof first |
| FAC-008 | Props validation failed | Check prop types match schema |