hyperframes render
Produce deterministic MP4, WebM, ProRes, or PNG sequences from HTML. The complete render command reference with every flag.
hyperframes render is the keystone command. It captures your composition frame-by-frame in headless Chromium, hands the frames to FFmpeg, and writes a single artifact. Given the same input it always writes the same bytes — that property is the entire reason the CLI exists.
Synopsis
hyperframes render <file> [flags]<file> is the composition's entry HTML. Output defaults to <file basename>.mp4 next to the input.
Flags
| Flag | Default | Meaning |
|---|---|---|
--out <path> | next to input | Output file. Extension is informative; codec wins. |
--width <n> | from HTML or 1920 | Render width in px. |
--height <n> | from HTML or 1080 | Render height in px. |
--fps <n> | from HTML or 60 | Frame rate. Must divide cleanly into your timeline. |
--codec <name> | h264 | h264 | h265 | prores | vp9 | av1 | png. |
--crf <n> | 18 | Constant rate factor (h264/h265/vp9/av1). Lower = bigger and sharper. |
--bitrate <rate> | — | Target bitrate (e.g. 12M). Overrides --crf when both are set. |
--hdr | off | Encode in BT.2020 PQ. Requires --codec h265 or av1. |
--alpha | off | Preserve transparency. Requires --codec prores or vp9 (webm). |
--workers <n> | cpu count | Parallel browser tabs capturing frames. |
--variants <json> | — | Path to a JSON file describing per-variant --vars and outputs. |
--vars k=v | — | Repeatable. Substitutes {{$K}} in the HTML at render time. |
--manifest <path> | — | Write a render manifest (sha, deps, flags) alongside the output. |
--seed <n> | from HTML or 0 | Seed for the determinism shim (Math.random, Date.now). |
--frame-range a:b | full | Render only frames [a, b). Useful for previews and reshoots. |
Common invocations
$ hyperframes render comp.html --out out.mp4
rendered 300 frames in 18.4s
out.mp4 2.4 MB sha256:e3b0c44...Encoding trade-offs
Variables and variants
A variants file batches renders that differ only by substituted strings. Variables in the HTML use {{$NAME}} form.
[
{ "vars": { "NAME": "Alice", "ROLE": "Engineer" } },
{ "vars": { "NAME": "Bob", "ROLE": "Designer" } },
{ "vars": { "NAME": "Cleo", "ROLE": "Founder" } }
]The --out template may reference any variable. Renders run in parallel up to --workers.
JSON output
{
"command": "render",
"status": "ok",
"exit_code": 0,
"out": "video.mp4",
"size": 2400000,
"sha": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"duration_ms": 18402,
"frames": 300,
"width": 1920,
"height": 1080,
"fps": 60,
"codec": "h264",
"warnings": []
}Variant runs return an array of these objects under results.
Manifests
--manifest render.json emits a sidecar capturing every input that contributed to the output: HTML sha, asset shas, CLI version, codec, and flags. Two manifests with the same content guarantee two identical outputs. This is what makes HyperFrames usable as a build artifact in CI.
{
"version": 1,
"cli": "[email protected]",
"input": { "path": "comp.html", "sha": "a91f..." },
"deps": [
{ "path": "music.mp3", "sha": "b3c2..." },
{ "path": "logo.svg", "sha": "0fe1..." }
],
"flags": { "width": 1920, "height": 1080, "fps": 60, "codec": "h264", "crf": 18 },
"out": { "path": "video.mp4", "sha": "e3b0..." }
}Exit codes
0— render complete.1— invalid flags or input.2—lintran first and produced errors.3— render failed (page crash, frame timeout, muxer error).4— ffmpeg or the requested codec is missing. Runhyperframes doctor.5— chromium launch failed. Runhyperframes browser install.
Tips
- Use
--frame-rangefor reshoots: render only the seconds you changed, then concat with your editor. --workerspast the physical core count rarely helps and can deadlock weak GPUs. Start atcpu/2.- Commit the manifest, not the MP4. Anyone can reproduce the bytes from the manifest.
- For CI, set
--no-cacheto guarantee a cold render. For local iteration, leave the cache on.
Next
- HyperFrames CLI — full command index.
hyperframes lint— catch determinism bugs before they reach the encoder.