PTENES
MODULE 3.3

⚛️ remotion

Create videos programmatically in React — frame-by-frame composition, smooth interpolations, Sequences, spring physics, and rendering to a real MP4.

6
Topics
~30
Minutes
Advanced
Level
Video/React
Type
Intro MainContent Other interpolate(frame) spring(fps) frame 0 frame N React → Frames → MP4 fps: 30
🧩

What it is / what it does

TOPIC 1
Main concept

Remotion is a framework that treats each video frame as a React component.

Instead of editing on a video editor's timeline, you write TypeScript/JSX. The framework controls which "frame" is being rendered via useCurrentFrame(), and you map this number to any visual property: opacity, scale, position, color. The result is exported frame by frame to a real MP4 — no cloud, no per-render cost.

What Remotion delivers
  • ▸ Compositions defined in src/Root.tsx with <Composition>
  • ▸ Deterministic animations via useCurrentFrame() + interpolate()
  • ▸ Motion physics with spring()
  • ▸ Sequencing with <Sequence> e <Series>
  • ▸ Render via CLI: npx remotion render
Actual skill stack
  • ▸ React + TypeScript — the component is the frame
  • ▸ remotion — main package + hooks
  • ▸ @remotion/renderer — headless rendering CLI
  • ▸ @remotion/captions — synchronized captions
  • ▸ @remotion/three — React Three Fiber integration
useCurrentFrame
central hook — returns the frame number
interpolate()
maps frames → CSS values
spring()
spring physics, natural bounce
<Composition>
sets fps, dimensions, and duration
🎣

When it runs

TOPIC 2
💡 Skill trigger

The skill remotion is triggered whenever code matters remotion or you ask Claude Code to create/edit programmatic videos in React. The description trigger: "Use this skill whenever you are dealing with Remotion code to obtain the domain-specific knowledge."

Trigger timeline
Code matters remotion
Any .tsx/.ts file with import ... from 'remotion'
Programmatic video request in React
"Create a presentation video", "Animate this chart for video", "Create a reel with animated text"
Adjust an existing animation
Fix spring bounce, adjust fps, change durationInFrames, create a Sequence with a delay
Render / export
CLI commands, bundling, MP4/WebM output, quality parameters
✓ Use the remotion skill when...
  • ✓ Export real MP4/WebM video from React
  • ✓ Animate data, charts, and text frame by frame
  • ✓ Create code-controlled motion graphics
  • ✓ Integrate Three.js 3D directly into the video
  • ✓ Sync subtitles (.srt) with audio
✗ Don’t confuse this with...
  • ✗ animation-designer — animates the HTML page in the browser; it does not export video
  • ✗ HyperFrames — converts static HTML into MP4 via Puppeteer+FFmpeg, without React
  • ✗ 3d-animation-creator — animates 3D objects on canvas; it does not export MP4 directly
import 'remotion'
automatic trigger
React video
explicit request
spring/timing
animation adjustment
render CLI
MP4 export
🚀

How it improves your videos

TOPIC 3
📊 Why Remotion changes the game
Total determinism
The same frame always produces the same pixel. No timeline glitches or inconsistent renders.
Git versioning
Videos are code—diff, branch, merge, CI/CD. Impossible in traditional editors.
Componentization
Reuse Intro, Lower Third, Outro as React components across multiple projects.
💡 Real-world best practices (from the SKILL.md)
  • • Write animations in seconds × fps, never in fixed frames: 2 * fps instead of 60
  • • CSS transitions / Tailwind animation classes are prohibited — don’t render correctly
  • • Always use extrapolateRight: 'clamp' to prevent values from going out of range
  • • Use premountFor throughout <Sequence> to avoid visual pop-in
✓ With the skill active
  • ✓ spring() with the right damping → no excessive bounce
  • ✓ interpolate() with clamp → no artifacts at the extremes
  • ✓ Premounted Sequences → smooth transitions
  • ✓ Animations written in seconds → portable across frame rates
✗ Without the skill
  • ✗ CSS transition in JSX → frame renders as a static image
  • ✗ interpolate without clamp → negative opacity values
  • ✗ Sequence without premount → elements flicker on entry
  • ✗ spring without the right delay → overlapping animations
determinism
same frame = same pixel
Git-friendly
video as code
extrapolate clamp
values never leak
fps × seconds
timing portability
⚙️

How it works under the hood

TOPIC 4
Anatomy of a Remotion composition
// src/Root.tsx — defines the composition
import { Composition } from 'remotion';
import { MyVideo } from './MyVideo';

export const RemotionRoot = () => (
<Composition
id="MyVideo"
component={'{'}MyVideo{'}'}
durationInFrames={'{'}150{'}'}
fps={'{'}30{'}'}
width={'{'}1920{'}'}
height={'{'}1080{'}'}
/>
);
interpolate() — linear with easing
// Deterministic FadeIn
import {'{'} useCurrentFrame, interpolate, Easing {'}'} from 'remotion';

const FadeIn = () => {'{'}
const frame = useCurrentFrame();
const { fps } = useVideoConfig();

const opacity = interpolate(
frame, [0, 2 * fps], [0, 1],
{ extrapolateRight: 'clamp' {'}'}
);

return <div style={'{'}{'{'}opacity{'}'}{'}'}}>Hello!</div>;
{'}'}
spring() — spring physics
// Recommended settings
import {'{'} spring, useVideoConfig {'}'} from 'remotion';

// smooth, no bounce
const smooth = {'{'} damping: 200 {'}'};

// snappy with a slight bounce
const snappy = {'{'} damping: 20, stiffness: 200 {'}'};

// heavy, slow
const heavy = {'{'} damping: 15, stiffness: 80, mass: 2 {'}'};

const scale = spring({'{'} frame, fps, config: smooth {'}'});
Sequence + Series — sequencing
// Always use premountFor in Sequence!
import {'{'} Sequence, Series {'}'} from 'remotion';

// Manual Sequence with delay
<Sequence from={'{'}1 * fps{'}'} durationInFrames={'{'}2 * fps{'}'} premountFor={'{'}1 * fps{'}'}>
<Title />
</Sequence>

// Series — one after another, with no overlap
<Series>
<Series.Sequence durationInFrames={'{'}45{'}'}><Intro /></Series.Sequence>
<Series.Sequence durationInFrames={'{'}60{'}'}><Main /></Series.Sequence>
<Series.Sequence offset={'{'}-15} durationInFrames={30{'}'}><Other /></Series.Sequence>
</Series>
💡 Render via CLI
# Render to MP4
npx remotion render MyVideo out/video.mp4

# Render Only Specific Frames (Preview)
npx remotion render MyVideo out/video.mp4 --frames=0-30

# Studio (Interactive Browser Preview)
npx remotion studio
src/Root.tsx
composition entrypoint
AbsoluteFill
standard background layer
premountFor
loads before displaying
negative offset
overlap between scenes
💬

Practical example + ready-to-use PROMPT

TOPIC 5
Scenario: Product presentation video (30s, 30fps = 900 frames)

A 1920×1080 video with three scenes chained via Series: Intro with the logo fading in + spring scaling, Features listing 3 items with stagger, CTA with pulsing text. Exported to MP4 via CLI.

MyVideo.tsx — complete composition
// src/MyVideo.tsx
import {'{'} AbsoluteFill, Series, useCurrentFrame, useVideoConfig, interpolate, spring {'}'} from 'remotion';

const Intro: React.FC = () => {'{'}
const frame = useCurrentFrame();
const { fps } = useVideoConfig();
const opacity = interpolate(frame, [0, 1 * fps], [0, 1], {'{'} extrapolateRight: 'clamp' {'}'});
const scale = spring({'{'} frame, fps, config: {'{'} damping: 200 {'}'} {'}'});
return (
<AbsoluteFill style={'{'}{'{'}display:'flex', alignItems:'center', justifyContent:'center', backgroundColor:'#0a0a1a'{'}'}{'}'}>
<h1 style={'{'}{'{'}opacity, transform:`scale(${'{'} scale {'}'})`, color:'#a855f7', fontSize:80}'}>MyProduct</h1>
</AbsoluteFill>
);
{'}'}

export const MyVideo: React.FC = () => (
<Series>
<Series.Sequence durationInFrames={'{'}3 * fps{'}'}><Intro /></Series.Sequence>
<Series.Sequence durationInFrames={'{'}5 * fps{'}'}><Features /></Series.Sequence>
<Series.Sequence durationInFrames={'{'}2 * fps{'}'}><CTA /></Series.Sequence>
</Series>
);
📋 Ready-to-use PROMPT — paste into Claude Code
Create a complete Remotion project in TypeScript with the following specs: - "PromoVideo" composition: 1920×1080, 30fps, 300 frames (10s) - Scene 1 (frames 0-90): logo fades in with spring scale (damping: 200), no bounce - Scene 2 (frames 90-240): 3 features listed with a stagger of 20 frames each, interpolate opacity+translateY - Scene 3 (frames 240-300): CTA with pulsing text via spring in-out - NEVER use CSS transitions — only useCurrentFrame + interpolate/spring - ALWAYS use extrapolateRight/Left: 'clamp' in every interpolate() - ALWAYS set premountFor={fps} on every Sequence - Export command: npx remotion render PromoVideo out/promo.mp4
scenes in Series
clean chaining
manual stagger
frame offset per item
in-out spring
smooth entrance + exit
CLI render
npx remotion render
🧬

Works with / limitations

TOPIC 6
⚠️ Critical difference — three distinct tools
⚛️ remotion (this module)
React → frames → MP4. Exports real video. Requires Node.js, TypeScript. Animations via useCurrentFrame, deterministic.
🎬 HyperFrames (3.4)
HTML+CSS → Puppeteer → FFmpeg → MP4. No React. Animates static HTML. Simpler, with less frame-level control.
🎬 animation-designer (3.1)
Framer Motion / CSS / GSAP on the HTML page. Doesn't export video — animates only in the browser.
🔗 Pairs well with
  • ▸
    3d-animation-creator (3.2)

    Use @remotion/three to embed React Three Fiber scenes directly into the Remotion composition — 3D rendered frame by frame, exported as MP4.

  • ▸
    HyperFrames / seedance (3.4)

    Use Remotion to generate complex clips and HyperFrames/FFmpeg to assemble the final edit: concatenate, add music, and add simple overlays without rebuilding React.

  • ▸
    canvas-design (2.3)

    Export canvas-design assets as static images and import them into Remotion with <Img> or staticFile().

🚫 When NOT to use Remotion
  • ✗ Just want to animate the landing page — use animation-designer
  • ✗ Have ready-made HTML and want a quick MP4 without React — use HyperFrames
  • ✗ Want just to visualize 3D on a canvas — use 3d-animation-creator
  • ✗ Need cloud rendering without local Node.js — consider Remotion Lambda
  • ✗ Non-React project (Vue, Angular, plain HTML) — use HyperFrames/FFmpeg
Quick comparison — Media T3
Skill Export MP4? Stack Frame-based control?
⚛️ remotion ✓ Yes React + TypeScript ✓ Total
🔁 HyperFrames ✓ Yes HTML + Puppeteer + FFmpeg ~ Partial (CSS)
🎬 animation-designer ✗ No Framer Motion / CSS ✗ Browser only
🖱️ 3d-animation-creator ✗ Not directly Three.js / p5.js / Canvas ~ Via @remotion/three
@remotion/three
3D directly in the video
staticFile()
project assets
Remotion Lambda
AWS cloud rendering
calculateMetadata
dynamic duration based on data

📋 Module 3.3 Summary

What you learned
  • ✓ Remotion = programmatic video in React, frame = component
  • ✓ useCurrentFrame() + interpolate() control all animation
  • ✓ spring() precise spring physics delivery
  • ✓ CSS transitions are prohibited — they break rendering
  • ✓ <Sequence> / <Series> sequence scenes with premount
  • ✓ Render via npx remotion render → Local MP4
  • ✓ Clear distinction from HyperFrames and animation-designer
  • ✓ @remotion/three connects with 3d-animation-creator
Next module
3.4 🔁 seedance + HyperFrames/FFmpeg

Video loop with seedance, non-linear editing with HyperFrames, and final assembly via FFmpeg — the complete production pipeline without React.

Go to 3.4 →