/remotion-markup
Content, animation and effects best practices
Claude Code
$ npx -y skills add remotion-dev/remotion --skill remotion-markup --agent claude-code
Codex
$ npx skills add remotion-dev/remotion --skill remotion-markup -a codex -y
Cursor
$ npx skills add remotion-dev/remotion --skill remotion-markup -a cursor -y
Gemini CLI
$ npx skills add remotion-dev/remotion --skill remotion-markup -a gemini-cli -y
GitHub Copilot
$ npx skills add remotion-dev/remotion --skill remotion-markup -a github-copilot -y
OpenCode
$ npx skills add remotion-dev/remotion --skill remotion-markup -a opencode -y
Windsurf
$ npx skills add remotion-dev/remotion --skill remotion-markup -a windsurf -y
SKILL.md
remotion-markup.SKILL.mdname: remotion-markup
description: Content, animation and effects best practices
version: 4.0.542
This is guidance for writing Remotion React Markup. If this is not relevant, load [Remotion Best Practices](../remotion-best-practices/SKILL.md) 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
Keep `useCurrentFrame()` in the smallest component that needs it. Extract frame-dependent audio volume, titles, and overlays into their own components instead of subscribing the whole composition or scene; otherwise unrelated descendants re-render on every frame. Preserve the existing frame coordinates when extracting across timing boundaries, and keep editable interpolations inline on the item's props.
Inside a composition or scene component, get `fps` from `useVideoConfig()` for all seconds-to-frames calculations, including timing props such as `from`, `trimBefore` and `durationInFrames`. Keeping the expression on the JSX node, such as `trimBefore={4 * fps}`, lets Studio edit the timing and keeps it correct if the composition frame rate changes.
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.
Before choosing the markup hierarchy, read [editable timeline structure](../remotion-interactivity/timeline-structure.md). Choose editing units first, then the tracks or shared timing boundaries they need. It includes a complete example with interactive components and their registrations. For source-editable styles, schemas, and keyframes, see [Remotion Interactivity](../remotion-interactivity/SKILL.md).
import { useCurrentFrame, useVideoConfig, Easing, interpolate, Interactive } from "remotion";
export const FadeIn = () => {
const frame = useCurrentFrame();
const {fps} = useVideoConfig();
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`.
// 👍 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:
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')} />
</>
);
};If the composition is primarily a timeline of video or audio clips, read [video-editing.md](video-editing.md) before choosing its source structure.
Delaying, trimming
Use [sequencing](sequencing.md) to choose the timing boundary and [timing props](timing-props.md) for the supported props and order of operations.
Maps
See [Remotion Maps](./remotion-maps/SKILL.md) if wanting to include maps in the video.
Text highlights and annotations
See [text-highlights.md](text-highlights.md) for text highlights (highlight markers), circles, underlines, strike-throughs, crossed-off text, boxes.
Multi-scene videos
See [multi-scene-video.md](multi-scene-video.md) if planning to make a video with multiple subsequent scenes.
Connected compositions
Read [connected compositions](connected-compositions.md) when a scene or group needs its own editable timeline, or when handling a Studio pre-compose request. It covers extraction, registration, inherited styles, and verification in both the parent and standalone views.
Voiceover
See [voiceover.md](voiceover.md) for adding an AI-generated voiceover to Remotion compositions using ElevenLabs TTS.
Embedding Videos
See [embedding-videos.md](embedding-videos.md) for advanced knowledge about embedding videos - trimming, volume, speed, looping, pitch.
Embedding Audio
See [audio.md](audio.md) for advanced audio features like trimming, volume, speed, pitch.
Cropping
See [cropping.md](cropping.md) if needing to crop the visible r
Read more
name: remotion-markup description: Content, animation and effects best practices version: 4.0.542
This is guidance for writing Remotion React Markup. If this is not relevant, load [Remotion Best Practices](../remotion-best-practices/SKILL.md) 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
Keep `useCurrentFrame()` in the smallest component that needs it. Extract frame-dependent audio volume, titles, and overlays into their own components instead of subscribing the whole composition or scene; otherwise unrelated descendants re-render on every frame. Preserve the existing frame coordinates when extracting across timing boundaries, and keep editable interpolations inline on the item's props.
Inside a composition or scene component, get `fps` from `useVideoConfig()` for all seconds-to-frames calculations, including timing props such as `from`, `trimBefore` and `durationInFrames`. Keeping the expression on the JSX node, such as `trimBefore={4 * fps}`, lets Studio edit the timing and keeps it correct if the composition frame rate changes.
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.
Before choosing the markup hierarchy, read [editable timeline structure](../remotion-interactivity/timeline-structure.md). Choose editing units first, then the tracks or shared timing boundaries they need. It includes a complete example with interactive components and their registrations. For source-editable styles, schemas, and keyframes, see [Remotion Interactivity](../remotion-interactivity/SKILL.md).
import { useCurrentFrame, useVideoConfig, Easing, interpolate, Interactive } from "remotion";
export const FadeIn = () => {
const frame = useCurrentFrame();
const {fps} = useVideoConfig();
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`.
// 👍 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:
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')} />
</>
);
};If the composition is primarily a timeline of video or audio clips, read [video-editing.md](video-editing.md) before choosing its source structure.
Delaying, trimming
Use [sequencing](sequencing.md) to choose the timing boundary and [timing props](timing-props.md) for the supported props and order of operations.
Maps
See [Remotion Maps](./remotion-maps/SKILL.md) if wanting to include maps in the video.
Text highlights and annotations
See [text-highlights.md](text-highlights.md) for text highlights (highlight markers), circles, underlines, strike-throughs, crossed-off text, boxes.
Multi-scene videos
See [multi-scene-video.md](multi-scene-video.md) if planning to make a video with multiple subsequent scenes.
Connected compositions
Read [connected compositions](connected-compositions.md) when a scene or group needs its own editable timeline, or when handling a Studio pre-compose request. It covers extraction, registration, inherited styles, and verification in both the parent and standalone views.
Voiceover
See [voiceover.md](voiceover.md) for adding an AI-generated voiceover to Remotion compositions using ElevenLabs TTS.
Embedding Videos
See [embedding-videos.md](embedding-videos.md) for advanced knowledge about embedding videos - trimming, volume, speed, looping, pitch.
Embedding Audio
See [audio.md](audio.md) for advanced audio features like trimming, volume, speed, pitch.
Cropping
See [cropping.md](cropping.md) if needing to crop the visible r
Other skills on remotion.
remotion-interactivity
Structures Remotion markup so layers, timing and styles are editable in Remotion Studio. Use when writing a new composition or…
More skills from other plugins.
captions-overlay
Overlay doctrine for captions in HyperFrames videos — the caption MODEL (drop / rail / embed) and the rule that captions are an…
acestep
AI music generation with ACE-Step 1.5 — background music, vocal tracks, covers, stem extraction for video production. Use when…
seedance-antislop
This skill should be used when a Seedance 2.0 prompt contains generic AI filler, hollow superlatives, vague cinematic language,…
Questions about remotion-markup.
- Which coding agents can use remotion-markup?
- remotion-markup installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

