/remotion-markup
Content, animation and effects best practices
$ npx -y skills add guanyang/open-agent-hub --skill remotion-markup --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition β
- You can call itInvoke it directly when you want it.
- Slash command
/remotion-markup
Context preview
The summary Claude sees to decide when to auto-load this skill.
Content, animation and effects best practices
SKILL.md
remotion-markup.SKILL.mdname: remotion-markup
description: Content, animation and effects best practices
version: 4.0.507
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
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](../remotion-interactivity/SKILL.md)
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`.
// π 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')} />
</>
);
};Example scene
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
<Img from={1 * fps} {/* ... */}/>
<Video from={1 * fps} {/* ... */}/>
<Interactive.Div from={1 * fps} {/* ... */}/>When the element starts appearing in the timelien.
durationInFrames
<Img durationInFrames={20 * fps} {/* ... */}/>
<Interactive.Div durationInFrames={20 * fps} {/* ... */}/>For how long the layer plays in the timeline. For media, pass the natural duration of the media: `<Video durationInFrames={29.322 * fps}/>`
`trimBefore`
Useful for components whose internal clock should start later:
// Trim away first 2 seconds of footage
<Video trimBefore={2 * fps} {/* ... */} />
// `useCurrenFrame()` for children starts at `10 * fps`
<Sequence trimBefore={10 * fps} {/* ... */} />Fallback
If a component does not support these props, wrap it in`<Sequence>` from `remotion`, which has them.
- `layout="absolute-fill"` makes the Sequence behave like AbsoluteFill
- `layout="none"` is "headless" mode, no wrapper element is used.
Maps
See [Remotion Maps](./remotion-maps/REFERENCE.md) if wanting to
Read more
name: remotion-markup description: Content, animation and effects best practices version: 4.0.507
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
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](../remotion-interactivity/SKILL.md)
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`.
// π 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')} />
</>
);
};Example scene
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
<Img from={1 * fps} {/* ... */}/>
<Video from={1 * fps} {/* ... */}/>
<Interactive.Div from={1 * fps} {/* ... */}/>When the element starts appearing in the timelien.
durationInFrames
<Img durationInFrames={20 * fps} {/* ... */}/>
<Interactive.Div durationInFrames={20 * fps} {/* ... */}/>For how long the layer plays in the timeline. For media, pass the natural duration of the media: `<Video durationInFrames={29.322 * fps}/>`
`trimBefore`
Useful for components whose internal clock should start later:
// Trim away first 2 seconds of footage
<Video trimBefore={2 * fps} {/* ... */} />
// `useCurrenFrame()` for children starts at `10 * fps`
<Sequence trimBefore={10 * fps} {/* ... */} />Fallback
If a component does not support these props, wrap it in`<Sequence>` from `remotion`, which has them.
- `layout="absolute-fill"` makes the Sequence behave like AbsoluteFill
- `layout="none"` is "headless" mode, no wrapper element is used.
Maps
See [Remotion Maps](./remotion-maps/REFERENCE.md) if wanting to
A lightweight, zero-dependency CLI tool to manage and activate capabilities for AI coding assistants (such as Claude Code, Cursor, Trae, etc.).
Repo: guanyang/open-agent-hub
Other skills on open-agent-hub.
- /advanced-evaluation
This skill should be used for advanced LLM evaluation: LLM-as-judge systems, direct scoring, pairwise comparison, rubric calibration, evaluator bias mitigation, confidence scoring, and automated quality assessment.
Open skill - /algorithmic-art
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing
Open skill - /baoyu-article-illustrator
Analyzes article structure, identifies positions requiring visual aids, generates illustrations with Type Γ Style Γ Palette three-dimension approach. Use when user asks to "illustrate article", "add images", "generate images for article", or "δΈΊζη« ι εΎ".
Open skill - /baoyu-comic
Knowledge comic creator supporting multiple art styles and tones. Creates original educational comics with detailed panel layouts and batch-capable image generation. Use when user asks to create "η₯θ―ζΌ«η»", "ζθ²ζΌ«η»", "biography comic", "tutorial comic", or "Logicomix-style comic".
Open skill - /baoyu-compress-image
Compresses images to WebP (default) or PNG with automatic tool selection. Use when user asks to "compress image", "optimize image", "convert to webp", or reduce image file size.
Open skill - /baoyu-cover-image
Generates article cover images with 5 dimensions (type, palette, rendering, text, mood) combining 11 color palettes and 7 rendering styles. Supports cinematic (2.35:1), widescreen (16:9), and square (1:1) aspects. Use when user asks to "generate cover image", "create article
Open skill

