Skip to main content

Code sharing

If you are using the player, a common desire is to share the code with your Remotion Preview and/or server-side rendering. With the correct setup, you can write the component once and use it for previewing, displaying and rendering.

note

Remotion and your React app use a different Webpack config. Therefore, if you want to override your Webpack configuration, you need to override both the Remotion one and the React app one.

Setup

Set up a React project with your preferred setup, such as Create React App or Next.JS.

When your project is setup, add the necessary Remotion dependencies:

bash
npm i remotion @remotion/cli @remotion/player
bash
npm i remotion @remotion/cli @remotion/player

Afterwards, create a subfolder for Remotion within your project and add three files: An index file, a Root.tsx file for your list of compositions, and a file with your composition. It could look like this:

diff
└── src/
+ ├── remotion/
+ │ ├── index.ts
+ │ ├── MyComp.tsx
+ │ └── Root.tsx
└── app/
└── App.tsx
diff
└── src/
+ ├── remotion/
+ │ ├── index.ts
+ │ ├── MyComp.tsx
+ │ └── Root.tsx
└── app/
└── App.tsx

Your composition (remotion/MyComp.tsx in the example) could look for example like this:

tsx
export const MyComp: React.FC<{ text: string }> = ({ text }) => {
return <div>Hello {text}!</div>;
};
tsx
export const MyComp: React.FC<{ text: string }> = ({ text }) => {
return <div>Hello {text}!</div>;
};

Your list of videos (remotion/Root.tsx in the example) could look like this:

tsx
import { Composition } from "remotion";
import { MyComp } from "./MyComp";
 
export const MyVideo = () => {
return (
<>
<Composition
component={MyComp}
durationInFrames={120}
width={1920}
height={1080}
fps={30}
id="my-comp"
defaultProps={{ text: "World" }}
/>
</>
);
};
tsx
import { Composition } from "remotion";
import { MyComp } from "./MyComp";
 
export const MyVideo = () => {
return (
<>
<Composition
component={MyComp}
durationInFrames={120}
width={1920}
height={1080}
fps={30}
id="my-comp"
defaultProps={{ text: "World" }}
/>
</>
);
};

Your index file (remotion/index.ts in the example) could look like this:

tsx
import { registerRoot } from "remotion";
import { MyVideo } from "./Video";
 
registerRoot(MyVideo);
tsx
import { registerRoot } from "remotion";
import { MyVideo } from "./Video";
 
registerRoot(MyVideo);
tip

Don't move these statements together into one file, as you might break hot reloading.

Using Remotion Preview

You can open the Remotion Preview using the npx remotion preview command:

bash
npx remotion preview src/remotion/index.ts
bash
npx remotion preview src/remotion/index.ts

We recommend adding a new script into your package.json for easy access:

diff
"scripts": {
+ "video": "remotion preview src/remotion/index.ts"
}
diff
"scripts": {
+ "video": "remotion preview src/remotion/index.ts"
}

Adding <Player /> to your app

Anywhere in your app, import the <Player /> component and your Composition component.

tsx
import { Player } from "@remotion/player";
import { MyComp } from "./remotion/MyComp";
 
export const App: React.FC = () => {
return (
<Player
component={MyComp}
inputProps={{ text: "World" }}
durationInFrames={120}
compositionWidth={1920}
compositionHeight={1080}
fps={30}
style={{
width: 1280,
height: 720,
}}
controls
/>
);
};
tsx
import { Player } from "@remotion/player";
import { MyComp } from "./remotion/MyComp";
 
export const App: React.FC = () => {
return (
<Player
component={MyComp}
inputProps={{ text: "World" }}
durationInFrames={120}
compositionWidth={1920}
compositionHeight={1080}
fps={30}
style={{
width: 1280,
height: 720,
}}
controls
/>
);
};
note

Pass your React component directly to the component prop. Don't pass the list of compositions.

If everything worked, you can now run your webapp and preview your video.

Creating a bundle for server-side rendering

In any Node.JS context, you can call bundle() to bundle your video using Webpack and to server-side render the video. You need to add @remotion/bundler to your package.json for this.

server.tsx
ts
import path from "path";
import { bundle } from "@remotion/bundler";
 
const bundled = await bundle(
path.join(process.cwd(), "src", "remotion", "index.ts")
);
server.tsx
ts
import path from "path";
import { bundle } from "@remotion/bundler";
 
const bundled = await bundle(
path.join(process.cwd(), "src", "remotion", "index.ts")
);

See Server-side rendering for a full example.

tip

When using Lambda, you don't need this, you can use the CLI or deploySite() which will bundle the video for you.

See also