
Remotion
Look up Remotion React APIs while coding programmatic video scenes, keyframe motion, and spring animations in a solo builder's video toolkit.
Install
npx skills add https://github.com/digitalsamba/claude-code-video-toolkit --skill remotionWhat is this skill?
- Documents useCurrentFrame and useVideoConfig for frame-accurate React video scenes
- Covers interpolate() with input/output ranges, clamping, multi-keyframes, and Easing.bezier
- Documents spring() with damping, mass, stiffness, delay, and bounce presets
- Part of the Claude Code video toolkit for programmatic video with Remotion
Adoption & trust: 555 installs on skills.sh; 1.4k GitHub stars; 3/3 security scanners passed (skills.sh audits).
Recommended Skills
Video Editagentspace-so/runcomfy-agent-skills
Image To Videoagentspace-so/runcomfy-agent-skills
Image Editagentspace-so/runcomfy-agent-skills
Flux Kontextagentspace-so/runcomfy-agent-skills
Nano Banana 2agentspace-so/runcomfy-agent-skills
Nano Banana Editagentspace-so/runcomfy-agent-skills
Journey fit
Primary fit
Canonical shelf is Build because the skill is a hands-on API reference for implementing Remotion compositions and motion logic in code. Frontend fits React/TSX hooks, interpolate, and spring usage inside video components rather than backend or ops work.
Common Questions / FAQ
Is Remotion safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Remotion
# Remotion API Reference ## Core Hooks ### useCurrentFrame() ```tsx const frame = useCurrentFrame(); ``` Returns current frame (0-indexed). Inside `<Sequence>`, returns relative frame. ### useVideoConfig() ```tsx const { width, height, fps, durationInFrames, id, defaultProps } = useVideoConfig(); ``` ## interpolate() ```tsx interpolate( input: number, inputRange: number[], outputRange: number[], options?: { extrapolateLeft?: 'extend' | 'clamp' | 'identity' | 'wrap', extrapolateRight?: 'extend' | 'clamp' | 'identity' | 'wrap', easing?: (t: number) => number } ): number ``` **Examples:** ```tsx // Basic interpolation interpolate(15, [0, 30], [0, 100]); // 50 // With clamping interpolate(50, [0, 30], [0, 1], { extrapolateRight: 'clamp' }); // 1 // Multiple keyframes interpolate(frame, [0, 20, 40, 60], [0, 1, 1, 0]); // With easing interpolate(frame, [0, 30], [0, 100], { easing: Easing.bezier(0.42, 0, 0.58, 1) }); ``` ## spring() ```tsx spring({ frame: number, fps: number, config?: { damping?: number, // Default: 10 mass?: number, // Default: 1 stiffness?: number, // Default: 100 overshootClamping?: boolean }, from?: number, // Default: 0 to?: number, // Default: 1 durationInFrames?: number, durationRestThreshold?: number, delay?: number, reverse?: boolean }): number ``` **Config presets:** - High bounce: `{ damping: 5, stiffness: 200 }` - No bounce: `{ damping: 20, stiffness: 100, overshootClamping: true }` - Slow: `{ damping: 20, mass: 2 }` ## measureSpring() Get the duration of a spring animation: ```tsx import { measureSpring } from 'remotion'; const duration = measureSpring({ fps: 30, config: { damping: 10 } }); // Returns number of frames until spring settles ``` ## interpolateColors() ```tsx interpolateColors( input: number, inputRange: number[], outputRange: string[], // Hex, rgb(), rgba(), hsl() options?: { extrapolateLeft?, extrapolateRight? } ): string ``` ## Easing ```tsx import { Easing } from 'remotion'; // Basic Easing.linear Easing.ease Easing.quad Easing.cubic // In/Out/InOut variants Easing.in(Easing.quad) Easing.out(Easing.cubic) Easing.inOut(Easing.ease) // Cubic bezier Easing.bezier(x1, y1, x2, y2) // Other Easing.circle Easing.back(s?) // Overshoot Easing.elastic(bounciness?) Easing.bounce Easing.sin Easing.exp Easing.poly(n) // Power of n ``` ## Components ### Composition ```tsx <Composition id="MyVideo" component={MyComponent} // OR lazyComponent={() => import('./MyComponent')} durationInFrames={150} fps={30} width={1920} height={1080} defaultProps={{ title: 'Hello' }} calculateMetadata={async ({ props }) => ({ durationInFrames: props.items.length * 30, props: { ...props, computed: true } })} /> ``` ### Sequence ```tsx <Sequence from={30} // Start frame durationInFrames={60} // Optional duration name="Intro" // Label in Studio timeline layout="none" // "none" | "absolute-fill" > <Child /> </Sequence> ``` ### Series ```tsx <Series> <Series.Sequence durationInFrames={30} offset={-5}> <A /> {/* Frames 0-29 */} </Series.Sequence> <Series.Sequence durationInFrames={60}> <B /> {/* Frames 25-84 (offset caused overlap) */} </Series.Sequence> </Series> ``` ### Loop ```tsx <Loop durationInFrames={30} times={3} // Or Infinity layout="none" > <Animation /> </Loop> ``` ### AbsoluteFill ```tsx <AbsoluteFill style={{ backgroundColor: '#000' }}> {/* Position: absolute, full width/height */} </AbsoluteFill> ``` ### Media Components **Img** (waits for load): ```tsx <Img src={staticFile('photo.jpg')} style={{ width: '100%' }} /> ``` **Video/Html5Video:** ```tsx <Video src={staticFile('clip.mp4')} volume={0.5} // 0-1, or callback: (f) => f / 100 playbackRate={1.5} muted={false} loop={false} startFrom={30}