skill

Remotion Markup

Content, animation and effects best practices

remotion-dev100,214+ installsVetted

About

This is guidance for writing Remotion React Markup. If this is not relevant, load Remotion Best Practices instead.

## Preserve user changes

Users may make edits in the code outside of the conversation.

If you detect a surprising change made in the meanwhile, don't overwrite it, assume it was intentional or ask for confirmation.

## General rules

Drive animations using `useCurrentFrame()` and `interpolate()`. CSS `transition` or `animation` will not render correctly, they need to refactored. Tailwind animation class will not render correctly, they need to be refactored.

Use `Easing.bezier()` and `Easing.spring()` to customize timing.

Structure your markup according to Remotion Interactivity Best Practices

```tsx import { useCurrentFrame, Easing, interpolate, Interactive } from "remotion";

export const FadeIn = () => { const frame = useCurrentFrame();

return ( <Interactive.Div name="Title" style={{ opacity: interpolate(frame, [0, 2 * fps], [0, 1], { extrapolateRight: "clamp", extrapolateLeft: "clamp", easing: Easing.bezier(0.16, 1, 0.3, 1), }), }} > Hello World! </Interactive.Div> ); }; ```

Keep the `interpolate()` call inline in the `style` prop. Use `scale`, `translate`, `rotate` CSS properties over `transform`.

```tsx // 👍 Inline editable keyframes and transform shorthands style={{ scale: interpolate(frame, [0, 100], [0, 1], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.spring({damping: 200}), output: 'perceptual-scale' // For `scale` animations, use "output: 'perceptual-scale'" }), translate: interpolate(frame, [0, 100], ["0px 0px", "100px 100px"], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.spring({damping: 200}), }), rotate: interpolate(frame, [0, 100], ["20deg", "90deg"], { extrapolateLeft: 'clamp', extrapolateRight: 'clamp', easing: Easing.spring({damping: 200}), }), }}

// 👎 Non-inline values and transform strings become harder to edit in Studio const scale = interpolate(frame, [0, 100], [0, 1]);

style={{ transform: `scale(${scale})`, }} ```

## Assets

Place assets in the `public/` folder at your project root. Use `staticFile()` to reference files from the `public/` folder.

## Media components

Add video and audio using `<Video>` and `<Audio>` from `@remotion/media`. Add images using the `<CanvasImage>` component. Add animated GIFs, APNG, WebP or AVIF images using `<AnimatedImage>`, use `@remotion/gif` if not using Chrome. Use `staticFile()` for files in `public/` or pass a remote URL directly:

```tsx import { Audio, Video } from "@remotion/media"; import { staticFile, CanvasImage, AnimatedImage } from "remotion";

export const MyComposition = () => { return ( <> <Video src={staticFile("video.mp4")} style={{ opacity: 0.5 }} /> <Audio src={staticFile("audio.mp3")} /> <CanvasImage src={staticFile("logo.png")} style={{ width: 100, height: 100 }} /> <Video src="https://remotion.media/video.mp4" /> <AnimatedImage src={staticFile('nyancat.gif')} /> </> ); }; ```

## Example scene

```tsx import { AbsoluteFill, Easing, Interactive, interpolate, useCurrentFrame, useVideoConfig } from "remotion";

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

return ( <AbsoluteFill name="Scene" style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', backgroundColor: 'white' }} > <Interactive.Div name="Title" style={{ opacity: interpolate(frame, [1 * fps, 2 * fps], [0, 1], { extrapolateRight: "clamp", extrapolateLeft: "clamp", easing: Easing.bezier(0.16, 1, 0.3, 1), }), fontSize: 88 }} > Title </Interactive.Div> <Interactive.Div name="Subtitle" style={{ opacity: interpolate(frame, [2 * fps, 3 * fps, 8 * fps, 10 * fps], [0, 1, 1, 0], { extrapolateRight: "clamp", extrapolateLeft: "clamp", easing: [Easing.bezier(0.16, 1, 0.3, 1), Easing.linear, Easing.bezier(0.16, 1, 0.3, 1)], }), fontSize: 32 }} > Subtitle </Interactive.Div> </AbsoluteFill> ); } ```

## Delaying, trimming

Most components (`<AbsoluteFill>`, `<Interactive.*>` `<Img>`, `<AnimatedImage>`, `<CanvasImage>`, `<HtmlInCanvas>`, `<Solid>`, `<Sequence>` from `remotion`, `<Video>` and `<Audio>` from `@remotion/media`, `<Gif>`, and more) support the following props:

### from

```tsx <Img from={1 * fps} {/* ... */}/> <Video from={1 * fps} {/* ... */}/> <Interactive.Div from={1 * fps} {/* ... */}/> ```

When the element starts appearing in the timelien.

### durationInFrames

```tsx <Img durationInFrames={20 * fps} {/* ... */}

Install

Run this command

npx skills add remotion-dev/skills

Works with

claude appclaude codeclaude apicursorcodexwindsurfclinezed

Manual steps

Install with `npx skills add remotion-dev/skills`, or clone the repository and copy the `skills/remotion-markup` folder into your Claude skills directory.

View source

Frequently asked questions

What is the Remotion Markup skill?

Content, animation and effects best practices

How do I install Remotion Markup?

Run this in your terminal:

npx skills add remotion-dev/skills
Which AI tools does Remotion Markup work with?

It works with claude_app, claude_code, claude_api, cursor, codex, windsurf, cline, zed.

Who made Remotion Markup?

remotion-dev.

Is Remotion Markup free?

Yes, it is free to use.

Related assets

More curated picks in Content Creation.

All Remotion Markup alternatives →

Audit before you install

Run any source through our checks - AI visibility, security, performance, and stack detection.

More in Content Creation