Render videos from JSON scene definitions. Define compositions, sequences, elements, and keyframe animations as a JSON DSL — get an MP4. Designed for LLM-driven video generation.
- Node.js 18+
- ffmpeg (
brew install ffmpeg)
cd ~/tools/remotion-cli
npm install
npm link # makes `remotion-cli` globally availableremotion-cli render scene.json # → output.mp4
remotion-cli render scene.json -o my-video.mp4 # custom output path
remotion-cli render scene.json --crf 15 # higher quality (lower = better, default 18)A scene file defines a video composition:
{
"fps": 30,
"width": 1920,
"height": 1080,
"background": "#000000",
"sequences": [
{
"duration": 3,
"background": "#1a1a2e",
"elements": [
{
"type": "text",
"text": "Hello World",
"x": "center",
"y": 400,
"width": 800,
"style": { "fontSize": 64, "color": "#ffffff", "textAlign": "center" },
"keyframes": {
"0%": { "opacity": 0, "y": 50 },
"30%": { "opacity": 1, "y": 0 },
"100%": { "opacity": 1, "y": 0 }
},
"easing": "easeOut"
}
]
}
]
}| Field | Type | Default | Description |
|---|---|---|---|
fps |
number | 30 | Frames per second |
width |
number | 1920 | Width in pixels |
height |
number | 1080 | Height in pixels |
background |
string | "#000000" | Background color |
audio |
AudioTrack[] | [] | Global audio tracks |
sequences |
Sequence[] | required | Time segments played in order |
Each sequence has a duration and contains elements that render during that time window.
| Field | Type | Default | Description |
|---|---|---|---|
duration |
number | required | Duration in seconds |
background |
string | transparent | Background color |
elements |
Element[] | required | Visual elements (array order = z-order) |
transition |
Transition | none | Transition from previous sequence |
All elements share common positioning/animation properties:
| Field | Type | Default | Description |
|---|---|---|---|
x, y |
number/string | 0 | Position: pixels, "center", or "50%" |
width, height |
number/string | auto | Size: pixels, "100%", or "auto" |
keyframes |
object | none | Animation keyframes |
easing |
string | "linear" | Easing function |
delay |
number | 0 | Appear after N seconds |
duration |
number | auto | Visible for N seconds |
style |
object | {} | CSS styles (React camelCase) |
{ "type": "text", "text": "Hello", "style": { "fontSize": 64, "color": "#fff" } }{ "type": "box", "width": 400, "height": 300, "style": { "backgroundColor": "#e94560", "borderRadius": 16 } }{ "type": "image", "src": "./logo.png", "width": 200, "fit": "contain" }{ "type": "video", "src": "./clip.mp4", "width": "100%", "height": "100%", "fit": "cover", "trim": { "start": 2, "end": 5 } }Animate properties over the sequence duration using percentage keys:
{
"keyframes": {
"0%": { "opacity": 0, "scale": 0.8, "y": 50 },
"30%": { "opacity": 1, "scale": 1, "y": 0 },
"100%": { "opacity": 1, "scale": 1, "y": 0 }
}
}Animatable properties: x, y, opacity, scale, scaleX, scaleY, rotation, width, height, color, backgroundColor, borderRadius, fontSize
Easing options: linear, easeIn, easeOut, easeInOut, spring
{ "src": "./music.mp3", "volume": 0.5, "startFrom": 2, "loop": true }{ "type": "fade", "duration": 0.5 }Types: fade, slide-left, slide-right, slide-up, slide-down
- Reads the JSON scene file
- Resolves relative asset paths (images, videos, audio) relative to the JSON file
- Bundles a Remotion project with the scene data injected via webpack DefinePlugin
- Uses Remotion's Node API to render frames via headless Chrome
- Encodes to H.264 MP4 via ffmpeg
Built on Remotion.