> Markdown version of [/magazine/742-create-videos-programmatically-with-react-and-remotion](https://www.wearedevelopers.com/magazine/742-create-videos-programmatically-with-react-and-remotion). Every page supports `.md` or `Accept: text/markdown`. Links point to the HTML versions so they work for humans too. Agent guide: [/agents.md](https://www.wearedevelopers.com/agents.md). --- # Create Videos Programmatically with React and Remotion **By:** [Daniel Cranney](https://www.wearedevelopers.com/@daniel-cranney) **Published:** June 26, 2026 In a recent article, we looked at [how easy it is to clone your voice using Elevenlabs and Node.js](/magazine/739-clone-your-voice-with-elevenlabs-llms-and-node), so this time we thought we’d take a look at how to create videos programmatically, too. In a future article, we’ll piece it all together and combine multiple programmatically-generated videos with a voiceover, as well as a few custom animations, but for now let’s take a look at how to get started. For this, we’re going to use [Remotion](https://www.remotion.dev/), a library that lets you build videos as React components (with props making it easy to pass in dynamic data, and hooks great for handling complex state), preview in a light UI - called Remotion Studio - and then render out from there, too (or the CLI). ## Set up the project To get started, create a directory, initialise it and install Remotion alongside React and TypeScript, for type safety. Note that we install the core `remotion` library, along with `@remotion/cli` so we can run `preview` and `render` later on: mkdir remotion-demo && cd remotion-demo npm init -y npm install remotion @remotion/cli react react-dom npm install -D typescript @types/react @types/react-dom Let’s run `npx tsc --init` to create a `tsconfig.json` file, so we get auto-complete, type-checking and the other benefits of Typescript. ## Create your first composition Every Remotion project starts from a “Root” file that registers one or more **Compositions** , which are React components that include props like width, height, frame rate, and duration in frames. So, in `src/index.ts`, we import `registerRoot`, and pass it our `./Root` path imported as `Root`. import {registerRoot} from 'remotion'; import {Root} from './Root'; registerRoot(Root); Next, in `src/Root.tsx`, where the composition is registered, we create a `<Composition>`, and pass in those props we mentioned: import React from 'react'; import {Composition} from 'remotion'; import {Shapes} from './Shapes'; export const Root: React.FC = () => { return ( <Composition id="Shapes" component={Shapes} width={1280} height={720} fps={30} durationInFrames={150} /> ); }; Here, we’re making a 5 second-long video, with 30 frames per-second, so 150 frames in total. You’ll notice we’re passing in a `<Shapes>` component, which doesn’t actually exist yet, so let’s create it now. ## Build the Shapes component In `src/Shapes.tsx`, we’ll place three different animating shapes that we’ll create in a moment, and stagger them with `<Sequence>` so they appear one after another instead, using the `from` keyword to say the frame position we want each respective animation to start from: import {AbsoluteFill, Sequence} from 'remotion'; export const Shapes: React.FC = () => { return ( <AbsoluteFill style={{backgroundColor: '#15161D'}}> <Sequence from={0}><FadeCircle /></Sequence> <Sequence from={30}><SlideSquare /></Sequence> <Sequence from={60}><RotateTriangle /></Sequence> </AbsoluteFill> ); }; As a little tip, if you find frames a little confusing and would rather work in seconds, just pass in the number of seconds multiplied by the frame rate, for example `for={4*30}` will start the animation from the 4-second mark. ## Animate something on screen Now let’s create our animating shapes. For this example, we’re going to create the `<FadeCircle>` component, create an `opacity` variable where we animate `opacity` from 0 to 1 across the first 30 frames. Then, with `extrapolateRight: 'clamp'` we stop our animation when it gets to 1 and holds it there. The `opacity` const then gets passed in as the style for our `<div>`: const FadeCircle: React.FC = () => { const frame = useCurrentFrame(); const opacity = interpolate(frame, [0, 30], [0, 1], {extrapolateRight: 'clamp'}); return <div style={{width: 150, height: 150, borderRadius: '50%', backgroundColor: '#4C6EF5', opacity}} />; }; Now we won’t dig into the code for other two, but you can see how they animate down below, with `interpolate` driving a different CSS property over a frame range, so the concept stays the same. ## Preview and Render Finally, if we’re using the CLI, let’s add a script to our `package.json`’s `scripts`, to make it easy to switch between Remotion studio, and rendering from the command line (which also skips over needing to select output options like you do in the UI): { "scripts": { "start": "remotion studio", "render": "remotion render src/index.ts Shapes out/video.mp4" } } If you want to take a look at a live and scrubbable preview - with hot load - lets run `npm run start`, and when we’re done let’s run `npm run render` to output our chosen file. * * * We really enjoyed working with Remotion, and we’re pretty sure any React developers are going to find this incredibly easy to pick up, too. We hope you enjoyed this article, and be sure to let us know what you think on socials! ## Related Articles - [What Developers Really Need to Create Great Code Demos](https://www.wearedevelopers.com/magazine/658-what-developers-really-need-to-create-great-code-demos) - [Clone Your Voice with ElevenLabs LLMs and Node](https://www.wearedevelopers.com/magazine/739-clone-your-voice-with-elevenlabs-llms-and-node) - [HTML Media Elements and How to Use Them: <video> and <audio>](https://www.wearedevelopers.com/magazine/668-html-media-elements-and-how-to-use-them-video-and-audio) - [View Transition API: Adding Single-Page Transitions With Just HTML, CSS and JS](https://www.wearedevelopers.com/magazine/632-view-transition-api-adding-single-page-transitions-with-just-html-css-and-js) ## Related Videos - [Building Better Apps with React Native](https://www.wearedevelopers.com/videos/1466-building-better-apps-with-react-native) - [JSX to Live Activity: The Story of Voltra](https://www.wearedevelopers.com/videos/100118-jsx-to-live-activity-the-story-of-voltra) - [Hands-on React Native: From Zero to Hero](https://www.wearedevelopers.com/videos/277-hands-on-react-native-from-zero-to-hero) - [Practice makes perfect - when it comes to RxJS](https://www.wearedevelopers.com/videos/1-practice-makes-perfect-when-it-comes-to-rxjs) ## Related Jobs - [Junior Frontend Engineer](https://www.wearedevelopers.com/jobs/ext/1532351-junior-frontend-engineer) at **Almedia** - [Senior Software Engineer, React (Websites & Martech)](https://www.wearedevelopers.com/jobs/ext/1605272-senior-software-engineer-react-websites-martech) at **Bitpanda** - [Senior React Native Developer](https://www.wearedevelopers.com/jobs/ext/1518176-senior-react-native-developer) at **Almedia** - [Senior Software Engineer, React (Investing & Trading)](https://www.wearedevelopers.com/jobs/ext/1937625-senior-software-engineer-react-investing-trading) at **Bitpanda** - [Senior Full Stack Engineer](https://www.wearedevelopers.com/jobs/48289-senior-full-stack-engineer) at **Sensory-Minds GmbH** - [Software Engineer](https://www.wearedevelopers.com/jobs/ext/1304673-software-engineer) at **Bitpanda**