Skip to main content
Every animation generated by Remotion Prompt to Motion Graphics is designed for easy customization. This guide explains the constants-first architecture and how to make edits in the Monaco code editor.

Constants-First Design

All generated components follow a strict structure that places customizable values at the top:
Component Structure
import { useCurrentFrame, useVideoConfig, AbsoluteFill } from 'remotion';

export const MyAnimation = () => {
  // 1. Hooks (useCurrentFrame, useVideoConfig, etc.)
  const frame = useCurrentFrame();
  const { fps, width, height } = useVideoConfig();
  
  // 2. Editable Constants - ALL UPPER_SNAKE_CASE
  const COLOR_BACKGROUND = "#1a1a2e";
  const COLOR_TEXT = "#ffffff";
  const TITLE_TEXT = "Hello World";
  const FADE_DURATION = 20;
  const PADDING = 40;
  
  // 3. Calculations and derived values
  const opacity = interpolate(frame, [0, FADE_DURATION], [0, 1]);
  
  // 4. Return JSX
  return (
    <AbsoluteFill style={{ backgroundColor: COLOR_BACKGROUND }}>
      {/* ... */}
    </AbsoluteFill>
  );
};
All constants are defined inside the component body, after hooks. This allows you to easily find and modify values without touching the animation logic.

Why Constants-First?

This design pattern provides several benefits:
  1. Easy Discovery - All customizable values in one place
  2. No Magic Numbers - Every value has a descriptive name
  3. Type Safety - Monaco editor provides autocomplete
  4. Live Preview - Changes update instantly in the Remotion player
Look for UPPER_SNAKE_CASE variable names at the top of the component to find what you can customize.

Making Quick Edits in Monaco

The Monaco editor (same engine as VS Code) provides a powerful environment for code customization.

Changing Colors

Find color constants and update hex values:
Before
const COLOR_BACKGROUND = "#1a1a2e";
const COLOR_PRIMARY = "#3B82F6";
After
const COLOR_BACKGROUND = "#000000"; // Changed to black
const COLOR_PRIMARY = "#10B981";    // Changed to green
The preview updates automatically when you stop typing.

Changing Text Content

Update text constants:
Before
const TITLE_TEXT = "Welcome";
const SUBTITLE_TEXT = "to our product";
After
const TITLE_TEXT = "Hello World";      
const SUBTITLE_TEXT = "Let's get started";
Use double quotes for string constants to maintain consistency with the generated code style.

Adjusting Timing

Modify duration and delay constants (measured in frames):
Before
const FADE_DURATION = 20;    // ~0.67s at 30fps
const TITLE_DELAY = 10;      // ~0.33s at 30fps  
After
const FADE_DURATION = 40;    // Slower fade (~1.33s)
const TITLE_DELAY = 0;       // Remove delay
At 30fps: 30 frames = 1 second. Multiply desired seconds by the fps value to get frame count.

Changing Layout Values

Update positioning and spacing constants:
Before
const PADDING = 40;
const TITLE_SIZE = 72;
const SPACING = 20;
After
const PADDING = 80;      // More breathing room
const TITLE_SIZE = 96;   // Larger title
const SPACING = 40;      // More space between elements

Common Customization Patterns

Spring Physics Adjustments

Generated code uses Remotion’s spring() function for organic motion. Customize the physics:
Original
const scale = spring({
  frame,
  fps,
  config: { damping: 12, stiffness: 100 }
});
Bouncier (more overshoot):
config: { damping: 8, stiffness: 120 }  // Lower damping = more bounce
Stiffer (faster, less bounce):
config: { damping: 20, stiffness: 200 } // Higher values = faster settling
Slower motion:
config: { damping: 12, stiffness: 50 }  // Lower stiffness = slower
damping: How quickly oscillation decreases (lower = bouncier) stiffness: How strong the spring force is (higher = faster)

Interpolation Ranges

For linear animations, adjust interpolate() ranges:
Original
const opacity = interpolate(
  frame,
  [0, 30],        // Input range (frames)
  [0, 1],         // Output range (opacity)
  { extrapolateRight: 'clamp' }
);
Delay the start:
[10, 40],  // Start at frame 10 instead of 0
Make it faster:
[0, 15],   // Complete in 15 frames instead of 30
Reverse the animation:
[1, 0],    // Fade out instead of in

Using Natural Language Edits

Instead of manually editing code, you can describe changes in natural language. The system will apply targeted edits.

Small Targeted Changes

For simple modifications, describe what you want:
Example Follow-Up Prompts
"Change the background color to navy blue"
"Make the title text say 'Welcome Back'"
"Increase the animation speed by 50%"
"Add 20px more padding"
The AI will generate targeted edits that modify only the specific constants:
Edit Operation
{
  "type": "edit",
  "edits": [
    {
      "description": "Update background color",
      "old_string": "const COLOR_BACKGROUND = \"#1a1a2e\";",
      "new_string": "const COLOR_BACKGROUND = \"#001F3F\";"
    }
  ]
}
Targeted edits preserve your manual changes. If you’ve customized other parts of the code, they won’t be affected.

Major Restructuring

For significant changes, the system uses full code replacement:
Example Follow-Up Prompts
"Convert this to a vertical TikTok format"
"Change from bar chart to pie chart"
"Completely different style - make it minimalist"
Full replacement will overwrite all manual edits. Save your custom code before requesting major changes.

Manual vs AI Edits

You can mix manual editing in Monaco with AI-powered edits:

Workflow 1: AI First, Manual Polish

  1. Generate initial animation with detailed prompt
  2. Review generated code and constants
  3. Make small manual adjustments (colors, timing, text)
  4. Use AI for complex additions (“add a subtitle below”)

Workflow 2: Manual First, AI Enhancement

  1. Generate basic animation
  2. Manually customize all constants to your liking
  3. Use AI for structural changes (“add spring physics to the entrance”)
The system detects when you’ve made manual edits and preserves them during targeted AI edits. Your changes won’t be lost unless you request full code replacement.

Monaco Editor Features

The built-in code editor provides VS Code-like functionality:

Syntax Highlighting

  • TypeScript/JSX syntax highlighting with semantic colors
  • Error indicators - Red squiggly lines for syntax errors
  • Import validation - Warnings for undefined imports

Code Intelligence

  • Auto-complete - Ctrl+Space for suggestions
  • Type checking - Hover over variables to see types
  • Go to definition - Ctrl+Click on imports

Editing Shortcuts

  • Ctrl+F - Find and replace
  • Ctrl+/ - Toggle line comment
  • Alt+Up/Down - Move line up/down
  • Ctrl+D - Select next occurrence
  • Ctrl+Z - Undo
  • Ctrl+Shift+Z - Redo
The editor automatically saves your changes and triggers live preview updates when you stop typing.

Understanding Generated Code Structure

Every component follows strict patterns:

Import Section

import { useCurrentFrame, useVideoConfig, AbsoluteFill } from "remotion";
import { interpolate, spring } from "remotion";
Only imports actually used in the code are included.

Multi-Line Comment

/**
 * Animated bar chart showing quarterly revenue.
 * Features spring-based entrance animations with staggered timing.
 */
Describes what the animation does (2-3 sentences).

Hooks Section

const frame = useCurrentFrame();
const { fps, width, height, durationInFrames } = useVideoConfig();
Always comes before constants. Never modify this section.

Constants Section

// COLORS
const COLOR_BACKGROUND = "#000000";
const COLOR_PRIMARY = "#3B82F6";

// TEXT
const TITLE_TEXT = "Revenue Report";
const FONT_SIZE = 48;

// TIMING  
const FADE_DURATION = 20;
const STAGGER_DELAY = 5;

// LAYOUT
const PADDING = 60;
const BAR_WIDTH = 80;
Grouped by category with comments. This is where you make most edits.

Return JSX

return (
  <AbsoluteFill style={{ backgroundColor: COLOR_BACKGROUND }}>
    {/* Animation elements */}
  </AbsoluteFill>
);
Uses inline styles only (no CSS classes or styled-components).
The <AbsoluteFill> wrapper always has backgroundColor set from frame 0. Backgrounds never fade in from undefined.

Common Pitfalls

Reserved Variable Names

Never use these names for custom variables - they shadow Remotion imports:
  • spring, interpolate, useCurrentFrame, useVideoConfig
  • AbsoluteFill, Sequence, Series
Use descriptive names instead: scaleSpring, opacityInterpolate, etc.

Font Family

All generated code uses:
fontFamily: 'Inter, sans-serif'
Inter is preloaded in the Remotion configuration. Change to other web-safe fonts if needed:
fontFamily: 'Arial, sans-serif'
fontFamily: 'Georgia, serif'
fontFamily: 'Courier New, monospace'

Extrapolate Options

Always use extrapolate clamping to prevent unexpected values:
Correct
interpolate(
  frame,
  [0, 30],
  [0, 1],
  { extrapolateLeft: 'clamp', extrapolateRight: 'clamp' } // ✓ Prevents values outside range
)
Incorrect
interpolate(frame, [0, 30], [0, 1]) // ✗ Values can exceed 0-1 range

Copying Code for Use Outside

The editor header includes a copy button. Copied code can be used in any Remotion project:
  1. Click the copy button in the editor header
  2. Create a new .tsx file in your Remotion project
  3. Paste the component code
  4. Import and use in your Root.tsx:
Root.tsx
import { MyAnimation } from './MyAnimation';

export const RemotionRoot = () => {
  return (
    <Composition
      id="MyAnimation"
      component={MyAnimation}
      durationInFrames={150}
      fps={30}
      width={1920}
      height={1080}
    />
  );
};

Summary

Key principles for customization:
  1. All editable values are UPPER_SNAKE_CASE constants at the top
  2. Constants are grouped by category (COLORS, TEXT, TIMING, LAYOUT)
  3. The Monaco editor provides live preview with automatic updates
  4. Use natural language for complex edits, manual editing for quick tweaks
  5. Mix AI and manual edits - your changes are preserved during targeted edits
Start by exploring the constants section to understand what’s customizable, then make changes incrementally while watching the live preview.

Build docs developers (and LLMs) love