Compositions & Metadata
In Remotion, a composition is the fundamental unit of a video project. It defines the entry point, dimensions, frame rate, and duration of a renderable asset.
Defining Compositions
The <Composition /> component registers a React component as a video. These are typically defined in the src/Root.tsx file.
import { Composition } from "remotion";
import { MyVideoComponent } from "./MyVideoComponent";
export const RemotionRoot = () => {
return (
<Composition
id="MainVideo"
component={MyVideoComponent}
durationInFrames={300} // 10 seconds at 30fps
fps={30}
width={1920}
height={1080}
/>
);
};
Required Props
| Prop | Type | Description |
| :--- | :--- | :--- |
| id | string | A unique identifier for the composition, used during rendering. |
| component | React.ComponentType | The React component that renders the video content. |
| durationInFrames | number | The total length of the video in frames. |
| fps | number | Frames per second. |
| width | number | Width of the video in pixels. |
| height | number | Height of the video in pixels. |
Default Props and Type Safety
You can pass initial data to your components using the defaultProps attribute. This allows you to preview your video in the Remotion Studio with realistic data.
To ensure strict type safety, use type declarations instead of interface and the satisfies operator.
type MyVideoProps = {
title: string;
themeColor: string;
};
export const RemotionRoot = () => {
return (
<Composition
id="StyledVideo"
component={MyVideoComponent}
durationInFrames={120}
fps={30}
width={1080}
height={1080}
defaultProps={{
title: "Agent Board Demo",
themeColor: "#4f46e5",
} satisfies MyVideoProps}
/>
);
};
Note: Values must be JSON-serializable, though Remotion provides built-in support for Date, Map, Set, and staticFile().
Stills and Static Images
For single-frame assets like thumbnails or posters, use the <Still /> component. It shares the same interface as <Composition /> but omits durationInFrames and fps.
import { Still } from "remotion";
import { Thumbnail } from "./Thumbnail";
<Still
id="VideoThumbnail"
component={Thumbnail}
width={1280}
height={720}
/>
Organizing with Folders
As projects grow, use the <Folder /> component to group related compositions in the Remotion Studio sidebar. Folder names must be alphanumeric or contain hyphens.
import { Folder, Composition } from "remotion";
<Folder name="marketing-assets">
<Composition id="InstagramStory" ... />
<Composition id="YouTubeAd" ... />
</Folder>
Dynamic Metadata
The calculateMetadata function allows you to dynamically determine a composition's properties (duration, dimensions, or props) right before rendering begins. This is essential for videos that depend on external assets like variable-length audio or remote API data.
Usage Example: Syncing with Video Duration
import { CalculateMetadataFunction } from "remotion";
import { getMediaMetadata } from "./utils/media";
type Props = { videoSrc: string };
const calculateMetadata: CalculateMetadataFunction<Props> = async ({ props }) => {
const metadata = await getMediaMetadata(props.videoSrc);
return {
durationInFrames: Math.ceil(metadata.durationInSeconds * 30),
width: metadata.width,
height: metadata.height,
// You can also transform or inject new props
props: {
...props,
aspectRatio: metadata.width / metadata.height,
}
};
};
<Composition
id="DynamicPlayer"
component={VideoPlayer}
durationInFrames={1} // Placeholder, overridden by calculateMetadata
fps={30}
width={1920}
height={1080}
calculateMetadata={calculateMetadata}
defaultProps={{ videoSrc: "https://example.com/video.mp4" }}
/>
Handling External Requests
When fetching data within calculateMetadata, always use the provided abortSignal to ensure that stale requests are cancelled if the user changes props in the Studio.
const calculateMetadata: CalculateMetadataFunction<Props> = async ({ props, abortSignal }) => {
const response = await fetch(`https://api.data.com/v1/video/${props.id}`, {
signal: abortSignal
});
const data = await response.json();
return {
props: { ...props, data }
};
};
Overridable Fields
The object returned by calculateMetadata can contain:
durationInFrameswidth/heightfpsprops(Transformed version of input props)defaultOutName(The default filename when rendering)defaultCodec