Guide
Batch-render video variants
Build the video once, declare what may change, and let one command render a version for every row of a spreadsheet.
Updated
To render many versions of one short video, turn it into a template whose changeable parts are declared variables, put one set of values per version in a JSON rows file (exported from any spreadsheet), and run npx hyperframes render --batch rows.json. HyperFrames renders one MP4 per row and names each file from the row's values.
It is the fastest way to make a video per product, five versions of a hook to test, the same promo in three languages, or a personal thank-you video for every customer on a list.
When batching is worth it
Batch rendering pays off when the design stays the same and only the content changes:
- Product videos. One drop or price video per product: name, price, photo, color.
- Hook tests. Five opening lines for the same video (a question, a claim, a number, a mistake, a result), posted on different days so you can keep the one that works.
- Languages. The same video with translated text that is checked to fit its box.
- Series. Episode covers or title cards from an episode list.
- Personal videos. A thank-you or welcome video per customer, from a list you are allowed to use.
If every version needs a different layout, batching is the wrong tool; make separate videos instead.
Make the video a template
A HyperFrames template declares its variables on the root of the page, each with an id, a type, a label and a default:
<html data-composition-variables='[
{"id":"product","type":"string","label":"Product name","default":"Linen tote"},
{"id":"price","type":"string","label":"Price","default":"$39"},
{"id":"accent","type":"color","label":"Accent color","default":"#FF2E93"}
]'>
The page then uses them: data-var-text="product" replaces an element's text, data-var-src swaps an image, and scalar variables are available in CSS as custom properties such as var(--accent). Types include string, number, color, boolean, enum, font and image.
You do not have to write this by hand. Ask Claude Code: "Turn this project into a template: make the product name, price, photo and accent color variables with the current values as defaults, and test it with a product name twice as long." The long-text test matters, because a design that only fits the default words will break on row seventeen.
Test one version
Before rendering a whole list, render a single version from a file of values:
npx hyperframes render --variables-file vars.json --strict-variables -o renders/test.mp4
A file avoids quoting problems on Windows, where typing JSON on one command line breaks easily. Look at the result at the moments the text appears. Note that npx hyperframes check and snapshots always show the declared defaults, not your values, so judge variable versions from a render.
Turn a spreadsheet into rows
Keep the list in any spreadsheet: one row per video, one column per variable, plus a slug column for the file name. Export it as CSV and ask Claude Code to convert it:
| slug | product | price | accent |
|---|---|---|---|
| tote | Linen tote | $39 | #FF2E93 |
| cap | Canvas cap | $24 | #00E5FF |
| mug | Stoneware mug | $18 | #FFE600 |
The result is a JSON array with one object per row, using the same keys as the variable ids.
Render every row
npx hyperframes render --batch rows.json --strict-variables --output "renders/{slug}.mp4"
The {slug} placeholder is filled from each row, so the files come out as renders/tote.mp4, renders/cap.mp4 and so on. Rows render one after another by default; --batch-concurrency renders several at once on a machine with spare memory, and --batch-fail-fast stops at the first failure instead of finishing the rest.
Check the results
Spot-check before posting. Grab a frame from a few renders where the longest text appears:
ffmpeg -ss 2.0 -i renders/tote.mp4 -frames:v 1 check-tote.png
Look for words that overflow their box, prices that wrap and colors that clash with the photo. Fix the template, not single rows, and render again; the same input always gives the same frames, so only what you changed moves.
Data rules
Only render with real data. Prices, results and reviews in a batch are still claims, and a spreadsheet makes it easy to publish a wrong one fifty times. For personal videos, use names and details you have permission to use.
Ready-made
In the Motion Cheat Code pack, the text, numbers and colors you would want to change in each template are already variables, and the batch skill for Claude Code handles the CSV conversion, the test row and the naming ("render one thank-you video per row of customers.csv"). Want to see variables in action first? The free starter kit's Counter Card template renders with your own number from one line.
Questions
How many videos can one batch render?
There is no fixed limit. By default HyperFrames renders one row at a time, so a longer list simply takes longer. You can raise the number of rows rendered at once with --batch-concurrency if the computer has memory to spare.
What does --strict-variables do?
It stops the render when a row has a variable name that the template does not declare or a value of the wrong type, instead of quietly using the default. Keep it on, because a typo in a column name otherwise renders the default text.
Can I batch-render from Google Sheets or Excel?
Yes. Export the sheet as CSV and ask Claude Code to convert it into a JSON rows file, mapping each column to a variable and adding a short slug per row for the file name.