---
title: Rendering
description: "Render compositions to MP4, MOV, WebM, GIF, or PNG sequences locally or in Docker."
---
Render your Hyperframes [compositions](/concepts/compositions) to MP4, MOV, WebM, GIF, or PNG sequences with the [CLI](/packages/cli). The rendering pipeline is frame-by-frame and seek-driven — see [Deterministic Rendering](/concepts/determinism) for how this works under the hood.
## Getting Started
Run the diagnostics command to check for required dependencies:
```bash Terminal
npx hyperframes doctor
```
Expected output:
```
✓ Node.js v22.x
✓ FFmpeg 7.x
✓ FFprobe 7.x
✓ Chrome (bundled)
✓ Docker available
```
Before rendering, preview your composition in the browser to verify it looks correct:
```bash Terminal
npx hyperframes preview
```
Run the render command from your project directory:
```bash Terminal
npx hyperframes render --output output.mp4
```
Expected output:
```
⠋ Rendering composition "root" (30fps, standard quality)
✓ Captured 240 frames in 8.2s
✓ Encoded to output.mp4 (8.0s, 1920x1080, 4.2MB)
```
## Rendering Modes
### Local Mode (default)
Uses Puppeteer (bundled Chromium) and your system's FFmpeg. Fast for iteration during development.
**Requires:** FFmpeg installed on your system. See [Troubleshooting](/guides/troubleshooting) if FFmpeg is not found.
```bash Terminal
npx hyperframes render --output output.mp4
```
**Pros:**
- Fast startup, no container overhead
- Can use your system GPU for Chrome/WebGL capture by default
- Can use your system GPU for hardware-accelerated encoding (with `--gpu`)
- Best for iterative development
**Cons:**
- Output may vary across platforms due to font and Chrome version differences
- Not suitable for CI/CD pipelines that require reproducibility
### Docker Mode
[Deterministic](/concepts/determinism) output with an exact Chrome version and font set. Use this for production renders and CI pipelines.
**Requires:** Docker installed and running.
```bash Terminal
npx hyperframes render --docker --output output.mp4
```
**Pros:**
- Identical output on every platform — same Chrome, same fonts, same FFmpeg
- The same pipeline used in production
- Ideal for CI/CD and automated workflows
**Cons:**
- Slower startup due to container initialization
- Browser capture stays on the deterministic software-GL path
- GPU encoding requires Docker host GPU passthrough and is not cross-platform on Docker Desktop
Docker mode uses `chrome-headless-shell` with [BeginFrame](/concepts/determinism#how-it-works) control for frame-perfect, deterministic capture.
## When to Use Each Mode
| Scenario | Recommended Mode |
|----------|-----------------|
| Local development and iteration | Local |
| CI/CD pipeline | Docker |
| Sharing renders with a team | Docker |
| Quick preview export | Local |
| AI agent-driven rendering | Docker |
| Benchmarking performance | Local |
## Options
| Flag | Values | Default | Description |
|------|--------|---------|-------------|
| `--output` | path | `renders/.mp4` | Output file path |
| `--format` | mp4, mov, webm, gif, png-sequence | mp4 | Output format (see [Transparent Video](#transparent-video) below) |
| `--fps` | 1-240 or rational (e.g. `30000/1001`) | 30 | Frames per second |
| `--gif-loop` | 0-65535 | 0 | GIF loop count. `0` loops forever |
| `--quality` | draft, standard, high | standard | Encoding quality preset |
| `--crf` | 0–51 | — | Override CRF (lower = higher quality). Cannot combine with `--video-bitrate` |
| `--video-bitrate` | e.g. `10M`, `5000k` | — | Target bitrate encoding. Cannot combine with `--crf` |
| `--video-frame-format` | auto, jpg, png | auto | Source video frame extraction format. Use `png` for UI recordings, screen captures, and color-sensitive source videos |
| `--workers` | 1-24 or `auto` | auto | Parallel render workers (see [Workers](#workers) below) |
| `--max-concurrent-renders` | 1-10 | 2 | Max simultaneous renders via the producer server (see [Concurrent Renders](#concurrent-renders) below) |
| `--batch` | path | — | JSON array of variable rows (or `{ "rows": [...] }`), rendering one output per row |
| `--batch-concurrency` | integer | 1 | Maximum batch rows to render at once |
| `--batch-fail-fast` | — | off | Stop launching new batch rows after the first row failure |
| `--gpu` | — | off | GPU encoding (NVENC, VideoToolbox, AMF, VAAPI, QSV) |
| `--browser-gpu` / `--no-browser-gpu` | — | on locally, off in Docker | Use or opt out of host GPU acceleration for local Chrome/WebGL capture |
| `--hdr` | — | off | Force HDR output even if no HDR sources are detected (MP4 only). See [HDR Rendering](/guides/hdr) |
| `--sdr` | — | off | Force SDR output even if HDR sources are detected |
| `--docker` | — | off | Use Docker for [deterministic rendering](/concepts/determinism) |
| `--quiet` | — | off | Suppress verbose output |
## Quality and Encoding
The `--quality` flag selects a preset that controls the H.264 CRF (Constant Rate Factor) and encoder speed:
| Preset | CRF | x264 Preset | Best For |
|--------|-----|-------------|----------|
| `draft` | 28 | ultrafast | Quick previews, iteration |
| `standard` | 18 | medium | General use — visually lossless at 1080p |
| `high` | 15 | slow | Final delivery, near-lossless quality |
For finer control, use `--crf` or `--video-bitrate` to override the preset:
```bash
# Near-lossless quality (CRF 15 = very high quality, large file)
npx hyperframes render --crf 15 --output pristine.mp4
# Target a specific bitrate (useful for size-constrained delivery)
npx hyperframes render --video-bitrate 10M --output controlled.mp4
```
**Tip**: The default `standard` preset (CRF 18) is visually lossless at 1080p — most people cannot distinguish it from the source. Use `--quality draft` for faster iteration, or `--quality high` / `--crf 10` when file size is no concern.
## Input Video Codecs
Video assets referenced by a composition (a `