Skip to main content
This page lists every command and every flag. If you are still deciding which command you need, the CLI guide is the shorter route. The installed version is always the authority. Run npx hyperframes <command> --help to see exactly what your copy accepts.

Find your command

validate, inspect, and layout still work but are deprecated. Use check instead.

What every command shares

Read this once and skip the repetition below. The project directory. Most commands take it as the first argument and default to the current directory: npx hyperframes check ./my-video. A few take it as a flag instead — add, transcribe, feedback, and skills use --dir. --json for agents and scripts. Almost every command accepts it. The payload is wrapped with a _meta field so a script can spot an outdated CLI from any command’s output, without a second call:
The version numbers come from a cache refreshed at most once a day. --json never makes a network request of its own. Deprecated commands add _meta.deprecated: true. Flags, not prompts. A missing required flag fails immediately with a usage example rather than waiting for input. Two commands are interactive on a TTY: init prompts for a project name and example unless you pass --non-interactive, and catalog --human-friendly opens a picker. Nothing else prompts, apart from confirmations you can skip with --yes or --no-confirm. Version notices. An owned install (npm, bun, pnpm, brew) updates itself quietly in the background and prints one line on the next run: hyperframes auto-updated to v0.1.5. It never crosses a major version. Anywhere it cannot install — npx, an unknown installer — you get a notice instead:
Both stay silent in CI and non-TTY shells. HYPERFRAMES_NO_UPDATE_CHECK=1 turns off the check, the install, and the notice.

Create a project

init

Scaffold a new composition project from an example.
Pass --video or --audio and the CLI transcribes the audio with Whisper and patches the captions into the composition for you. --skip-transcribe turns that off. --tailwind injects the pinned Tailwind v4 browser runtime 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 patterns. The browser runtime is meant for scaffolded projects and quick iteration — for offline or locked-down production renders, compile Tailwind to CSS and link the stylesheet. After scaffolding, init checks and installs the core AI skills from the current GitHub source. See skills.

add

Install one item from the registry into a project you already have. init scaffolds whole projects; add drops in a block (a sub-composition scene) or a component (an effect or snippet).
The positional name is a registry item, or a tag — a tag installs every block carrying it. --dir picks the project directory, --json prints the written files and paste snippet, and --no-clipboard skips the clipboard copy for CI. Every install produces files plus a paste snippet: the <iframe> tag for a block, or the fragment path for a component. It goes to your clipboard by default. Naming an example instead of a registry item (add warm-grain) gets you a clear error pointing at init --example. add reads hyperframes.json to learn which registry to pull from and where files land. If it is missing but the directory has an index.html, a default one is written on first use.

catalog

Browse the registry.
Filter with --type (block or component) and --tag (social, transition, text, …). Default output is a table of name, type, description, and tags, shaped for agents to parse; --json is the structured form. --human-friendly opens a picker that runs add on whatever you select.

Bring in source material

capture

Pull a real website into a working folder an agent can build from.
You get AGENTS.md, CLAUDE.md, meta.json, scroll screenshots, extracted HTML and CSS, visible text, design tokens, font files, images, SVGs, animation metadata, and contact sheets — plus whatever Lottie, video, and WebGL context the page exposed. It is raw material for an agent, not a finished composition; the /product-launch-video workflow uses it when a real product has to appear on screen. Dynamic sites, protected pages, and unusual media loaders produce partial results, so read the warnings and contact sheets before you build. For AI image descriptions, set GEMINI_API_KEY in a .env file (~$0.001/image), or OPENROUTER_API_KEY to route any vision model through OpenRouter — it wins if both are set, and HYPERFRAMES_OPENROUTER_MODEL overrides the model.

transcribe

Turn audio or video into word-level timestamps, or import a transcript you already have.
The command works out what you gave it. Audio and video are transcribed locally — Parakeet when it is installed (uv pip install parakeet-mlx; faster and more accurate), whisper.cpp otherwise. Transcript files are imported and normalized instead: whisper.cpp JSON, OpenAI Whisper API JSON with word timestamps, SRT, and VTT all land as the same [{text, start, end}] word array in transcript.json. If the project has caption HTML, it is patched automatically. Word-level transcripts get grouped into readable cues at sentence boundaries. Exporting straight from an .srt or .vtt keeps that file’s cue boundaries. Add --preserve-cues when the source transcript.json already holds finished cues with no internal spaces — single-word or CJK captions.
For music or noisy audio, --model medium.en is noticeably more accurate. For production content, transcribe through the OpenAI or Groq Whisper API and import the JSON.

tts

Generate speech with a local model (Kokoro-82M). No API key, nothing leaves the machine.
A voice ID’s first letter is its language: a American, b British, e Spanish, f French, h Hindi, i Italian, j Japanese, p Brazilian Portuguese, z Mandarin. So --voice ef_dora already speaks Spanish. Reach for --lang only to deliberately mismatch them — English text through a French phonemizer, for a stylized accent.
To get narration and caption timing in one pass: generate the audio with tts, then run transcribe on the result.

remove-background

Cut the background out of a video or image with a local AI model. The output is transparent media you can drop straight into a <video> or <img>. No green screen.
Which format do you want? The model is u2net_human_seg (MIT, ~168 MB ONNX). It downloads to ~/.cache/hyperframes/background-removal/models/ on first run and is reused after that. Peak inference RAM is about 1.5 GB. --device auto picks CoreML on Apple Silicon, CUDA where available, CPU otherwise. The CLI bundles the CPU build of onnxruntime-node; for CUDA, set HYPERFRAMES_CUDA=1 and supply a GPU-enabled build.
Chrome’s <video> only honours the alpha plane when the WebM is yuva420p with the alpha_mode=1 metadata tag. The CLI sets both. If you re-encode the output yourself, keep them.
The Remove background guide has the whole workflow — using transparent video in compositions, per-platform performance, where u2net_human_seg falls down, and free alternatives.

media-treatment

Read or edit the colour and effect treatment stored on one image or video.
The command writes data-color-grading — the same contract Studio, preview, and render all read, so the two can never disagree. It does not recognise subjects or isolate part of an image; the effect covers the whole media layer.

beats

Find the beats in a composition’s music and write them where Studio expects them.
beats finds the music track — an <audio> element with data-timeline-role="music", or an id like music, bgm, or soundtrack — runs the same decode and BPM analysis Studio uses inside headless Chrome, and writes beats/<audio-path>.json:
Run it while authoring, so the file exists before Studio opens — Studio loads this file as-is and only generates one when none exists. time is seconds into the audio; strength (0–1) is relative loudness. Beats you add, move, or delete in Studio save back to the same file. Needs a local Chrome, the same one render uses. Run npx hyperframes browser ensure if it is missing. Results match Studio’s to within a frame or two — a different headless-Chrome audio sample rate can shift a beat slightly.

Look at it

preview

Start a live preview server with hot reload.
To manage running servers: --status and --stop act on this project’s background preview, --list and --kill-all act on all of them, and --force-new starts a second server for a project that already has one. Each exits straight after. To read a running Studio from a script: --selection prints the selected element and --context prints the agent-readable context, both with --json. Narrow the context with --context-fields (server, selection, lint, capabilities) and --context-detail (compact or full). Your composition opens in HyperFrames Studio, and edits to index.html and its sub-compositions refresh live. Preview and render share the same runtime. The server picks one of three modes by itself: embedded (the default for npx — Studio bundled in the CLI, no extra dependencies), local studio (Vite with full HMR, when @hyperframes/studio is in your node_modules), or monorepo (the studio dev server, when you run from the source repo). --background works with the embedded server only.
Preview plays in real time, so paint-heavy compositions can stutter on your machine. Render seeks and captures one frame at a time, so the same work usually means a longer render rather than dropped frames. Browser, font, and GPU differences still move exact pixels — judge the rendered file. See Performance.

present and play

present serves a slideshow and opens its presenter view. The presenter and audience views stay in sync for as long as the command runs.
--port defaults to 3004. --open / --no-open controls the browser, and --browser-path opens a specific one — --user-data-dir and --remote-debugging-port both require it. play opens a composition in the lightweight Player instead of Studio — no editor, just playback. Same flags, --port defaults to 3003, plus --proxy / --no-proxy.

publish

Upload the project and get back a stable hyperframes.dev URL.
publish zips the project, uploads it, and prints a URL that resolves to stored content — so it keeps working after the CLI exits. No local server stays alive, and no tunnel is opened. You can publish while signed out. The printed URL then carries a claim token: whoever opens it on hyperframes.dev can sign in, claim the project, and keep editing in the web app. Sign in with npx hyperframes auth login first when you want an owned, stable link you can publish to again. --update and --space both need that ownership.

Check your work

lint

Read the HTML and report common mistakes. No browser, so it is fast.
Errors () must be fixed before rendering — a missing adapter library, invalid attributes. Warnings () are likely problems. Info () notices are hidden unless you pass --verbose, which keeps output clean for agents and CI. --json adds errorCount, warningCount, infoCount, and a findings array. The linter catches missing attributes, missing adapter libraries (GSAP, Lottie, Three.js), and structural problems. Troubleshooting explains each rule.

check

The browser gate. Everything the old validateinspectsnapshot loop did, in one command and one browser session.
check runs the linter first and skips the browser entirely on a lint error. Then it loads the bundled composition once and sweeps a single seek grid, running every audit at every sample: runtime console errors and failed requests, layout defects (overflow, clipping, held overlaps, occlusion, coordinate-frame drift), *.motion.json assertions, and WCAG AA contrast. Contrast failures are errors, and each one reports the sampled foreground and background colours, the measured ratio against the required one, and a compliant colour you could use instead. Severity is persistence-aware: a finding at a single sample demotes to info, a finding that persists gates the exit code, and a timeline that never moves on a composition of 3s or more fails with sweep_static.

Mark intentional layout choices

When the audit is wrong because the layout is deliberate, say so in the HTML and re-run. Put data-layout-allow-overflow on a planned off-canvas entrance, data-layout-allow-overlap on text you meant to stack, data-layout-allow-occlusion on text you meant to hide behind a prop, and data-layout-ignore on decoration that should not be audited at all. Each is inherited, so an ancestor works. For deliberate lower-third copy under --caption-zone, use data-layout-allow-caption-zone. It silences caption_zone_collision and nothing else — overflow, overlap, occlusion, and contrast still apply. Put it on the narrowest wrapper that owns the band copy.

Verify motion, not just layout

Layout sampling cannot catch a render-≠-preview bug: an entrance the seek lands past, a broken stagger order, an element that drifts off-frame mid-tween, a shot that freezes. Motion assertions can. Drop a *.motion.json sidecar next to the composition and check evaluates it automatically — no flag, no changes to your HTML. Without a sidecar, nothing changes.
duration, keepsMoving.withinSelector, and keepsMoving.maxStaticSec are optional. Findings use the same shape and envelope as layout findings and are errors by default, so a failed assertion fails the run. A selector that matches nothing reports motion_selector_missing rather than quietly passing.

snapshot

Capture specific frames as PNGs, without waiting for a full render.
Each snapshot is a 1920×1080 PNG taken by bundling the project, serving it, launching headless Chrome, and seeking. Useful for visual verification during the product launch video workflow.

keyframes

Show the GSAP, CSS, and Anime.js keyframes actually detected in a composition — or render an onion-skin diagnostic of one element’s motion.
Use --ghost for motion that happens inside a canvas, where the marker onion has nothing to draw.

compare and grade-compare

compare renders two or more independent variants into one labelled PNG.
grade-compare does the same for colour: candidate grades or LUTs applied to one reference frame.

Deprecated: validate, inspect, and layout

All three still run, and all three print a deprecation line on stderr and set _meta.deprecated: true in --json output. validate was the runtime-only browser check; inspect (and its alias layout) was the layout sweep and motion-sidecar pass. check does everything they did, in one browser session, and it is where new work should go. Their flags are unchanged — run npx hyperframes inspect --help if you are maintaining automation that still calls them.

Render to a file

render

Render a composition to MP4, WebM, MOV, GIF, or an RGBA PNG sequence.
The flags that come up most: Quality and file size: How it uses the machine, and when it gives up: Low-memory detection reads host RAM, not cgroup or container limits, so containerised callers — including --docker — should set PRODUCER_LOW_MEMORY_MODE explicitly.

When a render times out

Three separate budgets can expire, and the error message tells you which. All three have environment fallbacks that take milliseconds, even where the flag does not.
  • The page never loaded. --browser-timeout is the Puppeteer navigation budget for the entry HTML, and the flag takes seconds (default 60, range 0.001–86400). Raise it when a composition with many videos, fonts, or asset requests cannot reach domcontentloaded in time. Env: PRODUCER_PAGE_NAVIGATION_TIMEOUT_MS.
  • The player never became ready. After navigation, window.__hf readiness has its own budget: --player-ready-timeout, in ms, default 45000. Env: PRODUCER_PLAYER_READY_TIMEOUT_MS.
  • A single CDP call hung. --protocol-timeout is the per-call budget for seek, paint, and screenshot round-trips, in ms, default 300000. This is the one behind Runtime.callFunctionOn timed out and Target closed. Raise it on hosts with 8 GB RAM or less and on asset-heavy compositions. The default auto-scales with output pixel area, capped at 30 minutes; an explicit value becomes a floor and disables that scaling below it. Env: PRODUCER_PUPPETEER_PROTOCOL_TIMEOUT_MS.

Render the same composition with different content

Declare the variables on the composition root, read them inside it, then override them at render time.
index.html
getVariables() returns the declared defaults merged with any overrides, so the same composition runs unchanged in preview and in production. For many outputs at once, --batch renders one file per row of a JSON array. See Variables for the whole model.

Transparent WebM for overlays

--format webm produces VP9 with an alpha channel — the standard format for overlayable video.
For transparency to survive, your composition’s root elements need background: transparent. WebM renders capture PNG frames rather than JPEG to keep the alpha channel.
Rendering covers every mode in context.

benchmark

Find good render settings for this machine.
It runs several configurations — varying fps, quality, and worker count — and compares time and file size. --runs sets runs per configuration (1–20, default 3); --json prints the results as JSON.

Keep the environment healthy

doctor

Check the machine for everything a render needs.
It reports CLI version, Node.js, CPU, memory, disk, the extracted-frame cache, the archive extractor, /dev/shm on Linux, environment, whisper-cpp, local TTS and BGM models, FFmpeg, FFprobe, Chrome, and Docker. The frames cache row is worth knowing about: it prints the effective cache directory, its free space, and whether the location came from HYPERFRAMES_EXTRACT_CACHE_DIR or the default. Under 2 GB free it fails, since a long render can fill the drive from there. Move it with that variable or render --frames-cache-dir. Gating CI on it. doctor --json always exits 0 when it ran successfully — the command worked, whatever it found. Environment health lives in the payload’s ok field, so a new CLI release (which flips the version row to not-ok) can never break your pipeline. Gate on the payload:
In JSON mode, paths inside detail and hint are redacted — your home directory becomes the literal $HOME, so output is safe to paste into a bug report or an agent context.

info and compositions

npx hyperframes info [dir] prints project metadata: name, resolution, duration, element counts by type, track count, and total size. npx hyperframes compositions lists every composition in the project with its ID, duration, resolution, and element count. Both take --json.

upgrade

upgrade compares your installed version against npm. --check exits without prompting, --yes, -y upgrades a detected global install (otherwise it prints the right npx command), and --project [dir] rewrites hyperframes@<version> script pins in a project’s package.json. --check --json returns:

browser

Manage the Chrome that rendering uses.
path prints only the path, so it composes: $(npx hyperframes browser path). Use --force when a download was interrupted and left a partial file behind.

docs

Read documentation in the terminal.
Topics: data-attributes, examples, rendering, gsap, troubleshooting, compositions. Run it bare to list them.

feedback

Send anonymous feedback about how it went.
--rating is required, 0–10. --comment adds free text. --file-issue also opens a GitHub issue, --dir picks the project published as its repro (default: current directory), and --yes, -y skips the consent prompt for scripts. With --file-issue, the CLI publishes a minimal repro to a public URL — with your consent — and opens a pre-filled bug issue draft that you review and submit yourself. No token, no backend. See Share feedback. Agents can call this after a render; About feedback data covers what the surface includes. With telemetry disabled it prints Telemetry is disabled. Feedback not sent. and exits cleanly.

telemetry

Telemetry collects command names, render performance, render checkpoint and error names, aggregate browser diagnostic counts, browser initialization duration and tween count, aggregate video-extraction workload counts (extracted frames, VFR preflights), example choices, and system info — including a coarse environment fingerprint: OS, kernel string, CPU and memory shape, sandbox runtime such as gVisor or Docker, and the name of a coding agent driving the CLI when one is detected (claude_code, codex, cursor). That name is inferred from which well-known environment variables exist; their values are never read. Local paths and URL query strings are redacted from error and checkpoint messages. Project names, video content, and environment variable values are never collected. Nothing personally identifying is collected until you sign in. When you run hyperframes auth login, your HeyGen account email — or username, if the account has no email — is linked to your usage, and your prior anonymous usage is stitched to it. Nothing else personal, and only once you choose to sign in. Turn it all off with HYPERFRAMES_NO_TELEMETRY=1 or the command above. Feedback collection explains the post-render prompt and the Studio feedback bar. One consequence worth knowing: 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 that AI coding tools read.
Bare skills installs everything. skills update keeps a deliberate partial installation partial: it refreshes the core set plus whatever is already installed, and never expands beyond that unless you name a workflow. Naming one adds it. check and update both accept --json, plus --dir and --source to point removed-detection at a different skills directory or source — those two scope the prune, not the install. The CLI installs from the current HyperFrames GitHub source and links the global bundles into whichever compatible agents it finds. After scaffolding, init also refreshes the core set plus any HyperFrames skills you already have.

fatal: active post-checkout hook found during git clone

If Git LFS is installed globally, Git 2.45+ refuses to run the LFS post-checkout hook during any git clone — including the clone the upstream skills CLI does internally:
hyperframes skills already handles this. You do not need an environment variable. If you called the upstream command directly instead, set it yourself:

figma and events

npx hyperframes figma imports through the Figma REST API, with three subcommands: asset (export an image or SVG), tokens (pull design tokens), and component (import an editable component). Run it bare for usage. See Figma integration for setup and examples. npx hyperframes events lets an installed workflow skill emit an anonymous usage event (--skill, --event, --outcome). Nothing calls it by hand.

hyperframes auth

Sign in to HeyGen and manage credentials. They live in ~/.heygen/credentials (mode 0600) and are shared with the heygen CLI — sign in with one and the other picks up the session. First match wins:
  1. HEYGEN_API_KEY
  2. HYPERFRAMES_API_KEY (a HyperFrames alias for the same thing)
  3. ~/.heygen/credentials

auth login

Opens a browser for OAuth:
Pass --api-key when you want a long-lived HeyGen API key instead. The key is verified against GET /v3/users/me before the command reports success, so a rejected key is never left on disk.

auth status

Shows the active credential’s source and type, and the verified identity — account plus billing snapshot. It exits non-zero when nothing is configured or the API rejects the credential, so a script can test sign-in state.

auth refresh

Force-refreshes the stored OAuth access token. Applies to an OAuth session, not an API key.

auth logout

Removes the stored credential, with a confirmation on a TTY.

Environment variables

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

hyperframes cloud

Render on HeyGen’s hosted cloud. No local Chrome, no local ffmpeg, no AWS to manage. Sign in once and the same credential drives every subcommand.

cloud render [<projectDir>]

End to end: zips the project, uploads it through the direct-to-S3 asset flow, submits POST /v3/hyperframes/renders, polls GET /v3/hyperframes/renders/{id} until it finishes or fails, and streams the video to disk. The zip excludes root renders and snapshots, .git, node_modules, dist, .next, coverage, dotfiles, and anything your .hyperframesignore rules match. Those rules use gitignore syntax and apply to hyperframes publish too. Keep them narrow — a dynamically selected asset may have no static reference to protect it. The zip has to come in under 200 MB — the direct-upload cap. Use --dry-run first to see the compressed size and the largest included files, without authenticating, uploading, or starting anything. If you are over, add only paths you have verified are unneeded to .hyperframesignore, or pre-host the large media and reference it by URL. Render parameters mirror local hyperframes render where they overlap: Lifecycle and control:

Why you want --idempotency-key

On a 401, the CLI force-refreshes the OAuth token and replays the request. For reads that is harmless. But POST /v3/assets — the zip upload — is not idempotent on its own, so a retry without a key would create a duplicate asset and bill the workspace twice. Pass --idempotency-key <key> whenever you want safe retries. It is forwarded to both the upload and the submit, and the server scopes idempotency per endpoint, so reusing one value across both steps is safe and prevents a duplicate at either. Use a UUID per logical render, or any opaque string.

cloud list

Pages through recent renders, cursor-based. --limit caps one page (1–100, default 10), --token resumes from a previous next_token, and --all walks until exhausted. --json for the machine-readable form.

cloud get <render_id>

Fetches one render’s full detail record, including the short-lived signed video_url and thumbnail_url. Those are presigned S3 URLs — re-fetch on demand rather than caching them.

cloud delete <render_id>

Soft-deletes a render. Later GET calls return 404 and the signed video URL stops working shortly after. It prompts interactively; --no-confirm skips that, and is required alongside --json.

Which one should you use?

  • hyperframes render — the fastest loop. Use it while authoring.
  • hyperframes cloud render — zero infrastructure. HeyGen runs it, you pay per credit. Use it when you do not want Chrome, ffmpeg, or AWS on your machine.
  • hyperframes lambda render — your own AWS, chunked in parallel. Use it when you have already invested in AWS and want the work on your account.
cloud reuses whatever credential hyperframes auth status resolves. Override the API base for staging with HEYGEN_API_URL.

hyperframes lambda

Deploy distributed rendering to AWS Lambda and drive it from your laptop or CI. The command group wraps the @hyperframes/aws-lambda SDK plus AWS SAM, so an end-to-end render is three commands:
You need AWS credentials (env vars, ~/.aws/credentials, SSO, or IMDS), the AWS SAM CLI on PATH, and bun on PATH to build the handler ZIP. Flags are shared across the whole group. These identify the stack and shape the deploy: And these drive render and render-batch:

lambda deploy

Builds packages/aws-lambda/dist/handler.zip and SAM-deploys the stack at examples/aws-lambda/template.yaml. On success it writes <cwd>/.hyperframes/lambda-stack-<stackName>.json, so the other subcommands do not have to re-derive the bucket and state-machine ARN. Re-running on the same --stack-name is a no-op when nothing changed.

lambda sites create <projectDir>

Tars and uploads the project to S3 under a content-addressed key, and returns a siteId you can reuse. A re-render of the same tree then skips the upload.

lambda render <projectDir>

Starts a Step Functions execution and returns a renderId immediately — poll it with lambda progress — unless you pass --wait.
Variables travel inside the Step Functions Standard execution input, which AWS caps at 256 KiB for the whole payload. So pass typed data through variables — strings, numbers, records — and reference media by URL for the composition to resolve at render time, rather than inlining bytes. The SDK checks the size client-side and rejects an oversize input with a clear error before any AWS call runs. The templates-on-lambda guide explains 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 pipelines. It deploys the site once (or skips that with --site-id), then invokes renderToLambda per row with that row’s variables and outputKey.
It prints one row per input line, with the executionArn and status:
Poll each one with hyperframes lambda progress <renderId>, or use the returned executionArn. Run it with --dry-run first to lint the batch file before committing to N billable executions — every entry comes back as status: "would-invoke". --max-concurrent (default 50) caps StartExecution calls, so a 10,000-entry batch does not try to spawn 10,000 executions and trip your account limits. It is orchestrator-side only, and cannot enforce your account’s Lambda concurrency quota — pick a value from that quota and the reserved concurrency you set at lambda deploy --concurrency=<N>. It is not --max-parallel-chunks, which caps chunks inside one render.

lambda progress <renderId | executionArn>

Prints one snapshot: overall percent, frames rendered, Lambda invocations, accrued cost, and any errors. A bare renderId is resolved against the stack’s state-machine ARN; a full SFN execution ARN also works.

lambda destroy

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

lambda policies role | user | validate

Prints or validates the minimum IAM policy the CLI needs.
validate reads the JSON doc and checks the union of its Effect: Allow actions against what the CLI needs, expanding s3:*, s3:Get*, and * wildcards. Missing actions print to stderr and it exits non-zero — wire it into CI to catch drift before the next deploy fails. The action list is deliberately broad (Resource: "*") because CloudFormation mints new function, state-machine, and bucket ARNs on every adopter’s first deploy. Narrow Resource to the deployed ARNs after that first success if your security posture calls for it.

State files

hyperframes lambda keeps per-stack metadata under <cwd>/.hyperframes/lambda-stack-<name>.json, so the verbs never have to call describe-stacks. Commit it or .gitignore it as you prefer — it holds the bucket name, state-machine ARN, and region. None are secrets, but all identify your AWS account.

hyperframes cloudrun

The Google Cloud counterpart to lambda: distributed rendering on Cloud Run plus Cloud Workflows, driven from your laptop or CI. It wraps the @hyperframes/gcp-cloud-run SDK plus terraform (the module shipped with the package) and gcloud or Cloud Build for the image.
deploy enables the required APIs, builds and 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. It caches the bucket, service URL, and workflow id so later verbs do not need them again. --project is required; --region defaults to us-central1 and --repo (the Artifact Registry repo) to hyperframes. Sizing is --cpu (1, 2, 4, or 8; default 4), --memory (default 16Gi), --max-instances (the fan-out ceiling, default 100), and --timeout (per-request seconds, max 3600). Omit one and the module default stands; for anything finer, apply the Terraform module directly. The other verbs mirror lambda one for one, and so do their flags:
  • sites create <projectDir> uploads a project to GCS once and prints the gs:// URI.
  • render <projectDir> starts a distributed render. --width and --height are required, and --render-id stands in for --execution-name.
  • render-batch <projectDir> fans out from a JSONL file.
  • progress <executionName> prints progress and cost — coarse while running, exact on success.
  • destroy runs terraform destroy and force-destroys the render bucket.
Pick cloudrun when your backend and storage already live on GCP. The render primitives are identical; only the storage (GCS), compute (Cloud Run), and orchestration (Cloud Workflows) adapters differ. The deployed stack’s coordinates cache in ~/.hyperframes/cloudrun-state.json — project id, region, bucket, service URL, workflow id. None are secrets, but all identify your GCP project. Google Cloud Run has the full walkthrough.

hyperframes.json

hyperframes init writes a hyperframes.json at the root of every new project, and hyperframes add reads it to learn which registry to pull from and where files go. Edit it to reshape your layout or point at a custom registry — or delete it to fall back to the defaults.
Anything you leave out gets the default, so the file only needs your overrides.

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.