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

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 installs AI coding skills for Claude Code, Gemini CLI, and Codex CLI (use --skip-skills to disable). See skills command.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 — extract screenshots, design tokens, fonts, assets, and animations for video production:
The capture command extracts everything an AI agent needs to understand a website’s visual identity: viewport screenshots at every scroll depth, color palette (pixel-sampled + DOM computed), font files, images with semantic names, SVGs, Lottie animations, video previews, WebGL shaders, visible text, and page structure.Output is a self-contained directory with a CLAUDE.md file that any AI agent can read to understand the captured site. Used by the /product-launch-video workflow as step 1 of the video production pipeline.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 Website to Video guide for details.

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 --api-key

Save a HeyGen API key. 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 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 .git, node_modules, dist, .next, coverage, dotfiles), uploads it via POST /v3/assets, submits POST /v3/hyperframes/renders, polls GET /v3/hyperframes/renders/{id} until the render completes or fails, and streams the resulting video to disk. 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.