remotion-server

Installation
SKILL.md

Remotion Server

Render videos headlessly on any Linux server using Remotion v4 (latest: v4.0.435). No Mac or GUI required. Chrome Headless Shell handles all rendering - works on VPS, Raspberry Pi, CI runners, Docker containers, anywhere Node.js runs. FFmpeg is baked into each Remotion project - no separate FFmpeg install needed.

Setup (one-time)

Install browser dependencies for Chrome Headless Shell:

bash {baseDir}/scripts/setup.sh

This installs system libraries (libnss3, libatk, libgbm, libcups2, etc.) required by Chrome on headless Linux. Supports Ubuntu 22.04/24.04, Debian, and Amazon Linux.

Verify setup

After setup, confirm Chrome Headless Shell works:

npx @remotion/chrome-headless-shell --help

If this fails, the system dependencies are missing. Re-run setup.sh or install manually:

# Ubuntu/Debian
sudo apt install -y libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libgbm1 \
  libpango-1.0-0 libcairo2 libxcomposite1 libxdamage1 libxfixes3 libxrandr2

# Amazon Linux
sudo yum install -y mesa-libgbm libX11 libXrandr libdrm libXdamage libXfixes \
  libxkbcommon dbus-libs libXcomposite alsa-lib nss pango cups-libs at-spi2-core atk

Quick Start

Create a project

bash {baseDir}/scripts/create.sh my-video
cd my-video

Render a video

npx remotion render MyComp out/video.mp4

Preview in browser (dev mode)

npx remotion preview

Opens a local dev server where you can scrub through the video timeline, adjust props, and iterate before rendering.

Rendering Options (5 ways to render)

Remotion v4 offers five rendering backends. Choose based on your infrastructure and scale.

1. Local CLI (default)

Render on the machine where Node.js runs. Best for development, CI, and single-server deployments.

npx remotion render MyComp out/video.mp4

2. Remotion Lambda

Distribute rendering across AWS Lambda functions. Renders up to ~80 minutes of Full HD video. Supports webhooks for async notifications and built-in cost estimation.

npm install @remotion/lambda

# Deploy Lambda function
npx remotion lambda functions deploy

# Render on Lambda
npx remotion lambda render MyComp

# Estimate cost before rendering
npx remotion lambda still --estimate-price MyComp

Key features:

  • Distributed rendering across multiple Lambda invocations
  • Webhook callbacks on render completion
  • Cost estimation before rendering
  • S3 output storage

See https://www.remotion.dev/docs/lambda

3. @remotion/vercel (NEW - Feb 2026)

Render inside Vercel Sandboxes. Simplest setup - no AWS account needed.

npm install @remotion/vercel

Deploy your Remotion project to Vercel and trigger renders via API. Best for teams already on Vercel who want zero-config rendering.

See https://www.remotion.dev/docs/vercel

4. Cloud Run (alpha)

Render on Google Cloud Run. Lower compute costs than Lambda for longer videos.

npm install @remotion/cloudrun
npx remotion cloudrun render MyComp

See https://www.remotion.dev/docs/cloudrun

5. GPU rendering on EC2 (v4.0.248+)

Hardware-accelerated rendering on EC2 GPU instances. Fastest option for complex compositions with heavy animations or 3D content.

Requires an EC2 instance with a GPU (e.g., g4dn.xlarge) and appropriate drivers.

See https://www.remotion.dev/docs/gpu

Social Media Format Presets

Use these resolution and aspect ratio presets when creating compositions. Pass --width and --height to npx remotion render to override the composition defaults.

TikTok / YouTube Shorts / Instagram Reels (9:16 vertical)

npx remotion render ChatDemo out/tiktok.mp4 --width=1080 --height=1920
  • Resolution: 1080x1920
  • Aspect ratio: 9:16
  • Recommended FPS: 30
  • Max duration: 60s (TikTok), 60s (Shorts), 90s (Reels)

YouTube Standard (16:9 landscape)

npx remotion render MyComp out/youtube.mp4 --width=1920 --height=1080
  • Resolution: 1920x1080
  • Aspect ratio: 16:9
  • Recommended FPS: 30 or 60

Instagram Post (1:1 square)

npx remotion render MyComp out/instagram-post.mp4 --width=1080 --height=1080
  • Resolution: 1080x1080
  • Aspect ratio: 1:1
  • Max duration: 60s

Twitter/X Video (16:9 landscape)

npx remotion render MyComp out/twitter.mp4 --width=1280 --height=720
  • Resolution: 1280x720
  • Aspect ratio: 16:9
  • Max file size: 512MB
  • Max duration: 140s

Format preset summary

Platform Width Height Ratio FPS
TikTok 1080 1920 9:16 30
YouTube Shorts 1080 1920 9:16 30
Instagram Reel 1080 1920 9:16 30
Instagram Post 1080 1080 1:1 30
YouTube 1920 1080 16:9 30
Twitter/X 1280 720 16:9 30

When building a Composition in code, set width, height, and fps directly:

<Composition
  id="TikTokPromo"
  component={PromoVideo}
  durationInFrames={30 * 15}
  fps={30}
  width={1080}
  height={1920}
/>

New Packages (v4.0.429+)

@remotion/sfx (v4.0.429)

Built-in sound effects for quick audio cues:

import { Sfx } from "@remotion/sfx";

// Available sounds: ding, bruh, vineBoom
<Sfx name="ding" />
<Sfx name="bruh" />
<Sfx name="vineBoom" />

@remotion/starburst (v4.0.435)

Starburst shape and animation component:

import { Starburst } from "@remotion/starburst";

<Starburst
  points={12}
  innerRadius={50}
  outerRadius={100}
  fill="yellow"
/>

@remotion/shapes (updated v4.0.432)

Geometric shape primitives. Now includes Arrow shape:

import { Triangle, Star, Pie, Arrow } from "@remotion/shapes";

<Triangle length={100} direction="up" fill="red" />
<Star points={5} innerRadius={30} outerRadius={60} fill="gold" />
<Pie radius={50} progress={0.75} fill="blue" />
<Arrow length={150} direction="right" fill="black" />

@remotion/captions

Animated captions for video content. Supports word-level timing and multiple animation styles:

import { Caption } from "@remotion/captions";

<Caption
  text="Hello world"
  startFrame={0}
  endFrame={60}
  style="bounce"
/>

@remotion/player

Embed Remotion videos in React apps without rendering to file. Interactive playback with controls:

import { Player } from "@remotion/player";

<Player
  component={MyComp}
  durationInFrames={300}
  fps={30}
  compositionWidth={1920}
  compositionHeight={1080}
  controls
/>

Mediabunny (format conversion)

Mediabunny is the successor to @remotion/media-parser and @remotion/webcodecs. GPU-accelerated format conversion built into Remotion.

Supported inputs: MP4, WebM, MOV, MKV, M3U8, TS, AVI, MP3, FLAC, WAV, M4A, AAC Supported outputs: MP4, WebM, WAV

import { convertMedia } from "@remotion/media-converter";

await convertMedia({
  src: "input.mov",
  container: "mp4",
});

Remotion Skills (Jan 2026)

AI agent integration for prompt-to-video workflows. Claude Code can generate Remotion compositions from natural language descriptions.

"Create a 15-second TikTok video with animated text saying 'New Feature'
 that fades in with a spring animation, then show three bullet points"

The agent generates the TSX composition, registers it, and renders it - all from a single prompt.

Templates

All templates are created via the create.sh script. Each generates a full Remotion project with TypeScript, TailwindCSS 4.2.0, and the template components.

Chat Demo (Telegram-style phone mockup)

Animated chat bubbles appearing in sequence inside a phone mockup. Good for product demos, bot showcases, customer support highlights.

bash {baseDir}/scripts/create.sh my-chat --template chat
cd my-chat

Edit src/messages.json to customize the conversation:

[
  {"text": "How do I reset my password?", "isUser": true},
  {"text": "Go to Settings > Account > Reset Password. You'll get an email in ~30 seconds.", "isUser": false},
  {"text": "Got it, thanks!", "isUser": true}
]

Render at TikTok resolution:

npx remotion render ChatDemo out/chat-tiktok.mp4 --width=1080 --height=1920

Default composition: 1080x1920 (vertical), 30fps, duration auto-calculated from message count.

Title Card (animated intro)

Fade-in title with spring animation. Use for video intros, section headers, or standalone announcement cards.

bash {baseDir}/scripts/create.sh my-intro --template title
cd my-intro

Customize by editing src/TitleCard.tsx defaultProps:

defaultProps={{ title: "Product Launch", subtitle: "Coming March 2026" }}

Render at YouTube resolution:

npx remotion render TitleCard out/title-youtube.mp4 --width=1920 --height=1080

Default composition: 1920x1080 (landscape), 30fps, 3 seconds.

Blank (starter template)

Empty canvas for building custom compositions from scratch.

bash {baseDir}/scripts/create.sh my-project
cd my-project

Shows frame counter. Replace src/Composition.tsx with your own component.

Building Custom Templates

To add a new template (e.g., promo, code walkthrough, stats dashboard, countdown, testimonial), create a React component that uses Remotion primitives:

import { AbsoluteFill, useCurrentFrame, spring, useVideoConfig, interpolate, Sequence, Img, Audio } from "remotion";

Key Remotion APIs for templates:

  • useCurrentFrame() - current frame number for animation
  • spring({ frame, fps, config }) - spring physics animation
  • interpolate(frame, inputRange, outputRange) - linear interpolation
  • <Sequence from={30}> - delay child content by N frames
  • <Img src={staticFile("logo.png")} /> - load static assets
  • <Audio src={staticFile("music.mp3")} /> - add background audio
  • <AbsoluteFill> - full-frame container

Register compositions in src/Root.tsx:

import { Composition } from "remotion";
import { PromoVideo } from "./PromoVideo";

export const RemotionRoot: React.FC = () => {
  return (
    <>
      <Composition
        id="PromoVideo"
        component={PromoVideo}
        durationInFrames={300}
        fps={30}
        width={1080}
        height={1920}
      />
    </>
  );
};

Thumbnail Generation

Extract a single frame as a still image using Remotion's still command:

npx remotion still MyComp out/thumbnail.png

Options

# Specific frame (default is frame 0)
npx remotion still MyComp out/thumb.png --frame=45

# JPEG output
npx remotion still MyComp out/thumb.jpeg --image-format=jpeg

# JPEG quality (0-100)
npx remotion still MyComp out/thumb.jpeg --image-format=jpeg --jpeg-quality=90

# Custom resolution
npx remotion still MyComp out/thumb.png --width=1280 --height=720

# Pass props
npx remotion still MyComp out/thumb.png --props='{"title":"Episode 1"}'

Thumbnail for YouTube

npx remotion still TitleCard out/yt-thumb.png --width=1280 --height=720 \
  --props='{"title":"How to Build an AI Agent","subtitle":"Step by step guide"}'

YouTube recommended thumbnail: 1280x720 (16:9), PNG or JPEG.

Thumbnail for Instagram

npx remotion still MyComp out/ig-thumb.png --width=1080 --height=1080

Batch Rendering

Render multiple videos in sequence using a shell loop or xargs.

Render multiple compositions from one project

If your Root.tsx registers multiple compositions:

npx remotion render PromoVideo out/promo.mp4
npx remotion render ChatDemo out/chat.mp4
npx remotion render TitleCard out/title.mp4

Render with different props

for topic in "AI Agents" "Open Source" "DevTools"; do
  slug=$(echo "$topic" | tr ' ' '-' | tr '[:upper:]' '[:lower:]')
  npx remotion render TitleCard "out/${slug}.mp4" \
    --props="{\"title\":\"$topic\",\"subtitle\":\"Deep dive\"}"
done

Render all social formats at once

npx remotion render MyComp out/youtube.mp4 --width=1920 --height=1080
npx remotion render MyComp out/tiktok.mp4 --width=1080 --height=1920
npx remotion render MyComp out/square.mp4 --width=1080 --height=1080
npx remotion render MyComp out/twitter.mp4 --width=1280 --height=720

Batch from JSON config

Create a render-jobs.json file:

[
  {"comp": "TitleCard", "output": "out/intro.mp4", "props": {"title": "Welcome"}},
  {"comp": "ChatDemo", "output": "out/demo.mp4"},
  {"comp": "TitleCard", "output": "out/outro.mp4", "props": {"title": "Thanks!"}}
]

Then render all jobs:

cat render-jobs.json | jq -c '.[]' | while read job; do
  comp=$(echo "$job" | jq -r '.comp')
  output=$(echo "$job" | jq -r '.output')
  props=$(echo "$job" | jq -r '.props // empty')
  if [ -n "$props" ]; then
    npx remotion render "$comp" "$output" --props="$props"
  else
    npx remotion render "$comp" "$output"
  fi
done

Output Formats

Remotion supports multiple codecs via --codec:

# MP4 with H.264 (default, best compatibility)
npx remotion render MyComp out/video.mp4

# MP4 with H.265 (smaller files, less compatible)
npx remotion render MyComp out/video.mp4 --codec=h265

# WebM with VP8
npx remotion render MyComp out/video.webm --codec=vp8

# WebM with VP9 (better quality, slower encode)
npx remotion render MyComp out/video.webm --codec=vp9

# GIF (no audio, large files)
npx remotion render MyComp out/video.gif --codec=gif

# ProRes (lossless, huge files, for post-production)
npx remotion render MyComp out/video.mov --codec=prores

# PNG sequence (one PNG per frame)
npx remotion render MyComp out/frames/ --image-format=png --sequence

Quality and performance flags

# CRF (quality) - lower = better quality, larger file. Default ~20
npx remotion render MyComp out/video.mp4 --crf=18

# Concurrency - render multiple frames in parallel
npx remotion render MyComp out/video.mp4 --concurrency=4

# Log level for debugging
npx remotion render MyComp out/video.mp4 --log=verbose

Bundler Options

Remotion v4 supports multiple bundlers:

  • Webpack (default) - stable, well-tested
  • Rspack (experimental) - faster builds, drop-in replacement

To use Rspack:

// remotion.config.ts
import { Config } from "@remotion/cli/config";
Config.setBundler("rspack");

Studio Visual Mode

Remotion Studio includes a visual editing mode with shared contexts. Preview compositions, adjust props visually, and use the timeline scrubber for frame-accurate editing.

npx remotion studio

Features:

  • Visual prop editing
  • Shared contexts between compositions
  • CSS filter support in the web renderer
  • Real-time preview with hot reload

Styling

TailwindCSS 4.2.0

Templates ship with TailwindCSS 4.2.0 pre-configured. Use Tailwind classes directly in your compositions:

<AbsoluteFill className="bg-gradient-to-br from-purple-600 to-blue-500 flex items-center justify-center">
  <h1 className="text-6xl font-bold text-white">Hello World</h1>
</AbsoluteFill>

Zod v4 for props validation

Use Zod v4 schemas to validate composition props:

import { z } from "zod";

const schema = z.object({
  title: z.string(),
  subtitle: z.string().optional(),
  color: z.string().default("#ffffff"),
});

<Composition
  id="MyComp"
  component={MyComp}
  schema={schema}
  defaultProps={{ title: "Hello" }}
  ...
/>

CSS filters

The web renderer supports CSS filter properties:

<div style={{ filter: "blur(5px) brightness(1.2) saturate(1.5)" }}>
  <Img src={staticFile("photo.jpg")} />
</div>

Progress Tracking

Remotion prints render progress to stderr during rendering. The output includes:

  • Frames rendered / total frames
  • Percentage complete
  • Estimated time remaining
  • Encoding progress

To capture progress programmatically, parse stderr output:

npx remotion render MyComp out/video.mp4 2>&1 | tee render.log

For CI/CD pipelines, check the exit code:

npx remotion render MyComp out/video.mp4
if [ $? -eq 0 ]; then
  echo "Render complete: out/video.mp4"
  ls -lh out/video.mp4
else
  echo "Render failed"
  exit 1
fi

Asset Management

Static files (fonts, images, audio)

Place assets in the public/ directory. Reference them with staticFile():

import { Img, Audio, staticFile } from "remotion";

// Image
<Img src={staticFile("logo.png")} />

// Audio
<Audio src={staticFile("background-music.mp3")} />

// Video overlay
<OffthreadVideo src={staticFile("clip.mp4")} />

Custom fonts

Load web fonts or local fonts in your component:

// Google Fonts via CSS import in src/index.css
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;700&display=swap');

// Or load a local font file
@font-face {
  font-family: 'CustomFont';
  src: url('./fonts/CustomFont.woff2') format('woff2');
}

Then use in components:

<div style={{ fontFamily: "'Inter', sans-serif" }}>Your text</div>

Background images and gradients

<AbsoluteFill style={{
  backgroundImage: `url(${staticFile("bg.jpg")})`,
  backgroundSize: "cover",
  backgroundPosition: "center",
}} />

Error Recovery

Chrome Headless Shell not found

Error: Could not find Chrome Headless Shell

Fix: Run setup script or install Chrome dependencies:

bash {baseDir}/scripts/setup.sh

Or install Chrome Headless Shell explicitly:

npx @remotion/install-chrome-headless-shell

Out of memory during render

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory

Fix: Increase Node.js memory limit:

NODE_OPTIONS="--max-old-space-size=4096" npx remotion render MyComp out/video.mp4

Or reduce concurrency:

npx remotion render MyComp out/video.mp4 --concurrency=1

Missing npm dependencies

Cannot find module 'remotion'

Fix: Install dependencies in the project directory:

npm install

Composition not found

Could not find composition with id "MyComp"

Fix: List available compositions:

npx remotion compositions

Then use the correct composition ID in your render command.

Render timeout on slow machines

For long videos or slow servers, increase the timeout per frame:

npx remotion render MyComp out/video.mp4 --timeout=60000

Default timeout is 30000ms (30 seconds) per frame.

Display server errors (headless Linux)

Error: Failed to launch the browser process

On headless Linux without a display server, Remotion uses Chrome Headless Shell which does not require X11/Wayland. If you see display errors, ensure you are not accidentally using a full Chrome install. Set the browser explicitly:

npx remotion render MyComp out/video.mp4 --browser=chrome-headless-shell

Usage Examples

Product launch promo (TikTok)

bash {baseDir}/scripts/create.sh launch-promo --template title
cd launch-promo
# Edit src/TitleCard.tsx to customize
npx remotion render TitleCard out/promo.mp4 --width=1080 --height=1920

Customer support bot demo (Instagram Reel)

bash {baseDir}/scripts/create.sh support-demo --template chat
cd support-demo
# Edit src/messages.json with support conversation
npx remotion render ChatDemo out/support-reel.mp4 --width=1080 --height=1920

YouTube intro with custom branding

bash {baseDir}/scripts/create.sh yt-intro --template title
cd yt-intro
# Add logo to public/logo.png, edit TitleCard to include <Img>
npx remotion render TitleCard out/intro.mp4 --width=1920 --height=1080

Generate thumbnails for a video series

for i in 1 2 3 4 5; do
  npx remotion still TitleCard "out/thumb-ep${i}.png" --width=1280 --height=720 \
    --props="{\"title\":\"Episode ${i}\",\"subtitle\":\"The Series\"}"
done

Square Instagram post

bash {baseDir}/scripts/create.sh ig-post
cd ig-post
# Build a 1:1 composition
npx remotion render MyComp out/post.mp4 --width=1080 --height=1080

Render on Lambda with webhook

npx remotion lambda render MyComp \
  --webhook-url=https://example.com/api/render-complete \
  --webhook-secret=my-secret

Add sound effects to a composition

import { Sfx } from "@remotion/sfx";
import { Sequence } from "remotion";

// Play a ding at frame 30
<Sequence from={30}>
  <Sfx name="ding" />
</Sequence>

Related Skills

  • Use /nano-triple to generate still images (logos, backgrounds, icons) to use as assets in your Remotion compositions
  • Use /last30days to research trending topics and generate content ideas for your videos

Linux Dependencies Reference

The setup script installs these system packages required by Chrome Headless Shell:

Ubuntu/Debian

libnss3 libdbus-1-3 libatk1.0-0 libasound2 libxrandr2 libxkbcommon-dev
libxfixes3 libxcomposite1 libxdamage1 libgbm-dev libcups2 libcairo2
libpango-1.0-0 libatk-bridge2.0-0

Note: Ubuntu 24.04 uses libasound2t64 instead of libasound2.

Amazon Linux

mesa-libgbm libX11 libXrandr libdrm libXdamage libXfixes libxkbcommon
dbus-libs libXcomposite alsa-lib nss dbus pango cups-libs at-spi2-core atk at-spi2-atk

Docker

For Docker, use a base image with Chrome dependencies pre-installed, or add the apt-get install to your Dockerfile:

FROM node:20-slim
RUN apt-get update && apt-get install -y \
  libnss3 libatk1.0-0 libatk-bridge2.0-0 libcups2 libgbm1 \
  libpango-1.0-0 libcairo2 libxcomposite1 libxdamage1 libxfixes3 libxrandr2 \
  && rm -rf /var/lib/apt/lists/*

Full dependency reference

See https://www.remotion.dev/docs/miscellaneous/linux-dependencies

Privacy Note

All templates use FAKE demo data only:

  • Fake GPS coords (San Francisco: 37.7749, -122.4194)
  • Placeholder names and values
  • Never includes real user data

Always review generated content before publishing.

Weekly Installs
2
GitHub Stars
1
First Seen
Mar 20, 2026