Files
hyperframes/docs/deploy/templates-on-lambda.mdx
Miguel Ángel e6b8e396f4 fix(core,sdk): namespace composition variables so they stop shadowing theme tokens
A declared composition variable was written to the composition root as a CSS
custom property named after its own id, with no namespace. A variable called
accent therefore set --accent inline and shadowed the host theme for that
whole subtree.

That is worse than a naming clash. The accent enum values are green, blue and
violet, which are not colours, they are selectors a composition maps onto
theme slots. A representative composition maps blue to var(--accent, #18181b).
The runtime then set --accent to blue, so the lookup resolved to the CSS
keyword and no host theme could win. green and violet escaped only because
they route to --brand and --accent-2, which nothing shadowed, which is why
this survived: it was invisible for two of three values.

Variables are now written to --hf-var-<slug>. The bare name is still written
as a deprecated alias, but only for ids that are not reserved theme tokens,
which is what actually fixes the collision.

Four writers had the bug, not one: the runtime bindings, the scoped
getVariables path, the compiler stylesheet, and the SDK mutate and
apply-patches path. Fixing only the runtime left the compiler emitting the
bare name into compiled output, where a host theme supplied as an inline
style attribute still rendered the keyword. All four now route through one
helper, and the helper takes the raw id so callers cannot derive the name
themselves.

That last point closed a real defect rather than a tidy-up. Two sites derived
the property name differently, one verbatim and one slugged, so an id like
Accent produced two disjoint property sets: one path reserved it, the other
aliased it, and an SDK edit silently never landed. A test pins that every
injection path derives one name per id.

Docs that taught binding the bare name are corrected, including the capstone,
whose ink variable is reserved and would have re-skinned the ground while
quietly ignoring the ink. Rendered output is unchanged there, so the published
videos stay accurate.
2026-08-09 17:45:02 +00:00

187 lines
5.7 KiB
Plaintext

---
title: "Render templates on Lambda"
description: "Render one HyperFrames composition with different variable values, individually or from a JSONL batch."
---
A HyperFrames template is a composition with declared variables. The same
project can produce many videos without rewriting its HTML.
Use this guide after deploying the [AWS Lambda render stack](/deploy/aws-lambda).
## Declare the inputs
Declare variables on the document, then bind them in the composition. This
example exposes a headline and accent color:
```html
<!doctype html>
<html
data-composition-variables='[
{"id":"title","type":"string","label":"Headline","default":"Welcome"},
{"id":"accent","type":"color","label":"Accent","default":"#6d5dfc"}
]'
>
<body>
<div
id="stage"
data-composition-id="welcome"
data-start="0"
data-width="1920"
data-height="1080"
data-duration="5"
data-no-timeline
style="color:var(--hf-var-accent)"
>
<h1 data-var-text="title">Welcome</h1>
</div>
</body>
</html>
```
A scalar variable is exposed as the CSS custom property `--hf-var-<slug>`, which
is why the stage binds `var(--hf-var-accent)` rather than `var(--accent)`. See
[Variables](/concepts/variables) for every type and binding method, and for the
reserved theme-token names a variable never writes.
## Test locally
Render one realistic payload before using cloud infrastructure:
```bash
hyperframes render ./my-template \
--variables '{"title":"Hello Ada","accent":"#ff4d67"}' \
--strict-variables \
--output renders/ada-preview.mp4
```
`--strict-variables` rejects undeclared keys and values with the wrong type.
## Render one version on Lambda
```bash
hyperframes lambda render ./my-template \
--width 1920 \
--height 1080 \
--variables '{"title":"Hello Ada","accent":"#ff4d67"}' \
--output-key renders/ada.mp4 \
--wait
```
Without `--wait`, the command returns a render ID. Check it later with:
```bash
hyperframes lambda progress <render-id>
```
## Reuse the project upload
`lambda render` can upload the project for each call. For repeated renders,
create a content-addressed site once:
```bash
hyperframes lambda sites create ./my-template
```
Pass the returned ID with later renders:
```bash
hyperframes lambda render ./my-template \
--site-id <site-id> \
--width 1920 \
--height 1080 \
--variables '{"title":"Hello Lin"}'
```
An unchanged project keeps the same site ID and skips another S3 upload.
## Render a batch
Create one JSON object per line. `outputKey` is required; `variables` and
`executionName` are optional.
```jsonl
{"outputKey":"renders/ada.mp4","variables":{"title":"Hello Ada","accent":"#ff4d67"}}
{"outputKey":"renders/lin.mp4","variables":{"title":"Hello Lin","accent":"#36b37e"}}
```
Start the batch:
```bash
hyperframes lambda render-batch ./my-template \
--batch ./recipients.jsonl \
--width 1920 \
--height 1080 \
--max-concurrent 10
```
The command uploads the project once and returns one manifest row per input
line. A failure to start one row does not discard the other started renders.
Validate the file without starting AWS executions:
```bash
hyperframes lambda render-batch ./my-template \
--batch ./recipients.jsonl \
--width 1920 \
--height 1080 \
--strict-variables \
--dry-run \
--json
```
## Keep variables small
The complete Step Functions Standard execution input is limited to 256 KiB.
HyperFrames checks this before starting the execution.
Use variables for JSON data. Store images, audio, and video separately and
pass their URLs instead of base64 content.
```json
{
"title": "Hello Ada",
"avatarUrl": "https://cdn.example.com/avatars/ada.png"
}
```
## Migrating from Remotion Lambda inputProps
HyperFrames variables fill the role that `inputProps` serves in a Remotion
Lambda render:
| Remotion pattern | HyperFrames equivalent |
| ----------------------- | ------------------------------------------------------------------ |
| `defaultProps` | A `default` value in `data-composition-variables` |
| `inputProps` | `--variables` or the SDK render config's `variables` |
| `props.title` | `data-var-text="title"`, a CSS variable, or `getVariables().title` |
| `renderMediaOnLambda()` | `renderToLambda()` |
Declare the allowed values in the composition, pass only the per-render data,
and keep large media outside the execution payload. Use `--strict-variables`
while migrating so an old or misspelled input fails before the render begins.
## Control concurrency
Three settings control different layers:
| Setting | Controls |
| -------------------------------------- | ------------------------------------------------------------------- |
| `lambda deploy --concurrency` | Maximum concurrent invocations for the deployed Lambda function |
| `lambda render --max-parallel-chunks` | Maximum chunk workers used by one render |
| `lambda render-batch --max-concurrent` | Maximum render executions started concurrently by the batch command |
Start conservatively and measure a real composition before increasing them.
## Use the SDK
For a backend service, `@hyperframes/aws-lambda/sdk` exposes `deploySite`,
`renderToLambda`, and `getRenderProgress`. See the
[AWS package reference](/packages/aws-lambda) for the current types and a
working example.
## Related topics
- [Deploy the AWS Lambda stack](/deploy/aws-lambda)
- [Use the AWS Lambda package](/packages/aws-lambda)
- [Understand composition variables](/concepts/variables)