| name | hyperframes |
| description | Generate deterministic MP4 videos from HTML, CSS, media, and seekable animations using HeyGen's HyperFrames framework. Use when someone asks to "render HTML to video", "make a video with HyperFrames", "create a programmatic video", "turn an animation into MP4", "build a launch/product video from HTML", "render GSAP/Lottie/Three.js to video", or set up an agent-driven video pipeline. Covers init/preview/render/add/lint/inspect commands, data-* timing attributes, animation adapters, and the component catalog. |
| license | Apache-2.0 |
| compatibility | Node.js 22+, FFmpeg, headless Chrome (Chromium). macOS, Linux, Windows. |
| metadata | {"author":"terminal-skills","version":"1.0.0","category":"content","tags":["video","html","ffmpeg","animation","rendering"]} |
| evals | [{"name":"render-gsap-to-mp4","prompt":"I have an index.html with a GSAP animation and some text. How do I turn it into an MP4 video that comes out identical every time I render it?","rubric":"Pass criteria: (1) names HyperFrames and uses `npx hyperframes render`;\n(2) explains rendering is via headless Chrome seeking each frame + FFmpeg encoding;\n(3) ties determinism to binding animation progress to the timeline (paused/seekable),\nnot real time — warns against Date.now()/Math.random()/wall-clock motion;\n(4) mentions previewing (`hyperframes preview`) and/or `lint` before render.\nScore higher for concrete commands over prose.\n"},{"name":"ci-launch-video-pipeline","prompt":"Set up an automated pipeline that renders a product launch video from an HTML file on every release, with no manual editor step.","rubric":"Pass criteria: (1) uses HyperFrames non-interactive CLI (`lint` then `render`) in CI;\n(2) lists the real prerequisites — Node.js 22+ and FFmpeg installed on the runner;\n(3) leverages deterministic output so the artifact only changes when the composition does;\n(4) shows or describes a concrete CI job (e.g. GitHub Actions) producing an MP4 artifact.\nScore higher for a runnable workflow over generic CI advice.\n"},{"name":"composition-timing-and-audio","prompt":"In a programmatic HTML video, how do I control exactly when each element appears and disappears, set the canvas size, and add background music at reduced volume?","rubric":"Pass criteria: (1) uses `data-start` and `data-duration` in seconds on elements;\n(2) sets canvas via `data-width`/`data-height` on the stage element;\n(3) uses an <audio> element with `data-volume` (0.0-1.0) for the music bed;\n(4) optionally references `data-track-index` for layering and `data-composition-id`.\nScore higher for a correct HTML snippet over a prose description.\n"}] |
HyperFrames
Overview
HyperFrames is an open-source (Apache-2.0) framework from HeyGen that turns HTML, CSS, media,
and animations into deterministic MP4 videos — identical input always produces identical
output. It parses HTML compositions annotated with data-* timing attributes, drives headless
Chrome to seek and capture each frame, and encodes the result with FFmpeg. There is no build
step, no React requirement, and no per-render fee. It is designed to be agent-friendly: the CLI
is non-interactive by default, so it slots cleanly into automated content pipelines.
Use this skill to scaffold projects, author HTML compositions, preview them with live reload,
and render frame-accurate video — including animations driven by GSAP, CSS, Lottie, Three.js,
Anime.js, or the Web Animations API.
Instructions
Prerequisites
Confirm the environment before starting:
- Node.js 22+ (
node --version)
- FFmpeg on PATH (
ffmpeg -version)
- Headless Chrome/Chromium is downloaded by the engine on first run.
Scaffolding a project
npx hyperframes init my-video
cd my-video
For agent-managed setup inside an existing AI-agent workspace, the skill can be installed with
npx skills add heygen-com/hyperframes.
Authoring a composition
Compositions are plain index.html files. A root stage element declares the canvas and
composition id; child elements declare when they appear and how long they last via data-*
attributes. Time values are in seconds.
| Attribute | Purpose |
|---|
data-composition-id | Names the composition (target for render/inspect) |
data-start | When the element enters the timeline (seconds) |
data-duration | How long the element stays on the timeline (seconds) |
data-width / data-height | Canvas dimensions in pixels (on the stage element) |
data-track-index | Layer/track ordering for stacked audio or video |
data-volume | Audio level, 0.0–1.0 |
Previewing and rendering
npx hyperframes preview
npx hyperframes render
npx hyperframes lint
npx hyperframes inspect
Resolution comes from data-width/data-height on the stage; frame rate, output path, and
codec are render parameters (check npx hyperframes render --help for the exact flags in your
installed version, as flag names evolve). Because output is deterministic, re-rendering
unchanged input is safe to cache.
Using the component catalog
Pre-built blocks (transitions, overlays, captions, animated charts, maps, effects) install into
the project:
npx hyperframes add flash-through-white
npx hyperframes add data-chart
npx hyperframes add instagram-follow
Browse the full catalog at hyperframes.heygen.com/catalog, then add blocks by name.
Animations
Any seekable, frame-accurate animation works because the engine seeks each timeline position
deterministically rather than recording in real time. Supported adapters: GSAP, CSS
animations, Lottie, Three.js, Anime.js, WAAPI, and custom frame adapters.
Avoid time-based randomness or Date.now()/wall-clock driven motion — bind animation progress to
the composition timeline so seeks are reproducible.
Agent / CI pipelines
The CLI is non-interactive, so a typical automated flow is: generate/template the HTML →
hyperframes lint → hyperframes render → collect the MP4. For scale, the
@hyperframes/aws-lambda package enables distributed rendering across Lambda.
Examples
Example 1: Render a product-launch composition
index.html:
<div id="stage" data-composition-id="launch"
data-start="0" data-width="1920" data-height="1080">
<video data-start="0" data-duration="6" src="intro.mp4"></video>
<h1 id="title" data-start="1" data-duration="4">Launch day</h1>
<audio data-start="0" data-duration="6" data-volume="0.8" src="music.wav"></audio>
</div>
npx hyperframes inspect
npx hyperframes lint
npx hyperframes render
Example 2: A seekable GSAP title animation
<div id="stage" data-composition-id="title-card"
data-start="0" data-width="1080" data-height="1080">
<h1 id="headline" data-start="0" data-duration="3">Q3 Results</h1>
<script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script>
<script>
const tl = gsap.timeline({ paused: true });
tl.from("#headline", { y: 80, opacity: 0, duration: 1 })
.to("#headline", { scale: 1.05, duration: 2 });
window.__seek = (t) => tl.seek(t);
</script>
</div>
npx hyperframes preview
npx hyperframes render
Guidelines
- Determinism first. Bind all motion to the composition timeline. Avoid
Math.random(),
Date.now(), real-time loops, or network calls during render — they break reproducibility.
- Lint before you render.
hyperframes lint catches structural/timing mistakes cheaply;
rendering is the expensive step.
- Set canvas on the stage.
data-width/data-height live on the root composition element;
child timing (data-start/data-duration) lives on each element, in seconds.
- Verify the toolchain. Most failures trace back to missing FFmpeg or Node < 22, or a
Chromium download blocked by a firewall.
- Use
--help for exact flags. render/add options vary by version; confirm fps/output/
codec flags against the installed CLI rather than assuming.
- Prefer catalog blocks.
hyperframes add pulls maintained, seekable components instead of
hand-rolling transitions and charts.
- Scale with Lambda. For batch/large jobs, render via
@hyperframes/aws-lambda rather than
one long local job.
- Keep media local and committed. Reference assets by stable paths; remote fetches during
render undermine determinism and reproducibility.