remotion · diff
git:20260131.424bd52 to git:20260704.1cfe1ee
354 added, 35 removed. Audit A to A.
---
- name: remotion
- description: Best practices for Remotion - Video creation in React
+ name: remotion-best-practices
+ description: Best practices and domain knowledge for building videos programmatically with Remotion (videos in React/TypeScript, rendered to MP4). Use whenever writing or editing Remotion code — scaffolding a video project, animating with interpolate/spring over useCurrentFrame(), sequencing scenes and transitions, captions/subtitles, audio, GIFs/Lottie/3D, charts, visual effects, dynamic duration via calculateMetadata, or rendering. Consult before reaching for a Remotion API, since its components and props evolve (e.g. @remotion/media).
metadata:
tags: remotion, video, react, animation, composition
---
## When to use
- Use this skills whenever you are dealing with Remotion code to obtain the domain-specific knowledge.
+ Use this skill whenever you are dealing with Remotion code to obtain the domain-specific knowledge.
- ## How to use
+ ## New project setup
- Read individual rule files for detailed explanations and code examples:
+ When in an empty folder or workspace with no existing Remotion project, scaffold one using:
- - [rules/3d.md](rules/3d.md) - 3D content in Remotion using Three.js and React Three Fiber
- - [rules/animations.md](rules/animations.md) - Fundamental animation skills for Remotion
- - [rules/assets.md](rules/assets.md) - Importing images, videos, audio, and fonts into Remotion
- - [rules/audio.md](rules/audio.md) - Using audio and sound in Remotion - importing, trimming, volume, speed, pitch
- - [rules/calculate-metadata.md](rules/calculate-metadata.md) - Dynamically set composition duration, dimensions, and props
- - [rules/can-decode.md](rules/can-decode.md) - Check if a video can be decoded by the browser using Mediabunny
- - [rules/charts.md](rules/charts.md) - Chart and data visualization patterns for Remotion
- - [rules/compositions.md](rules/compositions.md) - Defining compositions, stills, folders, default props and dynamic metadata
- - [rules/display-captions.md](rules/display-captions.md) - Displaying captions in Remotion with TikTok-style pages and word highlighting
- - [rules/extract-frames.md](rules/extract-frames.md) - Extract frames from videos at specific timestamps using Mediabunny
- - [rules/fonts.md](rules/fonts.md) - Loading Google Fonts and local fonts in Remotion
- - [rules/get-audio-duration.md](rules/get-audio-duration.md) - Getting the duration of an audio file in seconds with Mediabunny
- - [rules/get-video-dimensions.md](rules/get-video-dimensions.md) - Getting the width and height of a video file with Mediabunny
- - [rules/get-video-duration.md](rules/get-video-duration.md) - Getting the duration of a video file in seconds with Mediabunny
- - [rules/gifs.md](rules/gifs.md) - Displaying GIFs synchronized with Remotion's timeline
- - [rules/images.md](rules/images.md) - Embedding images in Remotion using the Img component
- - [rules/import-srt-captions.md](rules/import-srt-captions.md) - Importing .srt subtitle files into Remotion using @remotion/captions
- - [rules/lottie.md](rules/lottie.md) - Embedding Lottie animations in Remotion
- - [rules/measuring-dom-nodes.md](rules/measuring-dom-nodes.md) - Measuring DOM element dimensions in Remotion
- - [rules/measuring-text.md](rules/measuring-text.md) - Measuring text dimensions, fitting text to containers, and checking overflow
- - [rules/sequencing.md](rules/sequencing.md) - Sequencing patterns for Remotion - delay, trim, limit duration of items
- - [rules/tailwind.md](rules/tailwind.md) - Using TailwindCSS in Remotion
- - [rules/text-animations.md](rules/text-animations.md) - Typography and text animation patterns for Remotion
- - [rules/timing.md](rules/timing.md) - Interpolation curves in Remotion - linear, easing, spring animations
- - [rules/transcribe-captions.md](rules/transcribe-captions.md) - Transcribing audio to generate captions in Remotion
- - [rules/transitions.md](rules/transitions.md) - Scene transition patterns for Remotion
- - [rules/trimming.md](rules/trimming.md) - Trimming patterns for Remotion - cut the beginning or end of animations
- - [rules/videos.md](rules/videos.md) - Embedding videos in Remotion - trimming, volume, speed, looping, pitch
- - [rules/parameters.md](rules/parameters.md) - Make a video parametrizable by adding a Zod schema
- - [rules/maps.md](rules/maps.md) - Add a map using Mapbox and animate it
+ ```bash
+ npx create-video@latest --yes --blank --no-tailwind my-video
+ ```
+
+ Replace `my-video` with a suitable project name.
+
+ ## Designing a video
+
+ Before designing visual scenes, layouts, promos, motion graphics, or text-heavy videos, load [rules/video-layout.md](rules/video-layout.md) for video-first layout and text sizing guidance.
+
+ Animate properties using `useCurrentFrame()` and `interpolate()`. Prefer `interpolate()` over `spring()` unless physics-based motion is explicitly needed. Use `Easing.bezier()` to customize timing, including jumpy or overshooting motion.
+
+ For animations that should be editable in Remotion Studio, keep the `interpolate()` call inline in the `style` prop and use individual CSS transform properties (`scale`, `translate`, `rotate`) instead of composing a `transform` string.
+
+ ```tsx
+ import { useCurrentFrame, Easing, interpolate, useVideoConfig } 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>;
+ };
+ ```
+
+ Prefer:
+
+ ```tsx
+ style={{
+ scale: interpolate(frame, [0, 100], [0, 1]),
+ translate: interpolate(frame, [0, 100], ["0px 0px", "100px 100px"]),
+ rotate: interpolate(frame, [0, 100], ["20deg", "90deg"]),
+ }}
+ ```
+
+ Over:
+
+ ```tsx
+ const scale = interpolate(frame, [0, 100], [0, 1]);
+
+ style={{
+ transform: `scale(${scale})`,
+ }}
+ ```
+
+ 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:
+
+ ```tsx
+ 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`:
+
+ ```tsx
+ 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`:
+
+ ```tsx
+ 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:
+
+ ```tsx
+ 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"`.
+
+ ```tsx
+ 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`:
+
+ ```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:
+
+ ```tsx
+ 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:
+
+ ```bash
+ 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.
+
+ ```bash
+ 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](./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](./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](./rules/silence-detection.md) file.
+
+ ## Audio visualization
+
+ When needing to visualize audio (spectrum bars, waveforms, bass-reactive effects), load the [./rules/audio-visualization.md](./rules/audio-visualization.md) file for more information.
+
+ ## Sound effects
+
+ When needing to use sound effects, load the [./rules/sfx.md](./rules/sfx.md) file for more information.
+
+ ## Visual and pixel effects
+
+ When creating a visual effect, prefer: 1. normal Remotion/HTML/CSS/SVG/filter/blend/mask animation, 2. a listed effect via [rules/effects.md](rules/effects.md), including on HTML rendered through `<HtmlInCanvas>`, 3. a custom `createEffect()` via [rules/effects.md](rules/effects.md) when the user asks for a reusable/project-specific effect, 4. custom `<HtmlInCanvas onPaint>` via [rules/html-in-canvas.md](rules/html-in-canvas.md) only if no effect fits.
+
+ For light leak overlays, see [rules/light-leaks.md](rules/light-leaks.md). Docs: https://www.remotion.dev/docs/effects
+
+ Available effects: `brightness()`, `contrast()`, `colorKey()`, `duotone()`, `grayscale()`, `hue()`, `invert()`, `saturation()`, `tint()`, `linearGradient()`, `linearGradientTint()`, `thermalVision()`, `blur()`, `linearProgressiveBlur()`, `radialProgressiveBlur()`, `zoomBlur()`, `dropShadow()`, `glow()`, `lightTrail()`, `evolve()`, `venetianBlinds()`, `mirror()`, `scale()`, `uvTranslate()`, `xyTranslate()`, `barrelDistortion()`, `chromaticAberration()`, `fisheye()`, `cornerPin()`, `wave()`, `burlap()`, `emboss()`, `dotGrid()`, `halftone()`, `noise()`, `noiseDisplacement()`, `pattern()`, `pixelate()`, `pixelDissolve()`, `scanlines()`, `speckle()`, `shine()`, `shrinkwrap()`, `vignette()`, `contourLines()`, `checkerboard()`, `halftoneLinearGradient()`, `gridlines()`, `whiteNoise()`, `tvSignalOff()`, `lines()`, `rings()`, `waves()`, `zigzag()`, `lightLeak()`, `starburst()`.
+
+ ## 3D content
+
+ See [rules/3d.md](rules/3d.md) for 3D content in Remotion using Three.js and React Three Fiber.
+
+ ## Advanced audio
+
+ See [rules/audio.md](rules/audio.md) for advanced audio features like trimming, volume, speed, pitch.
+
+ ## Dynamic duration, dimensions and data
+
+ See [rules/calculate-metadata.md](rules/calculate-metadata.md) for dynamically set composition duration, dimensions, and props.
+
+ ## Advanced compositions
+
+ See [rules/compositions.md](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](rules/google-fonts.md) for how to load Google Fonts.
+
+ ## Local fonts
+
+ See [rules/local-fonts.md](rules/local-fonts.md) for how to load local fonts.
+
+ ## Getting audio duration
+
+ See [rules/get-audio-duration.md](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](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](rules/get-video-duration.md) for getting the duration of a video file in seconds with Mediabunny.
+
+ ## GIFs
+
+ See [rules/gifs.md](rules/gifs.md) for how to display GIFs synchronized with Remotion's timeline.
+
+ ## Advanced Images
+
+ See [rules/images.md](rules/images.md) for sizing and positioning images, dynamic image paths, and getting image dimensions.
+
+ ## Lottie animations
+
+ See [rules/lottie.md](rules/lottie.md) for embedding Lottie animations in Remotion.
+
+ ## Measuring DOM nodes
+
+ See [rules/measuring-dom-nodes.md](rules/measuring-dom-nodes.md) for measuring DOM element dimensions in Remotion.
+
+ ## Measuring text
+
+ See [rules/measuring-text.md](rules/measuring-text.md) for measuring text dimensions, fitting text to containers, and checking overflow.
+
+ ## Advanced sequencing
+
+ See [rules/sequencing.md](rules/sequencing.md) for more sequencing patterns - delay, trim, limit duration of items.
+
+ ## TailwindCSS
+
+ See [rules/tailwind.md](rules/tailwind.md) for using TailwindCSS in Remotion.
+
+ ## Text animations
+
+ See [rules/text-animations.md](rules/text-animations.md) for typography and text animation patterns.
+
+ ## Advanced timing
+
+ See [rules/timing.md](rules/timing.md) for advanced timing with `interpolate` and Bézier easing, and springs.
+
+ ## Transitions
+
+ See [rules/transitions.md](rules/transitions.md) for scene transition patterns.
+
+ ## Transparent videos
+
+ See [rules/transparent-videos.md](rules/transparent-videos.md) for rendering out a video with transparency.
+
+ ## Trimming
+
+ See [rules/trimming.md](rules/trimming.md) for trimming patterns - cutting the beginning or end of animations.
+
+ ## Advanced Videos
+
+ See [rules/videos.md](rules/videos.md) for advanced knowledge about embedding videos - trimming, volume, speed, looping, pitch.
+
+ ## Parameterized videos
+
+ See [rules/parameters.md](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](rules/maplibre.md)
+
+ ## Voiceover
+
+ See [rules/voiceover.md](rules/voiceover.md) for adding AI-generated voiceover to Remotion compositions using ElevenLabs TTS.