Skip to main content
If you’re already running a different framework that deploys a serverless video renderer with one command, the muscle memory translates cleanly: a single deploy provisions the stack, a single render starts a render, a single progress polls it, and a single destroy tears the stack down. This page maps your existing concepts onto HyperFrames’ equivalents so you can spend the migration on the parts that actually differ instead of relearning the workflow.

Concept mapping

Composition format

If your current framework is React-based, you write JSX components, register them in a Composition, and the renderer compiles them at render time. In HyperFrames, compositions are plain HTML files. A composition element declares its ID and canvas, while clips declare their own timing. There is no JSX compilation step.
For framework-agnostic animation, HyperFrames supports first-party adapters for GSAP, Anime.js, CSS keyframes, Lottie, Three.js, and the Web Animations API — covered in the Concepts and per-skill docs.

Render config

Most adopters’ render config maps directly:

Variables (inputProps)

Render-time payloads — inputProps in some frameworks, variables in HyperFrames — are isomorphic. Declare the composition’s variable shape on its root [data-composition-id] element via data-composition-variables, then pass per-render values with hyperframes render --variables '{...}' locally or hyperframes lambda render --variables on the Lambda surface. The Lambda execution input is capped at 256 KiB, so reference large assets by URL instead of embedding base64 data. The full mapping — defaultProps → declarations, useCurrentFrame() + props.<x>__hyperframes.getVariables().<x>, renderMediaOnLambda({ inputProps })renderToLambda({ config: { variables } }) — lives in Templates on Lambda.

What HyperFrames does differently

A few areas where the contract is intentionally different from comparable frameworks. Surface them up front so the migration doesn’t surprise you mid-deploy.

Deterministic Chrome path is mandatory

HyperFrames refuses data-gpu-mode="hardware" in distributed mode — hardware GL is non-deterministic across chunk boundaries, and the per-chunk concat-copy assumes byte-level reproducibility. Compositions that opt into hardware GL in-process must drop it for Lambda renders. The Lambda handler trips a typed BROWSER_GPU_NOT_SOFTWARE non-retryable error on plan that’s easy to catch in the progress output.

Font fetching fails closed

failClosedFontFetch is default-on in distributed mode. A composition that references a font-family HyperFrames can’t fetch will fail at plan time (FONT_FETCH_FAILED) rather than silently falling back to the OS default. If you currently lean on system-font fallbacks, list the fonts you need explicitly via <link rel="stylesheet"> or @fontsource/* imports.

HDR is not supported

hdrMode: 'force-hdr' is rejected at plan time. Use the in-process renderer outside Lambda for HDR output.

webm uses closed-GOP VP9

webm distributed renders go through libvpx-vp9 with -g <chunkSize>, -keyint_min <chunkSize>, -auto-alt-ref 0, and -cpu-used 4 by default. The alt-ref disable is the load-bearing bit: libvpx-vp9’s default non-displayable alt-ref frames can land anywhere in a GOP, which breaks concat-copy at chunk seams. Closed-GOP forces a keyframe at every chunk boundary so ffmpeg -f concat -c copy round-trips losslessly. Output is yuva420p to preserve alpha. Audio is muxed as Opus. Distributed WebM can be larger than the same composition rendered in one pass because closed-GOP encoding forces more keyframes. VP9 encode speed is controlled by PRODUCER_VP9_CPU_USED (-8 to 8); use lower values for quality-sensitive or long-form WebM, and higher values when wall-clock encode time matters more than compression efficiency. Benchmark local and distributed rendering with the actual composition before choosing a path.

State files are local by default

hyperframes lambda deploy writes <cwd>/.hyperframes/lambda-stack-<name>.json so subsequent verbs don’t re-derive the bucket / state-machine ARN. Two worktrees produce two distinct state files. If you need a shared default location across CI workers, symlink the directory or pass --stack-name explicitly on every call.

IAM policy is print-then-narrow

The default policy doc emitted by hyperframes lambda policies user/role uses Resource: "*" because the CloudFormation stack creates new ARNs on every adopter’s first deploy. After your first successful deploy, narrow the Resource to the deployed ARNs — they’re predictable from the CFN outputs. CI users typically check the narrowed policy into source and run hyperframes lambda policies validate ./infra/policy.json as a pre-deploy gate.

Migration checklist

  1. Inventory the compositions you want to migrate. Filter out anything that needs HDR — that stays on your current framework for now. webm renders distributed via closed-GOP VP9 + concat-copy (see the webm section above).
  2. Translate each composition to plain HTML. The [Concepts](/concepts) page covers the data-attribute conventions; installing the skills (npx hyperframes skills update) makes Claude / Cursor / Codex aware of them too — start at /hyperframes, which routes to /hyperframes-core for the composition contract.
  3. Wire the new composition into your build pipeline alongside the old one. HyperFrames doesn’t need an external bundler — you can npx hyperframes preview against the HTML directly.
  4. Deploy in a separate AWS account or with a --stack-name=hyperframes-staging first. Run a real render with --wait; verify the output bytes.
  5. Add the policy to your CI. hyperframes lambda policies user > infra/iam/hyperframes.json then hyperframes lambda policies validate infra/iam/hyperframes.json on every PR.
  6. Cut over by pointing your existing automation at the new render endpoint. Keep the old deployment alive until you’ve verified rolling renders for a release cycle, then hyperframes lambda destroy the staging stack and decommission the previous one.

Non-Lambda runtimes

If you don’t want Lambda specifically, the same @hyperframes/producer/distributed primitives run anywhere Node + Chrome + ffmpeg + S3 are available. A reference Dockerfile lives at examples/k8s-jobs/Dockerfile.example for adopters running on:
  • Google Cloud Run Jobs
  • Azure Container Apps Jobs
  • AWS ECS Fargate
  • Kubernetes Jobs / Argo Workflows
  • Plain Docker on a beefy VM
Build it yourself — we don’t publish a Docker image to a registry. The Dockerfile is documented inline and bakes Node 22 + chrome-headless-shell + ffmpeg + the producer at the version your checkout is on.