/remotion-markup
Content, animation and effects best practices
Claude Code
$ npx -y skills add remotion-dev/skills --skill remotion-markup --agent claude-code
Codex
$ npx skills add remotion-dev/skills --skill remotion-markup -a codex -y
Cursor
$ npx skills add remotion-dev/skills --skill remotion-markup -a cursor -y
Gemini CLI
$ npx skills add remotion-dev/skills --skill remotion-markup -a gemini-cli -y
GitHub Copilot
$ npx skills add remotion-dev/skills --skill remotion-markup -a github-copilot -y
OpenCode
$ npx skills add remotion-dev/skills --skill remotion-markup -a opencode -y
Windsurf
$ npx skills add remotion-dev/skills --skill remotion-markup -a windsurf -y
SKILL.md
remotion-markup.SKILL.mdname: remotion-markup
description: Content, animation and effects best practices
version: 4.0.543
This is guidance for writing Remotion React Markup. If this is not relevant, load Remotion Best Practices (`remotion-best-practices` skill) 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 (`timeline-structure.md` in the `remotion-interactivity` skill). 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).
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/REFERENCE.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 vi
Read more
name: remotion-markup description: Content, animation and effects best practices version: 4.0.543
This is guidance for writing Remotion React Markup. If this is not relevant, load Remotion Best Practices (`remotion-best-practices` skill) 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 (`timeline-structure.md` in the `remotion-interactivity` skill). 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).
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/REFERENCE.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 vi
Remotion maintains a list of Agent Skills that define best practices for working in Remotion projects. These skills are useful for AI agents like Claude Code, Codex, Kimi Code or Cursor.
Other skills on skills.
remotion-license
Find Remotion license information, FAQs, terms, and where to buy a license.
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.

