Produce videos in React with Remotion
Tags: javascript, webdev, react, remotion
Published: 2022-08-02 21:39:36

by [Isaac Okoro](https://blog.openreplay.com/authors/isaac-okoro)

React is a beautiful Javascript framework and has sometimes been described as a "Learn Once, build anything" library. This case is true because the knowledge of React components can be used to develop anything from SPA to MPAs and everything in between. The same also goes for graphics and animations. 

In this article, we will learn how to use React components to build and create Videos using [Remotion](https://www.remotion.dev/). A demo of what we will be building is below:

![1](https://blog.openreplay.com/e231edec1b77b59034d1df7b3927ce59/image01.gif)


## What is Remotion?

[Remotion](https://www.remotion.dev/) is a library suite for programmatically producing videos using React. Remotion enables the creation of actual MP4 videos written in React. It uses web technologies such as CSS, SVG, and WebGL to create fascinating motion graphics. Remotion also allows you to use concepts like functions and variables. You can use JavaScript code to produce video and subsequently render it into an MP4 file with Remotion.

Remotion was created by [Jonny Burger](https://github.com/JonnyBurger) to allow anyone with minimal understanding of React, HTML, CSS, and Javascript the ability to create videos with code. Remotion lowers the barrier into the field of video creation by doing away with the complicated tools and training needed to thrive in the video creation field. Remotion does this by leveraging Javascript developers' current tools and allowing them to use those tools and skills to turn code into animations and videos.

Remotion includes a player called Remotion Player, which simulates the experience of an actual video editor and can be used to play and review your video on your browser.

## Getting started

You will need to install two dependencies to use Remotion effectively: [Node](https://nodejs.org/en/download/) and [FFmpeg](https://github.com/adaptlearning/adapt_authoring/wiki/Installing-FFmpeg). If you are planning on downloading or extracting your video after creation, you need FFmpeg; otherwise, you can choose not to install it. Once you install the dependencies, run the command below in your terminal to bootstrap a new Remotion app.

```
npm init video
# or 
yarn create video
```

You should see a prompt like below to choose a template for your application:

![2](https://blog.openreplay.com/static/a1ceb6f243dce190dacaed2388865bca/6a6ab/image02.png)

You can choose whichever template you want for the given list in the terminal, but for this article, I will use the blank template and explain as we go.

Once Remotion is installed, open it in the code editor of your choice, and let's go over the created files.

![3](https://blog.openreplay.com/static/1060507f75fca90a1f105221c1aefee8/af2bd/image03.png)

There are three files that we see in the `src` folder. the `index.tsx`, the `Video.tsx`, and the `Composition.tsx`

- The `index.tsx` file acts like the `index.js` file in a create-react-app (CRA) application. It takes a React component and, via a render function, outputs it as an mp4 video. We won't be modifying anything in this file
- The `Video.tsx` file acts like the `App` component in a React application, which means that it serves as the application's entry point. In this component, we will stitch together different compositions to create the video. The Video.tsx file shows us the first Remotion component, the `Composition`.
- The `Composition.tsx` is a component that holds and registers the videos that we want to render as well as the stylings and the props for the video

Inside the `Composition.tsx` file, we see the code below, which shows that we are currently returning nothing:

```javascript
export const MyComposition = () => {
  return null;
};
```
Inside the `Video.tsx` file, we see the code block below:

```javascript
import {Composition} from 'remotion';
import {MyComposition} from './Composition';
export const RemotionVideo: React.FC = () => {
  return (
    <>
      <Composition
        id="MyComp"
        component={MyComposition}
        durationInFrames={60}
        fps={30}
        width={1280}
        height={720}
      />
    </>
  );
};
```

- The `id` is used when you want to export the video, and we will get into what it does in the [exporting the video](https://www.dropbox.com/scl/fi/t2g1zrsyhfj5m9pioslgw/Untitled-7.paper?dl=0&rlkey=06w1aeocalfdf3qpuugqa9omr#:uid=846526813490374854414472&h2=Exporting-the-video) section.
- The `Component` takes the imported `Composition` component.
- The `durationInFrames` is the number of frames to be generated.
- The `fps` is the rate of the frame per second. The `durationInFrames` divided by the `fps` is used to calculate the length of the video. 
- The `width` is the width of the video in pixels
- The `height` is the height of the video in pixels

When we run `yarn start` to start up the development server, we see a 2-second long video of an empty canvas on `localhost:3000` - not very interesting, for sure!

## Creating our video

To get started, navigate to the `Composition.tsx` file and add the code below:

```javascript
export const MyComposition = () => {
  return (
    <div
      style={{
        width: '100%',
        height: '100%',
        backgroundColor: '#f2511b',
        color: '#fff',
        textAlign: 'center',
        alignItems: 'center',
        justifyContent: 'center',
        fontSize: '2rem',
      }}
    >
      <h1>
        My name is Isaac Okoro. A fullstack developer and technical writer for the OpenReplay blog
      </h1>

    </div>
  );
};
```    

The code above is pretty basic as we have a `div` with some inline styles and an `h1` tag with some content.

When we save and navigate to the browser, we should see a video that looks like the gif below:

![4](https://blog.openreplay.com/5900dda9b98f9788470e665f806d86ff/image04.gif)


## Getting properties

We will use a hook from Remotion to get the properties of our video. The hook is [useVideoConfig()](https://www.remotion.dev/docs/use-video-config#:~:text=Namely%2C%20useVideoConfig%20will%20return%20an,composition%2C%20in%20frames%20per%20seconds.). That hook retrieves returns an object with information about the context of the video that we are making. The properties contained in the object include width, height, fps, durationInFrames, etc.

We will use the information exposed to us by the `useVideoConfig()` hook to render the properties of our video.

```javascript
import { useVideoConfig } from 'remotion';
export const MyComposition = () => {
  const {width, height, fps, durationInFrames} = useVideoConfig();

  return (
    <div
      style={{
        width: '100%',
        height: '100%',
        backgroundColor: '#f2511b',
        color: '#fff',
        textAlign: 'center',
        alignItems: 'center',
        justifyContent: 'center',
        fontSize: '2rem',
      }}
    >
      <h1>
        My name is Isaac Okoro. A fullstack developer and technical writer for the OpenReplay blog
      </h1>
      <h3>
      This {width} * {height}px video is {durationInFrames / fps}secs long and
      was made to showcase Remotion
      </h3> 
    </div>
  );
};
```    

In the code block above, we imported the `useVideoConfig()` hook from Remotion. Next, we got the information about the video from the hook and rendered it. 

When we save and navigate to the browser, we should see a video that looks like the gif below:

![5](https://blog.openreplay.com/41ef083b7958c4cf615da4de354e315b/image05.gif)

**Note**: We are getting 2 seconds as our time because we didn't change the number of the `durationInFrames` in the `Video.tsx` file. Navigate to the `Video.tsx` file and change the number of the `durationInFrames` to 120 as shown below to get 4 secs:

```javascript
durationInFrames={120}
```

## Adding opacity

In the demo gif, we see that the screen starts dark and gets progressively brighter as the video continues. We will implement that feature in this section.

To do that, we will need to know the current frame of the video at every point in time. Thankfully, Remotion gives us a hook for that known as the `[useCurrentFrame()](https://www.remotion.dev/docs/use-current-frame)` hook. This hook retrieves the current frame of the video.

```javascript
import { useVideoConfig, useCurrentFrame } from 'remotion';

export const MyComposition = () => {
  const {width, height, fps, durationInFrames} = useVideoConfig();
  const frame = useCurrentFrame();
  const opacity = frame / durationInFrames;
  return (
    <div
      style={{
          // Inline styles remain the same
        opacity,
      }}
    >
      // Nothing changes here
    </div>
  );
};
```    

In the code block above, we imported the `useCurrentFrame()` hook and stored it in a frame variable. Next, we created an `opacity` variable, the `frame` variable divided by the `durationInFrames`. After that, we passed the opacity to the inline styles.

Save the file and view the results in the browser, which should look like the gif below:

![6 User-uploaded image: chrome-capture-2022-6-16.gif](./images/image06.gif)


## Open Source Session Replay

_[OpenReplay](https://github.com/openreplay/openreplay) is an open-source, session replay suite that lets you see what users do on your web app, helping you troubleshoot issues faster. OpenReplay is self-hosted for full control over your data._

![replayer.png](https://static.openreplay.com/images/banner-blog.png)

_Start enjoying your debugging experience - [start using OpenReplay for free](https://github.com/openreplay/openreplay)._


   
## Exporting the video

When rendering your video, make use that the `id` in the `video.tsx` file matches exactly with the title in the build section of your scripts. I changed the name of my `id` to "MyVideo" and also changed it in the build section of my script to "MyVideo" as shown in the images below:

![7](https://blog.openreplay.com/static/f568813e112489dc40ce94fe5b888b72/b8382/image07.png)

![8](https://blog.openreplay.com/static/9d47f71115c0cab5548b78027a0fd8b5/89c9d/image08.png)

With that done, run `yarn build` to export your video, and you should be presented with the image below:

![9](https://blog.openreplay.com/static/bcdebaa8c59bb074181d7c47d1c62c69/7753b/image09.png)

A link to the video on Github can be found [here](https://github.com/IsaacThaJunior/working-with-remotion/blob/main/out/video.mp4), and the complete code for this tutorial can be found [here](https://github.com/IsaacThaJunior/working-with-remotion).


## Conclusion

This article has covered Remotion and some of its amazing features. Remotion is still relatively new, but there are pleasant surprises ahead. Remotion also comes with standard features like data fetching and Server-side Rendering capabilities. Feel free to check out the Remotion Docs [here](https://www.remotion.dev/blog) and expand on the features found in this article.


[![newsletter](https://blog.openreplay.com/static/e6b18eda7a327511296a2f27692f9c70/e9957/newsletter.png)](https://newsletter.openreplay.com/)