Skip to main content
The hyperframes CLI is the primary way to work with HyperFrames. It handles project creation, live preview, rendering, linting, and diagnostics — all from your terminal.

When to Use

Use the CLI when you want to:
  • Capture a website for video production (capture)
  • Create a new composition project from an example (init)
  • Preview compositions with live hot reload (preview)
  • Render compositions to MP4 locally or in Docker (render)
  • Lint compositions for structural issues (lint)
  • Inspect rendered visual layout for text overflow, clipped containers, and overlapping text, plus verify motion intent against the seeked timeline (inspect)
  • Capture key frames as PNG screenshots (snapshot)
  • Check your environment for missing dependencies (doctor)
Use a different package if you want to:
  • Render programmatically from Node.js code — use the producer
  • Build a custom frame capture pipeline — use the engine
  • Embed a composition editor in your own web app — use the studio
  • Parse or generate composition HTML in code — use core
The CLI is the recommended starting point for all HyperFrames users. It wraps the producer, engine, and studio packages so you do not need to install them separately.

Agent-Friendly by Default

The CLI is agent-friendly by default: commands support explicit flags and parseable output so automation can run reliably.
  • Inputs can be passed via flags (for example, --example, --video, --output)
  • Missing required flags fail fast with a clear error and usage example
  • Output is plain text suitable for parsing
Interactivity is command-specific. For example, init uses prompts on TTY by default; pass --non-interactive to force non-interactive mode. --human-friendly is also command-specific (for example, catalog). It is not a global flag on every command.

JSON Output and _meta Envelope

All commands that support --json wrap their output with a _meta field containing version check info:
This allows agents to detect outdated versions from any command’s output without running a separate upgrade check. The version data comes from a 24-hour cache — no network request is made during --json output.

Passive Update Notices

The CLI checks npm for newer versions in the background (cached 24 hours). If an update is available, a notice appears on stderr after command completion:
This is suppressed in CI environments, non-TTY shells, and when HYPERFRAMES_NO_UPDATE_CHECK=1 is set.

Getting Started

1

Create a project

Scaffold a new composition from an example:
You will be prompted for a project name, or pass it as an argument:
See Examples for all available examples.
2

Preview in browser

Start the development server with live hot reload:
The HyperFrames Studio opens in your browser. Edit index.html and the preview updates instantly.
3

Lint your composition

Check for structural issues before rendering:
4

Render to MP4

Produce the final video:
Render a specific composition instead of index.html:
For deterministic output, add --docker:

Commands

The installed version is authoritative: run npx hyperframes --help or npx hyperframes <command> --help. The sections below document the commands used most often; deployment and integration commands link to their focused guides. validate, inspect, and layout remain as compatibility commands. Prefer check, which combines lint, runtime, layout, motion, and contrast checks in one browser session.

Create and source material

init

Create a new composition project from an example:
In non-interactive mode, --example is required — the CLI errors with a usage example if missing. In interactive mode (default on TTY), you choose the example interactively. Pass --non-interactive to require --example via flag. When --video or --audio is provided, the CLI automatically transcribes the audio with Whisper and patches captions into the composition (use --skip-transcribe to disable). --tailwind injects the pinned Tailwind v4 browser runtime into scaffolded HTML and exposes a window.__tailwindReady promise that renders wait on before capturing frame 0. Use the /hyperframes-core skill when editing these projects so agents follow v4 CSS-first patterns instead of v3 tailwind.config.js and @tailwind directive patterns. The browser runtime is still intended for scaffolded projects and quick iteration; for fully offline or locked-down production renders, compile Tailwind to CSS and include the stylesheet directly. After scaffolding, the CLI checks and installs the core AI skills from the current GitHub source. Set HYPERFRAMES_SKIP_SKILLS=1 only when CI or tests must opt out. See skills. See Examples for full details.

add

Install a block or component from the registry into an existing project. Examples (full projects) are scaffolded with init; blocks and components are smaller units you add to a composition you already have.
add reads hyperframes.json at the project root to know which registry to pull from and where to drop files. If the file is missing but the directory looks like a HyperFrames project (has index.html), a default hyperframes.json is written the first time you run add. Output for a block or component is a set of files plus a paste snippet — the <iframe> tag (for blocks) or the fragment path (for components) to include in your host composition. The snippet is copied to the clipboard by default; add --no-clipboard for CI or headless environments. Trying add with an example’s name (e.g. hyperframes add warm-grain) emits a clear error pointing you at init --example.

catalog

Browse the registry — list available blocks and components with optional filters:
Default output is a table listing name, type, description, and tags — designed for agents to parse. --json produces structured output. --human-friendly opens an interactive picker that runs add on selection.

compositions

List all compositions in the current project:
Shows each composition’s ID, duration, resolution, and element count.

transcribe

Transcribe audio/video to word-level timestamps, or import an existing transcript:
The command auto-detects the input type. Audio/video files are transcribed with whisper.cpp. Transcript files (.json, .srt, .vtt) are normalized and imported. Pass --to srt or --to vtt with a transcript input to write a caption sidecar instead. Supported transcript formats: All formats are normalized to a standard [{text, start, end}] word array and saved as transcript.json. If the project has caption HTML files, they are automatically patched with the transcript data. Sidecar export reads the same normalized transcript and writes transcript.srt or transcript.vtt by default. Word-level transcripts (whisper output) are grouped into readable caption cues on sentence boundaries. Exporting directly from an .srt/.vtt source keeps its cue boundaries unchanged. When exporting from a transcript.json whose entries are already finished cues with no internal spaces (single-word or CJK captions), pass --preserve-cues to keep them one cue per entry.
For music or noisy audio, use --model medium.en for better accuracy. For the best results with production content, transcribe via the OpenAI or Groq Whisper API and import the JSON.

tts

Generate speech audio from text using a local AI model (Kokoro-82M). No API key required — runs entirely on-device.
Voice IDs encode the phonemizer language in their first letter (a=American, b=British, e=Spanish, f=French, h=Hindi, i=Italian, j=Japanese, p=Brazilian Portuguese, z=Mandarin). --lang is only needed when you want to override that — for example, giving English text a French phonemizer for a stylized accent.
Combine tts with transcribe to generate narration and word-level timestamps for captions in a single workflow: generate the audio with tts, then transcribe the output with transcribe to get word-level timing.

remove-background

Remove the background from a video or image using a local AI model. The output is transparent media you can drop into any composition’s <video> or <img> element — no green screen required.
The model is u2net_human_seg (MIT, ~168 MB ONNX). Weights download to ~/.cache/hyperframes/background-removal/models/ on first run and are reused thereafter. Peak inference RAM is ~1.5 GB. --device auto picks CoreML on Apple Silicon, CUDA when available, and CPU otherwise. The CLI bundles the CPU build of onnxruntime-node; for CUDA, set HYPERFRAMES_CUDA=1 and provide a GPU-enabled onnxruntime-node build. Output formats:
The <video> element in Chrome only respects the alpha plane when the WebM is encoded as yuva420p with the alpha_mode=1 metadata tag. The CLI sets both automatically — if you re-encode the output yourself, preserve those flags.
See the Remove Background guide for the full workflow — using transparent videos in compositions, performance per platform, limitations of u2net_human_seg, and free alternative tools when this model isn’t the right fit.

capture

Capture a website into a working folder for video production:
Capture records scroll screenshots, extracted HTML and CSS, visible text, design tokens, font files, images, SVGs, and animation metadata. It also tries to preserve useful Lottie, video, and WebGL context when the page exposes it. Dynamic sites, protected pages, and unusual media loaders may produce partial results, so review the warnings and contact sheets before building. The output contains AGENTS.md, CLAUDE.md, meta.json, extracted source material, assets, screenshots, and contact sheets. It is source material for an agent, not a finished HyperFrames composition. The /product-launch-video workflow uses it when a real product or website needs to appear in the video. Set GEMINI_API_KEY in a .env file for AI-powered image descriptions via Gemini vision (~$0.001/image), or set OPENROUTER_API_KEY to use any vision model through OpenRouter instead (takes priority if both are set; override the model with HYPERFRAMES_OPENROUTER_MODEL). See the Product launch video guide for the creator workflow.

Preview and present

preview

Start a live preview server with hot reload:
Opens your composition in HyperFrames Studio with live preview. Edits to index.html and referenced sub-compositions refresh in the preview. Preview and render use the same HyperFrames composition runtime.
Preview still plays in real time, so paint-heavy compositions may stutter on the current computer. Render seeks and captures one frame at a time, so the same work normally increases render time instead of dropping output frames. Browser, font, and GPU differences can still affect exact pixels. Review the rendered file itself. See Performance.
The preview server runs in three modes, auto-detected:
  1. Embedded mode (default for npx) — runs a standalone server with the studio bundled in the CLI. Zero extra dependencies.
  2. Local studio mode — if @hyperframes/studio is installed in your project’s node_modules, spawns Vite with full HMR for faster iteration.
  3. Monorepo mode — if running from the HyperFrames source repo, spawns the studio dev server directly.

present

Serve a slideshow and open its presenter view:
The presenter and audience views stay synchronized while the command is running.

publish

Upload the project and get back a stable hyperframes.dev URL:
publish zips the current project, uploads it to the HyperFrames publish backend, and prints a hyperframes.dev URL. You can publish while signed out. In that case, the printed URL includes a claim token; opening it on hyperframes.dev lets the intended user sign in, claim the project, and continue editing in the web app. Sign in with npx hyperframes auth login first when you want an owned, stable link that you can publish to again. --update and --space require that authenticated ownership. Publishing does not keep a local preview server alive or open a tunnel. The URL resolves to a stored project, so it keeps working after the CLI process exits.

lint

Check a composition for common issues:
By default only errors and warnings are printed. Info-level findings (e.g., external script dependency notices) are hidden to keep output clean for agents and CI. Use --verbose to include them. Severity levels:
  • Error () — must fix before rendering (e.g., missing adapter library, invalid attributes)
  • Warning () — likely issues that may cause unexpected behavior
  • Info () — informational notices, shown only with --verbose
The linter detects missing attributes, missing adapter libraries (GSAP, Lottie, Three.js), structural problems, and more. See Troubleshooting for details on each rule.

check

The browser verification gate: everything the old validateinspectsnapshot loop did, in one command with one browser session:
check runs the linter first (browser skipped entirely on lint errors), then loads the bundled composition once and sweeps one seek grid running every audit per sample: runtime console errors and failed requests, layout defects (overflow, clipping, held overlaps, occlusion, coordinate-frame drift), *.motion.json sidecar assertions, and WCAG AA contrast. Contrast failures are errors and include the sampled fg/bg colors, measured vs required ratio, and a suggested compliant color. Severity is persistence-aware: single-sample transients demote to info, held findings gate the exit code, and a frozen timeline on a 3s+ composition fails with sweep_static. Escape hatches (mark intent in HTML, then re-run): data-layout-allow-overflow / data-layout-allow-overlap / data-layout-allow-occlusion / data-layout-ignore for the usual layout audits. For intentional lower-third copy under --caption-zone, mark data-layout-allow-caption-zone on the element or an ancestor (closest); it silences only caption_zone_collision (not overflow, overlap, occlusion, or contrast) — prefer the narrowest wrapper that owns the band copy.

validate

validate is the older runtime-only browser check:
It reports runtime errors, failed assets, and contrast findings. Prefer check for new workflows because it also runs lint, layout, motion, and snapshot checks.

beats

Detect the beats in a composition’s music track and write them to a beat file the Studio uses to draw beat guides on the timeline:
The command finds the music track (an <audio> element with data-timeline-role="music", or an id like music/bgm/soundtrack), runs the same detection the Studio uses inside a headless Chrome (identical decode + BPM analysis), and writes beats/<audio-path>.json:
Run it when authoring a composition so the beat file exists before the Studio is opened — the Studio loads this file as-is (it only auto-generates one when none exists). time is in seconds into the audio file; strength (0–1) is the beat’s relative loudness. Beats edited in the Studio (add/move/delete) persist back to the same file. Requires a local Chrome (the same one used by render; run npx hyperframes browser ensure if missing). Detection runs the same algorithm the Studio uses; results are near-identical (a different headless-Chrome audio sample rate can shift beat times by a frame or two).

media-treatment

Discover or edit the color and effect treatment stored on one image or video:
The command persists data-color-grading, the same contract used by Studio, preview, and render. It does not perform subject recognition or isolate part of an image.

inspect

Deprecated: use check — it covers this layout sweep plus runtime, motion, and contrast in one browser session. inspect keeps working and marks _meta.deprecated: true in JSON output.
Inspect rendered visual layout across the composition timeline:
inspect bundles the project, serves it locally, opens headless Chrome, seeks through the composition, and reports text or elements that escape their intended boxes, plus pairs of text blocks that overlap each other (content_overlap) and text that is hidden beneath an opaque element (text_occluded). It is designed for agent workflows: each finding includes a schema version, timestamp or collapsed timestamp range, selector, nearest container selector, measured bounding boxes, overflow sides, and a fix hint. Use data-layout-allow-overflow on an element or ancestor when overflow is intentional, such as a planned off-canvas entrance. Use data-layout-ignore for decorative elements that should not be audited. Use data-layout-allow-overlap on a text element that is intentionally stacked over another (for example a lower-third caption above a heading). Use data-layout-allow-occlusion when text is intentionally layered beneath another element (for example a caption behind a foreground prop). For --caption-zone / data-layout-allow-caption-zone, see check. layout remains available as a compatibility alias for the same visual inspection pass:

Motion verification

inspect also checks motion intent against the same seeked timeline the renderer uses — catching the render-≠-preview bugs that layout sampling can’t, like an entrance reveal the seek skips, a broken stagger order, an element that drifts off-frame mid-tween, or a shot that freezes. Drop a *.motion.json sidecar next to the composition and inspect evaluates it automatically (no flag, no authoring changes); without a sidecar, inspect behaves exactly as before.
duration, keepsMoving.withinSelector, and keepsMoving.maxStaticSec are optional. Findings are reported in the same shape and JSON envelope as layout findings, are errors by default (a failed assertion fails the run), and a selector that matches nothing is reported as motion_selector_missing rather than silently passing.

snapshot

Capture key frames from a composition as PNG screenshots — verify visual output without a full render:
The snapshot command bundles the project, serves it locally, launches headless Chrome, seeks to each timestamp, and captures a 1920×1080 PNG. It is useful for visual verification during the product launch video workflow.

keyframes

Inspect detected GSAP, CSS, and Anime.js keyframes, or render an onion-shot diagnostic of one element:

compare

Render two or more independent composition variants into one labeled PNG:

grade-compare

Apply candidate color grades or LUTs to one reference frame and write a labeled comparison PNG:

Check and render

render

Render a composition to MP4, WebM, MOV, GIF, or an RGBA PNG sequence:
CRF and target bitrate default to the --quality preset. Use --crf or --video-bitrate for fine-grained overrides; RenderConfig.crf and RenderConfig.videoBitrate accept the same overrides programmatically. Use --video-frame-format png when source videos are UI recordings, screen captures, or other color-sensitive clips that should avoid JPEG frame extraction.

Parametrized renders

Render the same composition with different content by declaring variables on the composition root and overriding them at render time:
index.html
getVariables() returns the merged result of declared defaults and any --variables overrides, so the same composition runs unchanged in dev preview and in production renders.

WebM with Transparency

Use --format webm to render compositions with a transparent background. This produces VP9 video with alpha channel in a WebM container — the standard format for overlayable video.
For transparency to work, your composition’s HTML should use background: transparent on the root elements. WebM renders use PNG frame capture (instead of JPEG) to preserve the alpha channel.
See Rendering for all options and modes.

benchmark

Find optimal render settings for your system:
Runs multiple render configurations (varying fps, quality, and worker count) and compares timing and file size for each.

Inspect and maintain

doctor

Check your environment for required dependencies:
Verifies CLI version, Node.js, FFmpeg, FFprobe, Chrome, and Docker availability. If a newer CLI version is available, the version row shows an upgrade hint. CI gating. hyperframes doctor --json always exits 0 on successful execution — the command succeeded if it produced valid output. Whether the environment is healthy is carried in the ok field of the payload, so a new CLI release (which flips Version.ok to false) never breaks your pipeline. Pipe through jq to gate on the payload instead:
Paths in detail and hint are redacted in JSON mode — the user’s home directory is replaced with the literal $HOME so output is safe to paste into bug reports and agent contexts.

info

Display project metadata:
Shows project name, resolution, duration, element counts by type, track count, and total project size.

upgrade

Check for updates and show upgrade instructions:
Compares your installed version against the latest on npm. With --check --json, returns:

browser

Manage the Chrome browser used for rendering:
The path subcommand outputs only the path, useful in scripts: $(npx hyperframes browser path).

docs

View inline documentation in the terminal:
Available topics: data-attributes, examples, rendering, gsap, troubleshooting, compositions. Run without a topic to see the full list.

feedback

Submit anonymous recommendation feedback about your experience:
With --file-issue, the CLI publishes a minimal repro to a public URL (with consent) and opens a pre-filled bug issue draft you review and submit yourself (no token or backend). See Share feedback. This command is also available to AI agents after a render — see About feedback data for what the feedback surface includes. No-op when telemetry is disabled — prints Telemetry is disabled. Feedback not sent. and exits cleanly.

telemetry

Manage anonymous usage telemetry:
Telemetry collects command names, render performance, render checkpoint/error names, aggregate browser diagnostic counts, browser initialization duration and tween count, aggregate video extraction workload counts (such as extracted frame count and VFR preflight count), example choices, and system info — including a coarse environment fingerprint (OS, kernel string, CPU/memory shape, sandbox runtime such as gVisor or Docker, and the name of a coding agent driving the CLI when one is detected, e.g. claude_code / codex / cursor). The agent name is derived from the existence of well-known environment variables; their values are never read. Telemetry redacts local paths and URL query strings from render error/checkpoint messages and does not collect project names, video content, or environment variable values. It collects no personally identifiable information until you sign in: when you authenticate with hyperframes auth login, your HeyGen account email (or your username, if your account has no email) is linked to your usage so CLI activity can be associated with your account (and your prior anonymous usage is stitched to it). Nothing else personal is collected, and this only happens after you choose to sign in. Disable all telemetry with HYPERFRAMES_NO_TELEMETRY=1 or the command above. See Feedback Collection for how the periodic post-render prompt and Studio feedback bar work, what data they collect, and how to opt out. Turning telemetry off also opts the install out of canary rollouts — a staged release enables a change for a stable slice of installs, and an install that reports nothing cannot be compared against anything. Every route counts: telemetry disable, HYPERFRAMES_NO_TELEMETRY=1, DO_NOT_TRACK=1, and dev builds. See Canary rollouts.

skills

Install or refresh the HyperFrames skills used by AI coding tools:
Bare skills installs the complete published set. skills update keeps a deliberate partial installation partial: it refreshes the core set and every workflow already installed. Passing a workflow name adds that workflow as well. The CLI installs from the current HyperFrames GitHub source and links the global bundles into the compatible agents it finds. After scaffolding, init also checks and refreshes the core set plus any HyperFrames skills already installed.

Troubleshooting: fatal: active post-checkout hook found during git clone

If you installed Git LFS globally (git lfs install), Git 2.45+ refuses to run the LFS post-checkout hook during any git clone — including the clone the upstream skills CLI performs under the hood. The error looks like:
hyperframes skills handles this Git setting itself. You do not need to add an environment variable when using the HyperFrames command. If you ran npx skills add heygen-com/hyperframes --full-depth directly (bypassing the HyperFrames CLI), set the env var yourself:
This workaround is only for calling the upstream skills command directly.

Other shipped commands

These commands are part of the current CLI but have narrower entry points: Run npx hyperframes <command> --help for the installed command’s exact flags. See Figma integration for setup and import examples.

hyperframes auth

Sign in to HeyGen and manage credentials. Credentials are stored in ~/.heygen/credentials (mode 0600) and are shared with the heygen CLI — sign in with one and the other picks up the session. Resolution order (first match wins):
  1. HEYGEN_API_KEY environment variable
  2. HYPERFRAMES_API_KEY environment variable (hyperframes alias)
  3. ~/.heygen/credentials

Subcommands

auth login

Open a browser and sign in with OAuth:
Pass --api-key when you need a long-lived HeyGen API key instead. The key is verified against GET /v3/users/me before the command reports success; a rejected key is not left on disk.

auth status

Show the active credential’s source, type, and verified identity (account + billing snapshot). Exits non-zero when nothing is configured or the API rejects the credential, so scripts can check sign-in state.

auth refresh

Force-refresh the stored OAuth access token:
This applies to an OAuth session, not an API key.

auth logout

Remove the stored credential. Prompts for confirmation on a TTY.

Environment variables

For the keys other capabilities use — ElevenLabs and Gemini for voice/music fallback, OpenRouter/Gemini for capture — and how the skills prioritize them, see Authentication & API keys.

hyperframes cloud

Render a HyperFrames composition on HeyGen’s hosted cloud — no local Chrome, no local ffmpeg, no AWS to manage. Sign in once with hyperframes auth login and the same credential drives every cloud subcommand.

Subcommands

cloud render [<projectDir>]

End-to-end render: zips the project (excluding root renders/snapshots, .git, node_modules, dist, .next, coverage, dotfiles, and project .hyperframesignore rules), uploads it through the direct-to-S3 asset flow, submits POST /v3/hyperframes/renders, polls GET /v3/hyperframes/renders/{id} until the render completes or fails, and streams the resulting video to disk. Use hyperframes cloud render --dry-run to inspect the compressed size and largest included files without authenticating, uploading, or starting a render. Project-specific .hyperframesignore rules use gitignore syntax and also apply to hyperframes publish; keep rules narrow because dynamically selected assets may not have obvious static references. Render parameters mirror the local hyperframes render UX where they overlap: Lifecycle / control flags:
Safe retries via --idempotency-key
The CLI transparently retries on a 401 Unauthorized by force-refreshing the OAuth token and replaying the failed request. For most reads that’s harmless, but POST /v3/assets (the zip upload) is not idempotent on its own — a retry without an Idempotency-Key would create a duplicate asset and bill the workspace twice. Pass --idempotency-key <key> whenever you want safe retries on cloud render. The key is forwarded to both the upload and submit calls; the server scopes idempotency per-endpoint, so reusing the same value across the two steps is safe and prevents duplicates on either step. Use a UUID per logical render, or any opaque string in [A-Za-z0-9_:.-] (1-255 chars).

cloud list

Pages through recent renders. Cursor-based: --limit caps a single page (1-100), --token resumes from a previous next_token, --all walks the full list until exhausted.

cloud get <render_id>

Fetches the full detail record for one render, including the short-lived signed video_url and thumbnail_url (presigned S3 URLs — re-fetch on demand rather than cache).

cloud delete <render_id>

Soft-deletes a render. Subsequent GET calls return 404 and the signed video URL stops working shortly after. Prompts for confirmation interactively; pass --no-confirm to bypass for scripts.

When to pick cloud vs lambda vs local render

  • hyperframes render (local): fastest iteration loop. Use during composition authoring.
  • hyperframes lambda render: bring-your-own-AWS distributed rendering. Use when you’ve already invested in AWS and want chunked parallelism on your own account.
  • hyperframes cloud render: zero-infra option. HeyGen runs the render; you pay per credit. Use when you don’t want to manage Chrome/ffmpeg/AWS locally.

Auth + base URL

cloud reuses the credential resolved by hyperframes auth status. Override the API base for staging tests with HEYGEN_API_URL (default https://api.heygen.com).

hyperframes lambda

Deploy HyperFrames distributed rendering to AWS Lambda and drive renders from your laptop or CI. The hyperframes lambda command group wraps the @hyperframes/aws-lambda SDK plus AWS SAM so an end-to-end render is three commands:

Prerequisites

  • AWS credentials configured (env vars, ~/.aws/credentials, SSO, or IMDS).
  • AWS SAM CLI on PATH.
  • bun on PATH (used to build the Lambda handler ZIP).

Subcommands

lambda deploy

Builds packages/aws-lambda/dist/handler.zip and SAM-deploys the stack at examples/aws-lambda/template.yaml. On success, writes <cwd>/.hyperframes/lambda-stack-<stackName>.json so the other subcommands don’t need to re-derive the bucket / state-machine ARN.
Idempotent — re-running on the same --stack-name resolves to a no-op when nothing changed.

lambda sites create <projectDir>

Tars + uploads <projectDir> to S3 with a content-addressed key. Returns a siteId you can reuse across multiple renders so a re-render of the same tree skips the upload.

lambda render <projectDir>

Starts a Step Functions execution. Returns immediately with a renderId (use lambda progress to poll) unless --wait is set, in which case the CLI blocks until the render finishes and streams per-chunk progress lines.
--json swaps the human-readable output for a machine-parseable JSON snapshot. The composition can be parameterised with --variables / --variables-file, mirroring the local hyperframes render flags. Variables flow into the Step Functions execution input and reach every chunk worker as window.__hfVariables. Mismatches against the composition’s data-composition-variables declaration print as warnings; pass --strict-variables to fail the command instead.
Variables travel inside the Step Functions Standard execution input, which AWS caps at 256 KiB for the entire payload. Pass typed data (strings, numbers, structured records) through variables; URL-reference media assets (images, audio, video) the composition resolves at render time rather than inlining bytes. The SDK validates the size client-side and rejects oversize inputs with a clear error before any AWS call runs — see the templates-on-lambda guide for the URL-your-assets convention.

lambda render-batch <projectDir>

Fans out N personalised renders from a JSONL batch file — the headline ergonomic for automated template-rendering pipelines. Deploys the site once (or skips with --site-id), then invokes renderToLambda per batch row with per-entry variables and outputKey. Concurrent Step Functions starts are capped at --max-concurrent (default 50) so a 10 000-entry batch doesn’t try to spawn 10 000 executions at once and trip AWS account limits. Batch file format (JSONL — one JSON object per line):
The verb prints a manifest — one row per input line — with executionArn + status:
Pass --json for the machine-readable form. Poll each execution via hyperframes lambda progress <renderId> (or use the returned executionArn). --dry-run skips the AWS calls and prints the manifest with status: "would-invoke" for every entry — use it to lint the batch file before committing to N billable executions:
--max-concurrent is orchestrator-side only: it caps how many StartExecution calls run simultaneously, not how many Lambda invocations the account can run. AWS account-level Lambda concurrency limits live one level up and render-batch cannot enforce them; pick --max-concurrent based on your account’s concurrent-execution quota and the Lambda reserved concurrency you provisioned via lambda deploy --concurrency=<N>.

lambda progress <renderId | executionArn>

Prints one progress snapshot — overall percent, frames rendered, Lambda invocations, accrued cost, and any errors. Accepts either a bare renderId (resolved against the stack’s state-machine ARN) or a full SFN execution ARN.

lambda destroy

Calls sam delete --no-prompts and drops the local state file. The render S3 bucket is configured with CloudFormation Retain so it survives destruction — empty and delete it via the AWS console / CLI if you want the storage back.

lambda policies role | user | validate

Print or validate the minimum IAM policy the CLI needs to deploy / invoke / destroy the stack.
validate reads the JSON doc and checks the union of its Effect: Allow actions against the CLI’s required action set, expanding s3:* / s3:Get* / * wildcards. Missing actions print to stderr and the command exits non-zero — wire it into CI to catch drift before the next deploy fails. The actions list is deliberately broad (Resource: "*") because CloudFormation creates new function / state-machine / bucket ARNs on every adopter’s first deploy. Adopters with stricter security postures should narrow Resource to the deployed ARNs after the first successful run.

State files

hyperframes lambda keeps per-stack metadata under <cwd>/.hyperframes/lambda-stack-<name>.json so the verbs don’t need to call describe-stacks every time. Commit the file to a repo or .gitignore it depending on your workflow — it contains the bucket name, state-machine ARN, and region, none of which are secrets but all of which are AWS-account-identifying.

hyperframes cloudrun

The Google Cloud counterpart to hyperframes lambda. Deploys HyperFrames distributed rendering to Cloud Run + Cloud Workflows and drives renders from your laptop or CI. Wraps the @hyperframes/gcp-cloud-run SDK plus terraform (the module shipped with the package) and gcloud / Cloud Build for the image.

cloudrun deploy

Enables the required APIs, builds + pushes the render image via Cloud Build (unless you pass --image), then terraform applys the module that provisions the GCS bucket, Cloud Run service, Cloud Workflows definition, two service accounts, and a runaway-request alert. Caches the resulting bucket / service URL / workflow id so later verbs don’t need them re-passed.
Flags: --project (required), --region (default us-central1), --image (skip the build), --repo (Artifact Registry repo, default hyperframes). Machine sizing / scaling: --cpu (1/2/4/8, default 4), --memory (e.g. 32Gi, default 16Gi), --max-instances (render fan-out ceiling, default 100), --timeout (per-request seconds, max 3600). Omitted sizing flags keep the module defaults; for anything finer, apply the Terraform module directly.

cloudrun sites create <projectDir>

Tar + upload a project to GCS once and reuse it across renders. --site-id overrides the content hash. Prints the gs:// URI.

cloudrun render <projectDir>

Start a distributed render. --width / --height are required; --fps (24/30/60), --format, --codec, --quality, --chunk-size, --max-parallel-chunks, --target-chunk-frames, and --output-resolution (deviceScaleFactor supersampling, e.g. 4k) mirror the local render flags. --target-chunk-frames caps the frames per chunk so a single chunk can’t run past a per-chunk timeout on a long video: the planner uses the fewest chunks that keep each at or below the bound, up to --max-parallel-chunks, and short videos still collapse to fewer chunks. It’s a ceiling, not a fixed size, and is ignored when --chunk-size is set. Pass composition variables with --variables '{"title":"Hi"}' or --variables-file alice.json; add --strict-variables to fail on a key that’s undeclared or mistyped vs the composition’s data-composition-variables. --wait polls until the render finishes and prints the output URI + cost; without it the command returns an execution name.

cloudrun render-batch <projectDir>

Fan out N personalised renders from a JSONL batch file (--batch users.jsonl, one {"outputKey":"...","variables":{...}} per line). Deploys the site once and starts an execution per entry, capped at --max-concurrent (default 50). --dry-run prints the resolved manifest without starting anything. Shares the render flags above.

cloudrun progress <executionName>

Print progress + cost for an in-flight or finished render. Coarse running progress; exact frame counts + cost on success.

cloudrun destroy

terraform destroy the stack (force-destroys the render bucket). Reads the cached project/region, or pass --project / --region.

When to pick cloudrun vs lambda

Same trade-off as lambda, on Google Cloud instead of AWS. Pick cloudrun when your backend + storage already live on GCP. The render primitives are identical; only the storage (GCS), compute (Cloud Run), and orchestration (Cloud Workflows) adapters differ.

State file

hyperframes cloudrun caches the deployed stack’s coordinates under ~/.hyperframes/cloudrun-state.json (project id, region, bucket, service URL, workflow id) so render / progress / destroy don’t need them re-passed. None are secrets, but all are GCP-project-identifying.

hyperframes.json

hyperframes init writes a hyperframes.json file at the root of every new project. hyperframes add reads it to know which registry to pull items from and where to drop them. Edit the file (or delete it to fall back to defaults) to reshape your project layout or point at a custom registry.
Missing fields are filled with defaults — you only need to specify what you want to override.

Producer

The rendering pipeline the CLI calls under the hood. Use directly for programmatic rendering.

Studio

The editor UI that powers hyperframes preview. Use directly to embed in your own app.

Core

Types, linter, and runtime. Use directly for custom tooling and integrations.

Engine

The capture engine. Use directly for custom frame capture pipelines.