Remotion Best Practices

Best practices for Remotion - Video creation in React

npx skills add https://github.com/remotion-dev/skills --skill remotion-best-practices

When to use

Use this skills whenever you are dealing with Remotion code to obtain the domain-specific knowledge.

New project setup

When in an empty folder or workspace with no existing Remotion project, scaffold one using:

npx create-video@latest --yes --blank --no-tailwind my-video

Replace my-video with a suitable project name.

Designing a video

Animate properties using useCurrentFrame() and interpolate(). Use Easing to customize the timing of the animation.

import { useCurrentFrame, Easing } from "remotion";

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

  const opacity = interpolate(frame, [0, 2 * fps], [0, 1], {
    extrapolateRight: "clamp",
    extrapolateLeft: "clamp",
    easing: Easing.bezier(0.16, 1, 0.3, 1),
  });

  return <div style={{ opacity }}>Hello World!</div>;
};

CSS transitions or animations are FORBIDDEN - they will not render correctly.
Tailwind animation class names are FORBIDDEN - they will not render correctly.

Place assets in the public/ folder at your project root.

Use staticFile() to reference files from the public/ folder.

Add images using the <Img> component:

import { Img, staticFile } from "remotion";

export const MyComposition = () => {
  return <Img src={staticFile("logo.png")} style={{ width: 100, height: 100 }} />;
};

Add videos using the <Video> component from @remotion/media:

import { Video } from "@remotion/media";
import { staticFile } from "remotion";

export const MyComposition = () => {
  return <Video src={staticFile("video.mp4")} style={{ opacity: 0.5 }} />;
};

Add audio using the <Audio> component from @remotion/media:

import { Audio } from "@remotion/media";
import { staticFile } from "remotion";

export const MyComposition = () => {
  return <Audio src={staticFile("audio.mp3")} />;
};

Assets can be also referenced as remote URLs:

import { Video } from "@remotion/media";

export const MyComposition = () => {
  return <Video src="https://remotion.media/video.mp4" />
};

To delay content wrap it in <Sequence> and use from. To limit the duration of an element, use durationInFrames of <Sequence>. <Sequence> by default is an absolute fill. For inline content, use layout="none".

import { Sequence } from "remotion";

export const Title = () => {
  const frame = useCurrentFrame();
  const { fps } = useVideoConfig();

  const opacity = interpolate(frame, [0, 2 * fps], [0, 1], {
    extrapolateRight: "clamp",
    extrapolateLeft: "clamp",
    easing: Easing.bezier(0.16, 1, 0.3, 1),
  });

  return <div style={{ opacity }}>Title</div>;
};

export const Subtitle = () => {
  return <div>Subtitle</div>;
};

const Main = () => {
  const {fps} = useVideoConfig();

  return (
    <AbsoluteFill>
      <Sequence>
        <Background />
      </Sequence>
      <Sequence from={1 * fps} durationInFrames={2 * fps} layout="none">
        <Title />
      </Sequence>
      <Sequence from={2 * fps} durationInFrames={2 * fps} layout="none">
        <Subtitle />
      </Sequence>
    </AbsoluteFill>
  );
}

The width, height, fps, and duration of a video is defined in src/Root.tsx:

import { Composition } from "remotion";
import { MyComposition } from "./MyComposition";

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

Metadata can also be calculated dynamically:

import { Composition, CalculateMetadataFunction } from "remotion";
import { MyComposition, MyCompositionProps } from "./MyComposition";

const calculateMetadata: CalculateMetadataFunction<
  MyCompositionProps
> = async ({ props, abortSignal }) => {
  const data = await fetch(`https://api.example.com/video/${props.videoId}`, {
    signal: abortSignal,
  }).then((res) => res.json());

  return {
    durationInFrames: Math.ceil(data.duration * 30),
    props: {
      ...props,
      videoUrl: data.url,
    },
    width: 1080,
    height: 1080,
  };
};

export const RemotionRoot = () => {
  return (
    <Composition
      id="MyComposition"
      component={MyComposition}
      fps={30}
      width={1080}
      height={1080}
      defaultProps={{ videoId: "abc123" }}
      calculateMetadata={calculateMetadata}
    />
  );
};

Starting preview

Start the Remotion Studio to preview a video:

npx remotion studio

Optional: one-frame render check

You can render a single frame with the CLI to sanity-check layout, colors, or timing.
Skip it for trivial edits, pure refactors, or when you already have enough confidence from Studio or prior renders.

npx remotion still [composition-id] --scale=0.25 --frame=30

At 30 fps, --frame=30 is the one-second mark (--frame is zero-based).

Captions

When dealing with captions or subtitles, load the ./rules/subtitles.md file for more information.

Using FFmpeg

For some video operations, such as trimming videos or detecting silence, FFmpeg should be used. Load the ./rules/ffmpeg.md file for more information.

Silence detection

When needing to detect and trim silent segments from video or audio files, load the ./rules/silence-detection.md file.

Audio visualization

When needing to visualize audio (spectrum bars, waveforms, bass-reactive effects), load the ./rules/audio-visualization.md file for more information.

Sound effects

When needing to use sound effects, load the ./rules/sfx.md file for more information.

3D content

See rules/3d.md for 3D content in Remotion using Three.js and React Three Fiber.

Advanced audio

See rules/audio.md for advanced audio features like trimming, volume, speed, pitch.

Dynamic duration, dimensions and data

See rules/calculate-metadata.md for dynamically set composition duration, dimensions, and props.

Advanced compositions

See rules/compositions.md for how to define stills, folders, default props and for how to nest compositions.

Google Fonts

Is the recommended way to load fonts in Remotion. See rules/google-fonts.md for how to load Google Fonts.

Local fonts

See rules/local-fonts.md for how to load local fonts.

Getting audio duration

See rules/get-audio-duration.md for getting the duration of an audio file in seconds with Mediabunny.

Getting video dimensions

See rules/get-video-dimensions.md for getting the width and height of a video file with Mediabunny.

Getting video duration

See rules/get-video-duration.md for getting the duration of a video file in seconds with Mediabunny.

GIFs

See rules/gifs.md for how to display GIFs synchronized with Remotion's timeline.

Advanced Images

See rules/images.md for sizing and positioning images, dynamic image paths, and getting image dimensions.

Light leaks

See rules/light-leaks.md for light leak overlay effects using @remotion/light-leaks.

Lottie animations

See rules/lottie.md for embedding Lottie animations in Remotion.

HTML in canvas

See rules/html-in-canvas.md if you need to render HTML into a <canvas> to apply 2D or WebGL effects via <HtmlInCanvas>.

Measuring DOM nodes

See rules/measuring-dom-nodes.md for measuring DOM element dimensions in Remotion.

Measuring text

See rules/measuring-text.md for measuring text dimensions, fitting text to containers, and checking overflow.

Advanced sequencing

See rules/sequencing.md for more sequencing patterns - delay, trim, limit duration of items.

TailwindCSS

See rules/tailwind.md for using TailwindCSS in Remotion.

Text animations

See rules/text-animations.md for typography and text animation patterns.

Advanced timing

See rules/timing.md for advanced timing with interpolate and Bézier easing, and springs.

Transitions

See rules/transitions.md for scene transition patterns.

Transparent videos

See rules/transparent-videos.md for rendering out a video with transparency.

Trimming

See rules/trimming.md for trimming patterns - cutting the beginning or end of animations.

Advanced Videos

See rules/videos.md for advanced knowledge about embedding videos - trimming, volume, speed, looping, pitch.

Parameterized videos

See rules/parameters.md for making a composition parametrizable by adding a Zod schema.

Maps

For simple maps with little flyovers, consider using static map images. For complex maps with animated routes or flyovers, load the maps rule: rules/maplibre.md

Voiceover

See rules/voiceover.md for adding AI-generated voiceover to Remotion compositions using ElevenLabs TTS.

Verwandte Skills

notion-meeting-intelligence
openai
Prepare meeting materials with Notion context and Codex research; use when gathering context, drafting agendas/pre-reads, and tailoring materials to attendees.
official
firecrawl-agent
firecrawl
AI-powered autonomous extraction. The agent navigates sites and extracts structured data (takes 2-5 minutes).
official
persona-researcher
Google
Organize research — manage references, notes, and collaboration.
brand-guidelines
sentry
Schreibe Texte gemäß den Sentry-Markenrichtlinien. Verwende dies beim Verfassen von UI-Texten, Fehlermeldungen, Leerzuständen, Onboarding-Abläufen, 404-Seiten, Dokumentation, Marketing…
official
nitro
sentry
Erstellen und bereitstellen universeller JavaScript-Server mit Nitro v3. Verwenden bei der Arbeit mit nitro.config.ts, defineNitroConfig, defineHandler, defineConfig, server.ts…
official
controlnet-pose
agentspace-so
Pose-conditioned generation on RunComfy via the `runcomfy` CLI. Routes across Kling 2-6 Motion Control Pro / Standard (transfer the motion / blocking of a reference video onto a target character), community Wan 2-2 Animate (audio-driven character animation with pose conditioning), and Z-Image Turbo ControlNet LoRA (pose-conditioned image generation from an OpenPose / DWPose / canny / depth control image). Picks the right route based on video vs still and stylized vs photoreal. Triggers on...
creativevideoimage
seedance-v2
runcomfy-com
Generate cinematic short-form video with ByteDance Seedance 2.0 Pro on RunComfy. Documents Seedance 2.0 Pro's strengths (multi-modal references — up to 9 images, 3 videos, 3 audio — synchronized in-pass audio with natural lip-sync, cinematic motion refinement), the 4–15s duration schema, and when to route to HappyHorse 1.0 / Wan 2.7 / Kling instead. Calls `runcomfy run bytedance/seedance-v2/pro` through the local RunComfy CLI. Triggers on "seedance", "seedance 2", "seedance v2", "seedance...
creativevideomedia
slack
firecrawl
Verwenden Sie, wenn Sie Slack über das Slack-Tool von OpenClaw aus steuern müssen, einschließlich des Reagierens auf Nachrichten oder des Anheften/Lösens von Elementen in Slack-Kanälen oder Direktnachrichten.
official