agentleFS
AnastasiyaWAnastasiyaW/codex-claude-code-config/skills/video-production/remotion-production-guide/SKILL.md

remotion-production-guide

Skill213 starsChanged 2 days agoMITView on GitHub

Remotion (React video framework) production guide with Apple-style design rules. Use when: 'create video with remotion', 'remotion project', 'render video', 'product demo video', 'animated video', 'video from code'. Covers project setup, animation library, spring presets, typography rules, color palettes, pacing tables, scene templates, 3D integration, and export settings for all platforms. Do NOT use to write the script or narrative beats (use video-narrative-arc), to critique a script's impact (use script-evaluator), or for FFmpeg audio mastering/captions/platform color-grade on a finished render (use video-post-production); this stage builds and renders scenes in React/code.

  • Installs packages

We split this skill into the rules it gives an agent

16 rules. About 0 are common, 11 are distinctive, and 5 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈11

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 5

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    NEVER animate text while expecting reading

    line 122
  2. Very specific:

    Use linear-gradient for premium text (WebkitBackgroundClip: 'text')

    line 155
  3. Distinctive:

    Breathing rule: After 3+ fast cuts, add one slow shot (5-8s).

    line 165
  4. Very specific:

    Use <ThreeCanvas> (not <Canvas>) for R3F in Remotion

    line 191
  5. Very specific:

    Use useCurrentFrame() instead of R3F's useFrame()

    line 192
  6. Distinctive:

    NEVER: use CSS transitions/animations - won't render during export

    line 215
  7. Very specific:

    ALWAYS: use useCurrentFrame() + interpolate() or spring()

    line 216
  8. Very specific:

    Use <Img> from remotion (not <img>) for reliable image loading

    line 219
  9. Distinctive:

    Don't rotate text

    line 225
  10. Distinctive:

    Don't bounce text (unless playful brand)

    line 226
  11. Distinctive:

    Don't animate 3+ elements simultaneously

    line 227
  12. Distinctive:

    Don't use more than 2 animation styles per video

    line 228
  13. Distinctive:

    Don't use star wipes or random transitions

    line 229
  14. Distinctive:

    Don't put more than 7 words on screen at once

    line 230
  15. Distinctive:

    Don't start with a logo (start with the hook)

    line 231
  16. Distinctive:

    Don't commit node_modules

    line 232

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Remotion Production Guide

Complete reference for creating production-quality videos with Remotion. Combines Apple-style design rules, motion design principles, and battle-tested animation patterns.

Quick Start

mkdir -p src && npm init -y
npm install --save-exact remotion @remotion/cli react react-dom typescript @types/react
echo "node_modules/\ndist/\nout/\n.cache/" > .gitignore

Project Structure

src/
  index.ts          # registerRoot
  Root.tsx           # Composition registration
  videos/
    ProductDemo/
      index.tsx      # Main composition
      scenes/        # One file per scene
      components/    # Reusable visual elements
  lib/
    constants.ts     # ALL editable values (colors, timing, fonts, sizes)
    animations.ts    # Reusable animation helpers
  public/            # Static assets (images, music, sounds)

Constants-First Design

ALWAYS define all values in constants.ts. Never hardcode in components:

export const COLORS = {
  bg: '#000000',
  text: '#FFFFFF',
  accent: '#007AFF',
  muted: '#8E8E93',
  cardBg: '#1C1C1E',
} as const;

export const TIMING = {
  fps: 30,
  fadeIn: 15,        // 500ms
  fadeOut: 12,       // 400ms
  stagger: 4,        // 133ms between items
} as const;

export const SIZES = {
  heroText: 120,     // px
  titleText: 72,
  subtitleText: 42,
  bodyText: 28,
  captionText: 20,   // NEVER below 16
} as const;

Animation Library

import { interpolate, spring, Easing } from 'remotion';

// --- Opacity ---
export const fadeIn = (frame: number, delay = 0, duration = 15) =>
  interpolate(frame, [delay, delay + duration], [0, 1], {
    extrapolateLeft: 'clamp', extrapolateRight: 'clamp',
    easing: Easing.out(Easing.cubic),
  });

// --- Movement ---
export const slideUp = (frame: number, delay = 0, distance = 40) =>
  interpolate(frame, [delay, delay + 20], [distance, 0], {
    extrapolateLeft: 'clamp', extrapolateRight: 'clamp',
    easing: Easing.out(Easing.cubic),
  });

// --- Scale ---
export const scalePop = (frame: number, fps: number, delay = 0) =>
  Math.min(spring({ frame: frame - delay, fps, config: { damping: 12, mass: 0.5 } }), 1);

// --- Stagger ---
export const stagger = (index: number, base = 0, gap = 4) => base + index * gap;

// --- Counter ---
export const countTo = (frame: number, target: number, delay = 0, duration = 30) =>
  Math.round(target * interpolate(frame, [delay, delay + duration], [0, 1], {
    extrapolateLeft: 'clamp', extrapolateRight: 'clamp',
    easing: Easing.out(Easing.cubic),
  }));

Spring Presets

NameConfigUse Case
Smooth{ damping: 200 }Default transitions
Snappy{ damping: 20, stiffness: 200 }Quick appearances
Bouncy{ damping: 8, stiffness: 200 }Playful elements (badges, icons)
Gentle{ damping: 200, stiffness: 50 }Large elements (product images)

Typography Rules

RoleSizeWeightTiming on Screen
Hero number/stat120-200px800-9003-5 seconds
Section title64-80px6002-4 seconds
Subtitle36-48px5002-3 seconds
Body text24-32px400min 2 seconds
Caption16-20px400min 1.5 seconds
NEVER<16px-- illegible on video

Rules:

  • Letter-spacing: -1 to -2px for large text (>48px)
  • Line-height: 1.1-1.2 for headings, 1.4 for body
  • Max 7 words on screen simultaneously
  • NEVER animate text while expecting reading
  • Font: Inter, Geist Sans, or system-ui

Animation Timing

TypeFrames @30fpsms
Text fade in9-15300-500
Text fade out6-12200-400
Slide in12-18400-600
Product appear18-30600-1000
Scale pop6-12200-400
Scene transition9-15300-500
Item stagger2-467-133

Easing Reference

Use CaseEasing
Element enteringEasing.out(Easing.cubic)
Element exitingEasing.in(Easing.cubic)
Apple-styleEasing.bezier(0.25, 0.1, 0.25, 1.0)
Dramatic enterEasing.bezier(0.05, 0.7, 0.1, 1.0)
Material StandardEasing.bezier(0.4, 0.0, 0.2, 1.0)
NEVERlinear (except progress bars)

Color Palettes

Dark theme (premium/tech): bg #000/#0A0A0A, text #FFF, accent from brand Light theme (consumer/clean): bg #F5F3EF/#FFF, text #1D1D1F, accent from brand

  • Max 3 colors + black/white/gray
  • Background:text contrast min 7:1
  • Use linear-gradient for premium text (WebkitBackgroundClip: 'text')

Scene Pacing

FormatTotalScenesFrame Budget @30fps
15s teaser450 frames5~90 each
30s demo900 frames5~180 each
60s launch1800 frames7~260 each

Breathing rule: After 3+ fast cuts, add one slow shot (5-8s). Alternate rhythm: FAST→SLOW→MEDIUM.

Cross-Fade Wrapper

const Fade: React.FC<{ children: React.ReactNode; dur: number; fade?: number }> = 
  ({ children, dur, fade = 15 }) => {
  const frame = useCurrentFrame();
  const inVal = interpolate(frame, [0, fade], [0, 1], { extrapolateRight: 'clamp' });
  const outVal = interpolate(frame, [dur - fade, dur], [1, 0], {
    extrapolateLeft: 'clamp', extrapolateRight: 'clamp',
  });
  return <AbsoluteFill style={{ opacity: Math.min(inVal, outVal) }}>{children}</AbsoluteFill>;
};

3D Integration

# React Three Fiber in Remotion:
npm install @remotion/three @react-three/fiber three @types/three

# Lottie animations:
npm install @remotion/lottie lottie-web
  • Use <ThreeCanvas> (not <Canvas>) for R3F in Remotion
  • Use useCurrentFrame() instead of R3F's useFrame()
  • Spline: design in spline.design, export to R3F, import via @remotion/three

Export Settings

PlatformResolutionAspectCommand
YouTube1920x108016:9default
TikTok/Reels1080x19209:16--width 1080 --height 1920
Instagram Square1080x10801:1--width 1080 --height 1080
# High quality master
npx remotion render src/index.ts CompositionId out/video.mp4

# Custom quality (CRF 18 = high, 28 = web preview)
npx remotion render src/index.ts CompositionId out/video.mp4 --crf 18

Universal: MP4 container, H.264, AAC audio, yuv420p.

Critical Rules

  • NEVER use CSS transitions/animations - won't render during export
  • ALWAYS use useCurrentFrame() + interpolate() or spring()
  • ALWAYS extrapolateRight: 'clamp' to prevent overshoot
  • spring() never reaches exactly 1.0 - use Math.min(spring(...), 1) for scale
  • Use <Img> from remotion (not <img>) for reliable image loading
  • First render downloads Chrome Headless Shell (~108MB), subsequent use cache
  • Google Fonts: use @remotion/google-fonts for reliable loading

DON'T List

  • Don't rotate text
  • Don't bounce text (unless playful brand)
  • Don't animate 3+ elements simultaneously
  • Don't use more than 2 animation styles per video
  • Don't use star wipes or random transitions
  • Don't put more than 7 words on screen at once
  • Don't start with a logo (start with the hook)
  • Don't commit node_modules

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.