Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Apply best practices for creating programmatic videos with Remotion and React
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
rules/compositions.md
1---2name: compositions3description: Defining compositions, stills, folders, default props and dynamic metadata4metadata:5tags: composition, still, folder, props, metadata6---78A `<Composition>` defines the component, width, height, fps and duration of a renderable video.910## Default Props1112Pass `defaultProps` to provide initial values for your component.13Values must be JSON-serializable (`Date`, `Map`, `Set`, and `staticFile()` are supported).1415```tsx16import { Composition } from "remotion";17import { MyComposition, MyCompositionProps } from "./MyComposition";1819export const RemotionRoot = () => {20return (21<Composition22id="MyComposition"23component={MyComposition}24durationInFrames={100}25fps={30}26width={1080}27height={1080}28defaultProps={29{30title: "Hello World",31color: "#ff0000",32} satisfies MyCompositionProps33}34/>35);36};37```3839Use `type` declarations for props rather than `interface` to ensure `defaultProps` type safety.4041## Folders4243Use `<Folder>` to organize compositions in the sidebar.44Folder names can only contain letters, numbers, and hyphens.4546```tsx47import { Composition, Folder } from "remotion";4849export const RemotionRoot = () => {50return (51<>52<Folder name="Marketing">53<Composition id="Promo" /* ... */ />54<Composition id="Ad" /* ... */ />55</Folder>56<Folder name="Social">57<Folder name="Instagram">58<Composition id="Story" /* ... */ />59<Composition id="Reel" /* ... */ />60</Folder>61</Folder>62</>63);64};65```6667## Stills6869Use `<Still>` for single-frame images. It does not require `durationInFrames` or `fps`.7071```tsx72import { Still } from "remotion";73import { Thumbnail } from "./Thumbnail";7475export const RemotionRoot = () => {76return (77<Still id="Thumbnail" component={Thumbnail} width={1280} height={720} />78);79};80```8182## Calculate Metadata8384Use `calculateMetadata` to make dimensions, duration, or props dynamic based on data.8586```tsx87import { Composition, CalculateMetadataFunction } from "remotion";88import { MyComposition, MyCompositionProps } from "./MyComposition";8990const calculateMetadata: CalculateMetadataFunction<91MyCompositionProps92> = async ({ props, abortSignal }) => {93const data = await fetch(`https://api.example.com/video/${props.videoId}`, {94signal: abortSignal,95}).then((res) => res.json());9697return {98durationInFrames: Math.ceil(data.duration * 30),99props: {100...props,101videoUrl: data.url,102},103};104};105106export const RemotionRoot = () => {107return (108<Composition109id="MyComposition"110component={MyComposition}111fps={30}112width={1080}113height={1080}114defaultProps={{ videoId: "abc123" }}115calculateMetadata={calculateMetadata}116/>117);118};119```120121The function can return `props`, `durationInFrames`, `width`, `height`, `fps`, and codec-related defaults. It runs once before rendering begins.122123## Nesting compositions within another124125To add a composition within another composition, you can use the `<Sequence>` component with a `width` and `height` prop to specify the size of the composition.126127```tsx128<AbsoluteFill>129<Sequence width={COMPOSITION_WIDTH} height={COMPOSITION_HEIGHT}>130<CompositionComponent />131</Sequence>132</AbsoluteFill>133```134