Files
wehub-resource-sync 85453da49f
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
Docs / Validate docs (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (python) (push) Waiting to run
Sync skills to ClawHub / Publish changed skills (push) Waiting to run
regression / regression-shards (style-16-prod style-9-prod style-17-prod iframe-render-compat variables-prod mp4-h265-sdr, shard-4) (push) Has been cancelled
regression / regression-shards (style-4-prod style-11-prod style-2-prod animejs-adapter typegpu-adapter parallel-capture-regression, shard-5) (push) Has been cancelled
regression / regression-shards (style-7-prod style-8-prod style-10-prod css-spinner-render-compat webm-transparency mp4-h264-sdr webm-vp9, shard-3) (push) Has been cancelled
regression / regression-shards (sub-composition-video style-18-prod raf-ball-render-compat font-variant-numeric sub-comp-t0 sub-comp-id-selector, shard-7) (push) Has been cancelled
Windows render verification / Detect changes (push) Has been cancelled
Windows render verification / Preflight (lint + format) (push) Has been cancelled
Windows render verification / Render on windows-latest (push) Has been cancelled
Windows render verification / Tests on windows-latest (push) Has been cancelled
CI / Detect changes (push) Has been cancelled
CI / Build (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Fallow audit (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Typecheck (push) Has been cancelled
CI / Test (push) Has been cancelled
CI / Producer: integration tests (push) Has been cancelled
CI / Producer: unit tests (push) Has been cancelled
CI / File size check (push) Has been cancelled
CI / Test: skills (push) Has been cancelled
CI / Skills: manifest in sync (push) Has been cancelled
CI / CLI: npx shim (macos-latest) (push) Has been cancelled
CI / CLI: npx shim (ubuntu-latest) (push) Has been cancelled
CI / CLI: npx shim (windows-latest) (push) Has been cancelled
CI / SDK: unit + contract + smoke (push) Has been cancelled
CI / Test: runtime contract (push) Has been cancelled
CI / Studio: load smoke (push) Has been cancelled
CI / Smoke: global install (push) Has been cancelled
CI / CLI smoke (required) (push) Has been cancelled
CI / Semantic PR title (push) Has been cancelled
Player perf / Detect changes (push) Has been cancelled
Player perf / Preflight (lint + format) (push) Has been cancelled
Player perf / player-perf (push) Has been cancelled
Player perf / Perf: drift (push) Has been cancelled
Player perf / Perf: fps (push) Has been cancelled
Player perf / Perf: parity (push) Has been cancelled
Player perf / Perf: scrub (push) Has been cancelled
Player perf / Perf: load (push) Has been cancelled
preview-regression / Detect changes (push) Has been cancelled
preview-regression / Preflight (lint + format) (push) Has been cancelled
preview-regression / Preview parity (push) Has been cancelled
preview-regression / preview-regression (push) Has been cancelled
regression / regression (push) Has been cancelled
regression / Detect changes (push) Has been cancelled
regression / Preflight (lint + format) (push) Has been cancelled
regression / regression-shards (hdr-regression style-5-prod style-3-prod mov-prores, shard-1) (push) Has been cancelled
regression / regression-shards (overlay-montage-prod style-12-prod chat missing-host-comp-id png-sequence portrait-edge-bleed, shard-6) (push) Has been cancelled
regression / regression-shards (style-13-prod style-6-prod vignelli-stacking gsap-letters-render-compat audio-mux-parity, shard-8) (push) Has been cancelled
regression / regression-shards (style-15-prod hdr-hlg-regression style-1-prod many-cuts vfr-screen-recording render-symlinked-assets, shard-2) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:58:35 +08:00

185 lines
11 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: Deploy
description: "Run a Hyperframes preview + render API in the cloud from an official template."
---
Hyperframes ships three official deployment templates that wrap a composition in a small web app: an in-browser preview and a `/api/render` endpoint that produces an MP4 server-side. All are open source, Apache-2.0 — Vercel and Cloudflare deploy from a single button, Modal from a single `modal deploy`.
| Template | Compute | Storage | Deploy |
|----------|---------|---------|--------|
| [Vercel](https://github.com/heygen-com/hyperframes-vercel-template) | [Vercel Sandbox](https://vercel.com/docs/vercel-sandbox) (Firecracker microVM) | [Vercel Blob](https://vercel.com/docs/vercel-blob) | [vercel.com/templates/ai/hyperframes-on-vercel](https://vercel.com/templates/ai/hyperframes-on-vercel) |
| [Cloudflare](https://github.com/heygen-com/hyperframes-cloudflare-template) | [Cloudflare Containers](https://developers.cloudflare.com/containers/) (Workers + Durable Object) | [R2](https://developers.cloudflare.com/r2/) | One-click button in the repo README |
| [Modal](https://github.com/heygen-com/hyperframes-modal-template) | [Modal Functions](https://modal.com/docs/guide/webhooks) (serverless containers, scale-to-zero) | [Modal Volume](https://modal.com/docs/guide/volumes) | `modal deploy src/app.py` |
All three templates use the same shape:
- **Preview** the bundled `ui-3d-reveal` composition in the browser via the [`<hyperframes-player>`](/packages/player) web component.
- **Render** to MP4 by POSTing to `/api/render`. The handler ships the composition to a sandboxed runtime that has Chromium, FFmpeg, and `hyperframes` pre-installed, then streams the MP4 back to storage and returns a URL.
- **Author locally**, deploy the preview + render API. Compositions are still built on your machine with `npx hyperframes init`, then dropped into the template's compositions directory.
## Choosing a template
<Tabs>
<Tab title="Vercel">
Pick this if you already deploy on Vercel, want zero-config Blob storage, or want to reuse Vercel's CI/preview environments.
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fheygen-com%2Fhyperframes-vercel-template&stores=%5B%7B%22type%22%3A%22blob%22%2C%22access%22%3A%22public%22%7D%5D)
**What you get**
- A Next.js app with `<hyperframes-player>` preview and a `POST /api/render` route.
- A pre-baked Vercel Sandbox snapshot built during `next build` — cold renders skip the Chromium/FFmpeg install and restore from snapshot in ~100 ms.
- A Vercel Blob store provisioned automatically on deploy. `BLOB_READ_WRITE_TOKEN` is injected for you.
**Performance**
Renders run on `standard-4` (4 vCPU). With `--workers auto`, three parallel Chrome workers cut render time meaningfully vs. single-worker. Concrete render time depends on composition length, complexity, and asset size.
**Pricing**
Vercel Pro plans include Sandbox credit each month. See [Vercel Sandbox pricing](https://vercel.com/docs/vercel-sandbox/pricing) for current per-vCPU and per-GB rates and the up-to-date credit allowance.
<Note>
Vercel Functions cap at 300s and a 50 MB compressed bundle, which can't fit Chromium + FFmpeg. The template uses Vercel Sandbox specifically because it's the purpose-built primitive for this workload — up to 5 hours of runtime and up to 8 vCPUs per render.
</Note>
</Tab>
<Tab title="Cloudflare">
Pick this if you're already on Cloudflare Workers, want R2's free egress, or want full control over the renderer image.
[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/heygen-com/hyperframes-cloudflare-template)
**What you get**
- A Worker that serves preview HTML and forwards `/api/render` requests to a `RenderContainer` Durable Object.
- A pre-built OCI container image with Chromium + FFmpeg + `hyperframes` baked in — no install at request time.
- An R2 bucket (`hyperframes-renders`) provisioned automatically on deploy.
**Performance**
Renders run on `standard-4` (4 vCPU, 12 GiB). With `--workers auto`, three parallel Chrome workers cut render time meaningfully vs. single-worker. Container instances sleep after 10 minutes of inactivity, so the next request after a quiet period pays a cold-start penalty.
**Pricing**
Cloudflare Containers bills per-10ms for memory, CPU, and disk; R2 storage has no egress within Cloudflare's network. Requires a [Workers Paid](https://developers.cloudflare.com/workers/platform/pricing/) plan. See [Cloudflare Containers pricing](https://developers.cloudflare.com/containers/pricing/) and [R2 pricing](https://developers.cloudflare.com/r2/pricing/) for current rates.
<Note>
Cloudflare's hosted [Browser Rendering](https://developers.cloudflare.com/browser-rendering/) API can't install FFmpeg — that's why the template uses Cloudflare Containers, which gives you a real OCI container in a Worker-bound Durable Object with up to 4 vCPUs and 12 GiB RAM.
</Note>
</Tab>
<Tab title="Modal">
Pick this if you already run on Modal, want containers that scale to zero with per-second billing, or want the render to run as a spawned function decoupled from the request.
Modal deploys from the CLI rather than a button:
```bash Terminal
uv sync
source .venv/bin/activate
modal setup # one-time auth
modal deploy src/app.py
```
**What you get**
- A FastAPI app (`@modal.asgi_app`) that serves the `<hyperframes-player>` preview and a `POST /api/render` route.
- A Modal image with Node.js 22, Python 3.12, FFmpeg, `hyperframes`, and `chrome-headless-shell` baked in at build time — no install at request time.
- A Modal Volume (`hyperframes-renders`) that persists the MP4, served back from the `/renders/:name` endpoint.
**Performance**
First deploy takes ~2 min to build the image; subsequent deploys are ~2s. Renders cold-boot in ~1s and containers scale to zero when idle. With `--workers auto`, three parallel Chrome workers cut render time (GPU is disabled via `--no-browser-gpu`). A 12s 1080p30 composition renders in roughly 1090s depending on complexity.
**Pricing**
You pay per second of render time and nothing while idle, since containers scale to zero. See [Modal pricing](https://modal.com/pricing) for current per-CPU and per-GB rates.
<Note>
Modal web endpoints cap at 150s per request, so `POST /api/render` returns a `call_id` immediately and the render runs in a spawned Modal Function (up to 15 min, `timeout=900`). Poll `GET /api/render/:id` — it returns `202` while the render is still running, then the finished MP4.
</Note>
</Tab>
</Tabs>
## Architecture
All three templates follow the same flow: the browser plays a preview locally, then POSTs to a render endpoint that delegates to a sandboxed runtime with Chromium + FFmpeg.
```
Browser Edge / Function Sandboxed renderer
┌──────────────────┐ ┌────────────────────┐ ┌──────────────────────────┐
│ <hyperframes- │ ────▶ │ /api/render │ ────▶ │ hyperframes render │
│ player> │ │ ship composition │ │ (Chromium + FFmpeg, │
│ preview iframe │ │ → renderer │ │ pre-installed) │
│ │ ◀──── │ ← stream MP4 │ ◀──── │ │
│ │ url │ → upload to blob │ mp4 │ │
└──────────────────┘ └────────────────────┘ └──────────────────────────┘
└─▶ Vercel Blob / Cloudflare R2 / Modal Volume
```
The key cost-saver in all three templates is **pre-baking the renderer**. Installing Chromium system libraries plus `chrome-headless-shell` takes 3060s, which would dominate every cold render. Vercel's template snapshots the sandbox at build time; Cloudflare's and Modal's templates bake everything into the container image. All restore in milliseconds and let you spend the entire request budget on actual rendering.
## Swapping the composition
All three templates ship with one bundled composition (`ui-3d-reveal`). To use your own:
<Steps>
<Step title="Author locally">
Compositions are HTML — author them on your machine with the [CLI](/packages/cli):
```bash Terminal
npx hyperframes init my-video
cd my-video
npx hyperframes preview
```
</Step>
<Step title="Drop the bundle into the template">
Copy your composition into the template's compositions directory — `public/compositions/<your-name>/` for Vercel and Cloudflare, `compositions/<your-name>/` for Modal.
</Step>
<Step title="Point the template at it">
- **Vercel**: edit `PREVIEW_COMPOSITION_DIR` at the top of `lib/preview.ts` and the dimensions in `app/page.tsx` if it isn't 1920×1080.
- **Cloudflare**: set `PREVIEW_COMPOSITION_DIR=compositions/<your-name>` when running `npm run deploy`, or edit the default in `scripts/build.mjs`. Update player dimensions in `public/index.html` if needed.
- **Modal**: set `PREVIEW_COMPOSITION = "<your-name>"` in `src/app.py`. Update the `<hyperframes-player>` dimensions in `web/index.html` if it isn't 1920×1080.
</Step>
<Step title="Deploy">
```bash Terminal
# Vercel
vercel deploy
# Cloudflare
npm run deploy
# Modal
modal deploy src/app.py
```
</Step>
</Steps>
## When to use a template vs. roll your own
Templates are optimized for **a single render endpoint behind a preview UI**. They're the fastest way to get a hosted Hyperframes render API running. If you need:
- A **render queue** with retries, deduplication, or priorities — start from a template, then add your own queue (e.g. Vercel Queues, Cloudflare Queues, SQS).
- **Multi-tenant rendering** with per-user composition uploads — start from a template, replace the bundled composition with a runtime-fetched one.
- **Self-hosted** rendering — see the [Rendering guide](/guides/rendering) and run `hyperframes render --docker` on your own infrastructure.
For everything else, the templates are the recommended starting point.
## Next Steps
<CardGroup cols={2}>
<Card title="Rendering" icon="film" href="/guides/rendering">
Render compositions locally or in Docker
</Card>
<Card title="Player package" icon="play" href="/packages/player">
Embed `<hyperframes-player>` in any HTML page
</Card>
<Card title="Vercel template" icon="github" href="https://github.com/heygen-com/hyperframes-vercel-template">
Source on GitHub
</Card>
<Card title="Cloudflare template" icon="github" href="https://github.com/heygen-com/hyperframes-cloudflare-template">
Source on GitHub
</Card>
<Card title="Modal template" icon="github" href="https://github.com/heygen-com/hyperframes-modal-template">
Source on GitHub
</Card>
</CardGroup>