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
185 lines
11 KiB
Plaintext
185 lines
11 KiB
Plaintext
---
|
||
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.
|
||
|
||
[](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.
|
||
|
||
[](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 10–90s 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 30–60s, 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>
|