---
name: Remotion
slug: remotion
category: AI Engineering
description: Remotion makes videos from notes, articles, scripts, or product briefs and renders them to MP4. Use it when creating product demos, promos, trailers, explainers, motion graphics, or animated logos.
github: "https://github.com/zhuzhaoyun/Molio/tree/main/apps/daemon/src/tools/skills/remotion"
language: TypeScript
stars: 241
forks: 35
install: "npx degit https://github.com/zhuzhaoyun/Molio/tree/main/apps/daemon/src/tools/skills/remotion ~/.claude/skills/remotion"
installs_to: ~/.claude/skills/remotion
source_path: apps/daemon/src/tools/skills/remotion/SKILL.md
collection_size: 8
category_size: 2631
collection_url: "https://dirskills.com/collections/zhuzhaoyun/Molio"
added: 2026-09-02T05:22:04.253Z
last_synced: 2026-09-02T05:22:04.253Z
canonical_url: "https://dirskills.com/skills/remotion"
---

# Remotion

Remotion makes videos from notes, articles, scripts, or product briefs and renders them to MP4. Use it when creating product demos, promos, trailers, explainers, motion graphics, or animated logos.

**Install:**

```bash
npx degit https://github.com/zhuzhaoyun/Molio/tree/main/apps/daemon/src/tools/skills/remotion ~/.claude/skills/remotion
```

## README

## When to use

If the user only wants to caption existing footage, capture a website tour, or do a quick one-off motion graphic under 10s with no narration, a lighter workflow may fit better — but when in doubt, start here.

## Environment preflight (run before coding)

Before writing any video code, resolve these four things — they are the difference between a smooth render and a stuck one:

1. **Browser source.** Remotion downloads Chrome Headless Shell on first render by default (~150 MB from `storage.googleapis.com`, slow/unreachable in some regions). Instead, find the user's local Chrome/Edge and pass `--browser-executable`. See [rules/browser-executable.md](rules/browser-executable.md).
2. **Font strategy.** For Chinese/Japanese/Korean text, do NOT rely on system fonts — they will not exist on a headless render runner. Bundle the font in `public/` and load via `@font-face` + `staticFile()`. See [rules/cjk-fonts.md](rules/cjk-fonts.md). For Latin text, [rules/google-fonts.md](rules/google-fonts.md).
3. **Monorepo?** If the project lives inside an existing pnpm/yarn/npm workspace that already depends on React (e.g. an app with `@types/react@19`), Remotion v4's pinned `@types/react@18` will cause `'AbsoluteFill' cannot be used as a JSX component` type errors. See the "Monorepo setup" note under New project setup below.
4. **TTS provider (if voiceover).** `voiceover.md` defaults to ElevenLabs (paid, needs API key). For a free path — especially for Chinese — use `edge-tts` (Microsoft TTS CLI, no API key, good `zh-CN` voices). See [rules/voiceover.md](rules/voiceover.md).

## New project setup

When in an empty folder or workspace with no existing Remotion project, scaffold it into the Molio workspace directory (Molio 工作区，文件树扫描会跳过 `.molio`，不污染 vault 根；其 `node_modules`/`dist`/`out` 不会触发监听或扫描，避免 daemon FD 泄漏):

```bash
mkdir -p .molio/remotion
cd .molio/remotion
npx create-video@latest --yes --blank --no-tailwind <project-name>
```

Replace `<project-name>` with a suitable project name. The project and all its build artifacts (`node_modules`, `out/` rendered MP4s) stay under `.molio/remotion/`, invisible to the vault file-tree scan. If you need the final MP4 visible in the knowledge tree, copy it out of `.molio/remotion/<project>/out/` into the vault root after rendering.

### Monorepo setup

If you are adding the Remotion project inside an existing pnpm/yarn workspace (e.g. a `videos/<name>/` sub-folder of a larger monorepo):

1. Add the sub-folder to the workspace `packages` list in `pnpm-workspace.yaml` (pnpm) or the workspace globs, so `pnpm install` reaches it.
2. Remotion v4 depends on `@types/react@18`. If another workspace package pulls in `@types/react@19` (common — e.g. a Vite/Next app), TypeScript will throw `'AbsoluteFill' cannot be used as a JSX component` / `bigint not assignable to ReactNode`. Fix by pinning `@types/react` to v18 for the Remotion project — either with a `pnpm.overrides` entry in the workspace root, or by adding `@types/react@^18.2.0` as a direct devDependency of the Remotion project so its local `node_modules/@types/react` wins over the hoisted v19.
3. Render with the local Chrome/Edge (see preflight #1) — do not let it download Chrome Headless Shell on a CI/worker machine that may already have a browser.

## 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
```

Studio runs in your own browser and does not need Chrome Headless Shell. Render/still commands DO — pass `--browser-executable` to reuse your local Chrome/Edge instead of triggering a ~150 MB download (see [rules/browser-executable.md](rules/browser-executable.md)).

## 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 \
  --browser-executable="/c/Program Files/Google/Chrome/Application/chrome.exe"
```

At 30 fps, `--frame=30` is the one-second mark (`--frame` is zero-based). The `--browser-executable` flag reuses your local Chrome so the first render doesn't stall downloading Chrome Headless Shell.

## 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()`, `paper()`, `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 **Latin** fonts in Remotion. See [rules/google-fonts.md](rules/google-fonts.md) for how to load Google Fonts.

For **Chinese / Japanese / Korean** text, system fonts are not safe (the headless render runner may not have PingFang/YaHei). Bundle the CJK font file in `public/` and load via `@font-face` + `staticFile()`. See [rules/cjk-fonts.md](rules/cjk-fonts.md).

## 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.
