## File: README.md

HyperFrames is an open-source framework for turning HTML, CSS, media, and seekable animations into deterministic MP4 videos. Use it locally with the CLI, from AI coding agents with skills, or as the rendering core behind hosted authoring workflows.

## Quick Start

### With an AI coding agent

Install the HyperFrames skills, then describe the video you want:

```bash
npx skills add heygen-com/hyperframes --full-depth
```

> The picker opens with nothing pre-selected — the **Core Skills** group is all you need: the `/hyperframes` router installs each creation workflow on demand. Agents and non-interactive runs should use `npx hyperframes skills update` instead — it installs exactly the core set, whereas a non-interactive `skills add` without `--skill` installs all 20.
>
> `--full-depth` does a full clone of the repo's current `main`. Without it, `skills add` fetches the skills.sh registry blob, which lags `main` by hours — you'd get an older copy of a skill. (`hyperframes skills update` already installs full-depth.)

Try a prompt like:

> Using `/hyperframes`, create a 10-second product intro with a fade-in title, a background video, and subtle background music.

The skills teach agents the HyperFrames production loop: plan the video, write valid HTML, wire seekable animations, add media, lint, preview, and render. They work with Claude Code, Cursor, Gemini CLI, Codex, and other coding agents that support skills.

## Skills

HyperFrames ships 20 skills agents load on demand. Read `/hyperframes` first — it's the router and capability map; it picks a workflow for any "make me a…" request — video, deck, or composition port — and points to the domain skills below.

Default to the **core set** — the router installs each creation workflow on demand. `npx hyperframes skills update` installs exactly that from anywhere; the interactive picker (`npx skills add heygen-com/hyperframes --full-depth`) lists it as the "Core Skills" group, nothing pre-selected. The picker is interactive-only — a non-interactive or agent run without `--skill` installs all 20. Use `npx skills add heygen-com/hyperframes --all --full-depth` to install all 20 deliberately (skips the picker), or `npx skills add heygen-com/hyperframes --skill <name> --full-depth` for just one (bare name, no leading `/`). Keep `--full-depth` — it installs the current `main`; without it `skills add` fetches the skills.sh blob, which lags by hours.

Installs stay lean after that: `npx hyperframes init` keeps the **core set** fresh (the router, the `hyperframes-*` domain skills, and `media-use` — plus whatever is already installed; `/figma` stays on demand) and never expands a partial install; the creation workflows install **on demand** — the router runs `npx hyperframes skills update <workflow>` before entering one. Nothing re-pulls the full set behind your back.

### Upload to Codex

Build the upload-ready Codex plugin archive from the committed `HEAD` version of the manifest, brand assets, and skills:

```bash
bun run package:codex-plugin
```

This writes `dist/hyperframes-plugin.zip` with a `hyperframes/` root folder and fails if the archive exceeds Codex's 100 MB upload limit.

### Router

| Skill          | Use when                                                                                                                                                                                                                                                                 |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `/hyperframes` | **Read first** for any request to make / create / edit / animate / render a video, animation, or motion graphic. Capability map for the domain skills, the intent layer that confirms every creation brief up front, and intent router for the creation workflows below. |

### Creation workflows

| Skill                      | Use when                                                                                                                                                                                                                     |
| -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/product-launch-video`    | Any **website** — marketing / launching / promoting a product (from its URL, a brief, or a script), or a site tour / showcase / social clip featuring the site's own visuals. Up to ~3 min (sweet spot 30-90s).              |
| `/faceless-explainer`      | **Explaining a topic / concept** from arbitrary text — no product, no URL, no website capture; every visual is LLM-invented (typography / abstract / diagram / data-viz).                                                    |
| `/pr-to-video`             | A **GitHub pull request** (PR URL, `owner/repo#N` ref, or "this PR") → changelog / feature-reveal / fix / refactor explainer, read via the `gh` CLI.                                                                         |
| `/embedded-captions`       | Adding **captions / subtitles** to an existing talking-head video (footage untouched) — verbatim rail, embedded climax behind the subject, or pure-cinematic embed.                                                          |
| `/talking-head-recut`      | Packaging an existing talking-head / interview / podcast video with **designed graphic overlays** — lower-thirds, data callouts, kinetic titles, pull-quotes, side panels, PiP.                                              |
| `/motion-graphics`         | A short, **unnarrated, design-led motion graphic** (~under 10s) — kinetic type, stat / chart hit, logo sting, lower-third, animated tweet / headline. MP4 or transparent overlay.                                            |
| `/music-to-video`          | A **music track** (audio file, video to pull audio from, or one generated from a mood brief) → a **beat-synced** video — lyric, slideshow, or kinetic promo; music drives pacing.                                            |
| `/slideshow`               | A **presentation / pitch deck / interactive deck** — discrete slides, fragment reveals, branching, hotspot navigation, presenter mode. Output is a navigable deck, not a rendered video.                                     |
| `/general-video`           | **Anything else** — longer or multi-scene pieces, brand / sizzle reel, title card, static loop, freeform composition. Input- and length-agnostic fallback, and the home of companion mode (co-create with the full toolbox). |
| `/remotion-to-hyperframes` | **Porting an existing Remotion** (React) composition's source to HyperFrames HTML. One-way migration, not creation.                                                                                                          |

### Domain skills (loaded on demand)

Atomic capabilities the creation workflows compose against — pull one when you need that specific layer.

| Skill                    | Covers                                                                                                                                                                                                                                                                                                                                                                  |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/hyperframes-core`      | The composition contract — `data-*` timing attributes, `class="clip"`, tracks, sub-compositions, variables, framework-owned media playback, determinism rules.                                                                                                                                                                                                          |
| `/hyperframes-animation` | All animation knowledge — atomic motion rules, scene blueprints, transitions, runtime adapters (GSAP / Lottie / Three.js / Anime.js / CSS / WAAPI / TypeGPU).                                                                                                                                                                                                           |
| `/hyperframes-keyframes` | Seek-safe keyframe authoring across runtimes — GSAP timelines, CSS keyframes, Anime.js, WAAPI, FLIP, paths, masks, SVG morph/draw, 3D depth — plus `hyperframes keyframes` diagnostics for rendered motion.                                                                                                                                                             |
| `/hyperframes-creative`  | Non-animation creative direction — `frame.md` / `design.md`, palettes, typography, narration, beat planning, audio-reactive visuals, composition patterns.                                                                                                                                                                                                              |
| `/media-use`             | The media OS — resolve any media need (BGM, SFX, image, icon, logo, voice, color grade, LUT) into a frozen local file or paste-ready block + ledger record, generate via TTS/music/image models when the catalog misses, transcribe, caption, remove backgrounds, and reuse assets across projects. One shared audio engine + manifest tracking.                        |
| `/hyperframes-cli`       | CLI dev loop — `init`, `lint`, `check`, `snapshot`, `preview`, `render`, `publish`, `doctor`, plus HeyGen-hosted cloud rendering (`cloud render`) and AWS Lambda rendering (`lambda deploy / render / progress`).                                                                                                                                                       |
| `/hyperframes-audio`     | Mix the audio already placed in a composition — voiceover carve (dip a music bed only in the bands the voice occupies, static or dynamic, level match included), the effect chain (EQ, compressor, limiter, gate, saturation, delay, reverb, chorus, phaser, bitcrush), and automation envelopes on volume or any effect parameter. Sourcing the audio is `/media-use`. |
| `/hyperframes-registry`  | Install and wire registry blocks and components into compositions via `hyperframes add`. Authoring a new block or component to contribute upstream.                                                                                                                                                                                                                     |
| `/figma`                 | Import Figma assets, tokens, components, and storyboard sections → reconstructed motion (frames read as states, not slides) (REST/CLI) plus Motion animations (MCP) and shaders (MCP source / native export) into a composition.                                                                                                                                        |

For visual design handoff workflows, see the [Claude Design guide](https://hyperframes.heygen.com/guides/claude-design) and [Open Design guide](https://hyperframes.heygen.com/guides/open-design).

### Manually with the CLI

```bash
npx hyperframes init my-video
cd my-video
npx hyperframes preview      # preview in browser with live reload
npx hyperframes render       # render to MP4
```

**Requirements:** Node.js 22+, FFmpeg

## What You Can Build

Need ideas? Browse the [Showcase](https://hyperframes.heygen.com/showcase) for finished videos you can watch, read, run, and remix.

- Product launch videos and feature announcements
- PR walkthroughs with animated code diffs, narration, and captions
- Data visualizations, chart races, and map animations
- Social videos with kinetic captions, overlays, and music
- Docs-to-video, PDF-to-video, and site-tour explainers
- Reusable motion graphics for automated content pipelines

## Frame.md

**frame.md — your design system, ready for video.**

Every brand has a `design.md`. None of them were written for a camera. `frame.md` is the missing translation layer: it takes your web-context design spec and inverts it for the frame — the same tokens, the same rules, but rewritten so an AI agent can compose a promo video without guessing at scale or reaching for web chrome.

The output is a `DESIGN.md` superset your whole toolchain can read. Atoms stay sacred. Composition stays free. Numbers come from the script.



| [](https://www.hyperframes.dev/design/biennale-yellow)
      **[Biennale Yellow](https://www.hyperframes.dev/design/biennale-yellow)** | [](https://www.hyperframes.dev/design/blockframe)
      **[BlockFrame](https://www.hyperframes.dev/design/blockframe)** |
| --- | --- |
| [](https://www.hyperframes.dev/design/blue-professional)
      **[Blue Professional](https://www.hyperframes.dev/design/blue-professional)** | [](https://www.hyperframes.dev/design/bold-poster)
      **[Bold Poster](https://www.hyperframes.dev/design/bold-poster)** |
| [](https://www.hyperframes.dev/design/broadside)
      **[Broadside](https://www.hyperframes.dev/design/broadside)** | [](https://www.hyperframes.dev/design/capsule)
      **[Capsule](https://www.hyperframes.dev/design/capsule)** |
| [](https://www.hyperframes.dev/design/cartesian)
      **[Cartesian](https://www.hyperframes.dev/design/cartesian)** | [](https://www.hyperframes.dev/design/cobalt-grid)
      **[Cobalt Grid](https://www.hyperframes.dev/design/cobalt-grid)** |
| [](https://www.hyperframes.dev/design/coral)
      **[Coral](https://www.hyperframes.dev/design/coral)** | [](https://www.hyperframes.dev/design/creative-mode)
      **[Creative Mode](https://www.hyperframes.dev/design/creative-mode)** |



Browse and remix them all at [hyperframes.dev/design](https://www.hyperframes.dev/design).

## How It Works

Define a video as HTML. Add data attributes for timing and tracks. Use GSAP, CSS, Lottie, Three.js, Anime.js, WAAPI, or your own frame adapter for seekable animation.

```html

  <video
    class="clip"
    data-start="0"
    data-duration="6"
    data-track-index="0"
    src="intro.mp4"
    muted
    playsinline
  ></video>

  <h1 id="title" class="clip" data-start="1" data-duration="4" data-track-index="1">Launch day</h1>

  <audio
    data-start="0"
    data-duration="6"
    data-track-index="2"
    data-volume="0.5"
    src="music.wav"
  ></audio>

  <script src="https://cdn.jsdelivr.net/npm/gsap@3/dist/gsap.min.js"></script>
  <script>
    const tl = gsap.timeline({ paused: true });
    tl.from("#title", { opacity: 0, y: 40, duration: 0.8 }, 1);
    window.__timelines = window.__timelines || {};
    window.__timelines.launch = tl;
  </script>

```

Preview instantly in the browser. Render locally or in Docker. The renderer seeks each frame in headless Chrome and encodes the result with FFmpeg, so the same input produces the same video.

## HyperFrames Stack

HyperFrames is the open-source rendering engine, plus a growing set of tools around HTML-native video creation.

| Piece                                           | Status              | What it does                                                                                      |
| ----------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------- |
| CLI                                             | Available           | Scaffold, preview, lint, inspect, and render local video projects                                 |
| Core / Engine / Producer                        | Available           | Parse compositions, drive headless Chrome, encode video, and mix audio                            |
| Catalog                                         | Available           | Reusable blocks and components for transitions, overlays, captions, charts, maps, and effects     |
| Agent skills                                    | Available           | Teach coding agents the video-production patterns that generic web docs miss                      |
| Studio                                          | Available, evolving | Browser surface for previewing and editing compositions                                           |
| AWS Lambda rendering                            | Available           | Deploy a distributed render stack and drive renders from your laptop or CI                        |
| [hyperframes.dev](https://www.hyperframes.dev/) | Available           | Community playground for previewing, iterating, sharing, and rendering HTML-native video projects |
| [frame.md](https://www.hyperframes.dev/design)  | Available           | Invert your design system for the camera — a DESIGN.md superset an agent can compose video from   |

## Catalog

Install ready-to-use blocks and components:

```bash
npx hyperframes add flash-through-white   # shader transition
npx hyperframes add instagram-follow      # social overlay
npx hyperframes add data-chart            # animated chart
```

Browse the catalog at [hyperframes.heygen.com/catalog](https://hyperframes.heygen.com/catalog/blocks/data-chart).

## Why HyperFrames?

- **HTML-native:** compositions are HTML files with data attributes. No React requirement, no proprietary timeline format.
- **Agent-friendly:** agents already write HTML, and the CLI is non-interactive by default.
- **Deterministic:** same input, same frames, same output. Built for CI, regression tests, and automated rendering.
- **No build step:** an `index.html` composition plays as-is and can be previewed directly in the browser.
- **Adapter-based animation:** bring GSAP, CSS animations, Lottie, Three.js, Anime.js, WAAPI, or a custom runtime.
- **Open source:** Apache 2.0 license, with no per-render fees or commercial-use thresholds.

## HyperFrames vs Remotion

HyperFrames is inspired by [Remotion](https://www.remotion.dev). Both tools render video with headless Chrome and FFmpeg. The main difference is the authoring model: Remotion's bet is React components; HyperFrames' bet is plain HTML that humans and agents can both write easily.

|                          | **HyperFrames**                       | **Remotion**                            |
| ------------------------ | ------------------------------------- | --------------------------------------- |
| Authoring                | HTML + CSS + seekable animation       | React components                        |
| Build step               | None; `index.html` plays as-is        | Bundler required                        |
| Agent handoff            | Plain HTML files                      | JSX / React project                     |
| Library-clock animations | Seekable, frame-accurate via adapters | Wall-clock animation patterns need care |
| Distributed rendering    | Local and AWS Lambda render paths     | Remotion Lambda, mature cloud renderer  |
| License                  | Apache 2.0                            | Source-available Remotion License       |

Read the full comparison in the [HyperFrames vs Remotion guide](https://hyperframes.heygen.com/guides/hyperframes-vs-remotion).

## Documentation

Full documentation: [hyperframes.heygen.com/introduction](https://hyperframes.heygen.com/introduction)

- [Quickstart](https://hyperframes.heygen.com/quickstart)
- [Showcase](https://hyperframes.heygen.com/showcase)
- [Guides](https://hyperframes.heygen.com/guides/gsap-animation)
- [API Reference](https://hyperframes.heygen.com/packages/core)
- [Catalog](https://hyperframes.heygen.com/catalog/blocks/data-chart)
- [Examples](https://hyperframes.heygen.com/examples)
- [AWS Lambda rendering](https://hyperframes.heygen.com/deploy/aws-lambda)

## Packages

| Package                                                          | Description                                                       |
| ---------------------------------------------------------------- | ----------------------------------------------------------------- |
| [`hyperframes`](packages/cli)                                    | CLI for creating, previewing, linting, and rendering compositions |
| [`@hyperframes/core`](packages/core)                             | Types, parsers, generators, linter, runtime, and frame adapters   |
| [`@hyperframes/engine`](packages/engine)                         | Seekable page-to-video capture engine using Puppeteer and FFmpeg  |
| [`@hyperframes/producer`](packages/producer)                     | Full rendering pipeline for capture, encode, and audio mix        |
| [`@hyperframes/studio`](packages/studio)                         | Browser-based composition editor UI                               |
| [`@hyperframes/player`](packages/player)                         | Embeddable `<hyperframes-player>` web component                   |
| [`@hyperframes/shader-transitions`](packages/shader-transitions) | WebGL shader transitions for compositions                         |
| [`@hyperframes/aws-lambda`](packages/aws-lambda)                 | AWS Lambda SDK and deployment surface for distributed renders     |

## Community

HyperFrames is used in production at [HeyGen](https://www.heygen.com), with community examples from teams like [tldraw](https://tldraw.com), [TanStack](https://tanstack.com), and others in [ADOPTERS.md](ADOPTERS.md). Open a PR if your team is using HyperFrames.

- Questions and ideas: [Discord](https://discord.gg/EbK98HBPdk)
- Bugs and feature requests: [GitHub Issues](https://github.com/heygen-com/hyperframes/issues)
- User research: [Book a casual 30-minute conversation with the HyperFrames team](https://calendar.google.com/calendar/u/0/appointments/schedules/AcZssZ2cSpKoDgmcmRrgekrnrgqmvPT8W6F2Zg6e7MY7IJqaZKwpn_I0NdTHkN390iguMepE_NVg8ezb?gv=true) — no preparation or sales pitch
- Security reports: [SECURITY.md](SECURITY.md)
- Contributions: [CONTRIBUTING.md](CONTRIBUTING.md)

## Development Note

The repo uses [Git LFS](https://git-lfs.com) for golden regression-test baselines under `packages/producer/tests/**/output.mp4` (about 240 MB of `.mp4` files). If you're cloning the full repo for development, install Git LFS first:

```bash
# macOS
brew install git-lfs

# Ubuntu / Debian
sudo apt install git-lfs

# Windows
winget install GitHub.GitLFS

# Then, once per machine
git lfs install
```

If you only need source files, you can skip LFS content:

```bash
GIT_LFS_SKIP_SMUDGE=1 git clone https://github.com/heygen-com/hyperframes.git
```

## License

[Apache 2.0](LICENSE)

---

## File: docs/concepts/data-attributes.mdx

---
title: "Time elements with data attributes"
sidebarTitle: "Data attributes"
---

HyperFrames keeps timing in HTML. A timed element normally needs a stable ID,
a start, a duration, and a track:

```html
<section id="headline" class="clip" data-start="0" data-duration="3" data-track-index="1">
  Launch day
</section>
```

| Attribute          | What it controls                                 |
| ------------------ | ------------------------------------------------ |
| `data-start`       | When the element enters the composition timeline |
| `data-duration`    | How long its timeline slot lasts                 |
| `data-track-index` | Which timeline lane owns that slot               |

Add `class="clip"` to timed DOM and image elements so the runtime can control
their visibility. Video visibility is managed by the media runtime; audio has
no visual lifecycle.

## Tracks are not layers

Tracks prevent time ranges from colliding. They do not decide which element is
in front. Use CSS `z-index` for paint order.

Two clips on one track cannot overlap. Put an intentional overlap, such as a
crossfade, on separate tracks:

```html
<video
  id="intro"
  data-start="0"
  data-duration="4"
  data-track-index="0"
  src="./intro.mp4"
  muted
  playsinline
></video>
<section id="result" class="clip" data-start="intro - 0.5" data-duration="3" data-track-index="1">
  The result
</section>
```

## Start relative to another clip

A numeric `data-start` is an absolute time in seconds. A clip ID means “start
when that clip ends.” Add or subtract seconds for a gap or overlap:

```html
data-start="intro" data-start="intro + 0.5" data-start="intro - 0.5"
```

References resolve only inside the same composition. The referenced clip must
have a known duration, and reference chains cannot contain a cycle.

## Media and nested compositions

Media can also declare a source offset, playback rate, and volume. A nested
composition adds a source path and its own fixed timeline window. These are
exact contracts rather than new timing models.

Use the [HTML schema reference](/reference/html-schema) for every supported
attribute and element-specific rule. Use [Compositions](/concepts/compositions)
to decide when a scene should become a separate composition.

---

## File: docs/concepts/determinism.mdx

---
title: Deterministic Rendering
---

The same [composition](/concepts/compositions) always produces the same video.
That is the guarantee everything else rests on — it is why automated pipelines,
CI tests, and AI-driven editing can be trusted.

## Why the same frame always comes out the same

Rendering never plays your video. It asks for one frame at a time, and the
answer to "what does frame 90 look like?" depends on exactly one thing that
changes: the number 90.

```mermaid
flowchart TD
    F["Frame 90"] --> T
    L["Locked before frame 0:fps, width, height, variables"] --> T
    T["t = 90 / fpsinteger math, never a clock"] --> S["Every animation seekedto exactly t"]
    S --> P["The same pixels, every run"]
    S -.-> X["Breaks if a frame reads:Date.now, unseeded Math.random,or a mid-render fetch"]
```

So the rules are short:

- **No wall clock.** No `Date.now()`, no `requestAnimationFrame`, no system
  timers.
- **No unseeded randomness.** `Math.random()` without a seed gives a different
  frame every run.
- **No fetching mid-render.** Every asset loads before the first frame.
- **Fixed output size.** `fps`, `width`, and `height` are locked before frame 0.
- **A finite length.** Every composition has a known end.

## What happens on each frame

<Steps>
  <Step title="Frame clock">
    The [engine](/packages/engine) works out the time with integer math:
    `time = floor(frame) / fps`. Real time is never consulted.
  </Step>
  <Step title="Seek">
    The [frame adapter](/concepts/frame-adapters) gets `seekFrame(frame)` and
    moves every animation, DOM change, and canvas draw to that exact moment. All
    [GSAP](/guides/gsap-animation) timelines are paused and seeked, never played.
  </Step>
  <Step title="Capture">
    Chrome's `HeadlessExperimental.beginFrame` grabs the pixels in one atomic
    operation. No half-painted frames.
  </Step>
  <Step title="Encode">
    FFmpeg turns the captured frames into the MP4 and mixes in the audio from
    your `<audio>` and `<video>` elements.
  </Step>
</Steps>

Every [frame adapter](/concepts/frame-adapters) follows these same rules. If you
write your own, it must follow the
[determinism contract](/concepts/frame-adapters#contract):
`seekFrame(frame)` gives the same result for the same frame, seeks work in any
order, nothing resolves after the frame is committed, and the lifecycle stays
`init` → `seekFrame` (many times) → `destroy`.

## Rule out your machine as a variable

Fonts and Chrome versions differ between computers, so a local render can shift
by a pixel from one machine to the next. Render in Docker when you need exact
reproducibility:

```bash
npx hyperframes render --docker --output output.mp4
```

Docker pins the Chromium version, the font set, and the FFmpeg encoder, so the
platform stops being an input. The [Rendering guide](/guides/rendering) covers
every other option.

## Will the preview match the render?

Every frame looks the same in both, because both run the same
`hyperframe.runtime`, the [producer's](/packages/producer) seek behavior is the
single source of truth, and the `__playerReady` and `__renderReady` gates hold
capture until the composition is fully loaded.

Speed is a different story. Preview plays in real time in your browser, so it is
limited by your hardware. Render is seek-driven and takes one frame at a time,
so it never drops a frame no matter how expensive that frame is. A composition
that stutters in preview still renders perfectly — see
[Performance](/guides/performance).

## Related topics

- [Frame adapters](/concepts/frame-adapters)
- [Render to MP4](/guides/rendering)
- [Compositions](/concepts/compositions)
- [@hyperframes/producer](/packages/producer)
- [Common mistakes that break determinism](/guides/troubleshooting)

---

## File: docs/concepts/frame-adapters.mdx

---
title: "Frame adapters"
---


  The exported `FrameAdapter` interface is experimental v0 API. Its signatures
  may change before v1.


A frame adapter answers one question: what state should an animation have at frame N?

Most composition authors do not implement this interface. HyperFrames already seeks registered GSAP, CSS, Anime.js, Lottie, Three.js, Web Animations, and TypeGPU animation through its browser runtime. Use the [GSAP guide](/guides/gsap-animation) for the normal authoring path.

Use `FrameAdapter` when you are building a custom host around a seekable animation object.

Rendering never plays the animation. It asks for one frame, waits, captures it,
then asks for the next — so the same frame always comes out the same.

```mermaid
sequenceDiagram
    participant R as Renderer
    participant A as Frame adapter
    participant T as Your timeline
    R->>A: getDurationFrames()
    A-->>R: 120
    loop every frame, in any order
        R->>A: seekFrame(90)
        A->>T: jump to 3.0s and settle
        T-->>A: state at 3.0s
        A-->>R: ready
        R->>R: capture the pixels
    end
    R->>A: destroy()
```

## Interface

```ts
import type { FrameAdapter, FrameAdapterContext } from "@hyperframes/core";

type FrameAdapter = {
  id: string;
  init?: (context: FrameAdapterContext) => Promise<void> | void;
  getDurationFrames: () => number;
  seekFrame: (frame: number) => Promise<void> | void;
  destroy?: () => Promise<void> | void;
};
```

The context contains the composition ID, frame rate, dimensions, and optional root element.

## Adapt a GSAP timeline

`@hyperframes/core` includes a helper for a GSAP-like timeline:

```ts
import { createGSAPFrameAdapter } from "@hyperframes/core";

const adapter = createGSAPFrameAdapter({
  id: "intro",
  fps: 30,
  timeline,
});

await adapter.init?.({
  compositionId: "intro",
  fps: 30,
  width: 1920,
  height: 1080,
});

await adapter.seekFrame(90); // three seconds
```

The helper pauses the timeline, derives its frame length, and converts each frame request to seconds.

## Contract

A custom adapter must:

- return a finite, non-negative frame count;
- support forward, backward, and random seeks;
- return the same state when the same frame is requested again;
- avoid wall-clock timers and unseeded randomness;
- finish asynchronous work before the frame is captured;
- release listeners and other resources in `destroy()`.

The host still owns the capture and encoding pipeline. The adapter owns only the animation state.

## Continue

Read [Deterministic rendering](/concepts/determinism) for the timing rules or [`@hyperframes/core`](/packages/core) for the package exports.

---

## File: docs/community/adopters.mdx

---
title: Adopters
---

The teams below use HyperFrames in production or are actively evaluating it. If your organization uses HyperFrames — in production, in evaluation, or in a side project — we'd love to add you.

## How to add your organization

Open a pull request that adds your team to [`ADOPTERS.md`](https://github.com/heygen-com/hyperframes/blob/main/ADOPTERS.md) at the repository root. The format is intentionally lightweight:

- **Organization** — your company or project name, linked to your website.
- **Contact** — a GitHub handle so other adopters can reach out.
- **How HyperFrames is used** — one sentence on the use case.
- **Logo** _(optional)_ — a square logo or icon to show on this page. If you skip this, your entry still appears in the table below.

If you'd rather not be listed publicly, we'd still love to hear about your usage — drop a note in [our Discord](https://discord.gg/EbK98HBPdk).

## Teams using or evaluating HyperFrames

<CardGroup cols={2}>
  <Card title="HeyGen" href="https://www.heygen.com">
    

    Powers AI-generated video composition and rendering across HeyGen's video product surface.

    [@jrusso1020](https://github.com/jrusso1020)

  </Card>
  <Card title="tldraw" href="https://tldraw.com">
    

    Generates automated pull-request walkthrough videos with GSAP-animated code diffs, narration, and captions.

    [@steveruizok](https://github.com/steveruizok)

  </Card>
  <Card title="TanStack" href="https://tanstack.com">
    

    Exploring HyperFrames for short-form code demo videos and documentation.

    [@AlemTuzlak](https://github.com/AlemTuzlak)

  </Card>
  <Card title="OptinMonster" href="https://optinmonster.com">
    

    Exploring HyperFrames for marketing and product video content.

    Angie Meeker

  </Card>
  <Card title="reap" href="https://reap.video">
    

    Powers agent-first AI video clipping, editing, and rendering across reap.video's creator and agent workflows.

    [@usamaabid](https://github.com/usamaabid)

  </Card>
  <Card title="Typeframe" href="https://typeframe.app">
    

    Renders speech videos into shareable MP4 exports with word-timed typing captions and styled caption layouts.

    [@kiyeonjeon21](https://github.com/kiyeonjeon21)

  </Card>
  <Card title="THU-MAIC" href="https://github.com/THU-MAIC">
    

    Powers OpenMAIC's one-click MP4 export for AI-generated interactive classrooms using self-contained HyperFrames compositions.

    [@wyuc](https://github.com/wyuc)
  </Card>
</CardGroup>

The HeyGen team's actual launch-video sources (the ones featured in product announcements) live at [hyperframes-launches](https://github.com/heygen-com/hyperframes-launches) — see [Examples](/examples) for the writeup.

---

## File: docs/catalog/components/texture-mask-text.mdx

---
title: "Texture Mask Text"
---

import { InstallCommand } from "/snippets/install-command.jsx";


  
    Brick
    BRICK
  
  
    Rock
    ROCK
  
  
    Ground 103
    GROUND
  
  
    Wood
    WOOD
  
  
    Metal
    METAL
  
  
    Lava
    LAVA
  


## Install



That writes `compositions/components/texture-mask-text/texture-mask-text.html`, plus 66 supporting files under `assets/texture-mask-text/masks/`.

## Source

<Accordion title={`texture-mask-text.html`}>

```
/* Detailed source-code truncated for AI context efficiency. */
```

</Accordion>

## Ask an agent for it

Paste this to your coding agent:

```text
Use the Texture Mask Text catalog component.

1. From the project root, run:
   npx hyperframes add texture-mask-text
2. That command creates this installed snippet:
   compositions/components/texture-mask-text/texture-mask-text.html
3. Open that file and paste the real <style> block
   near the bottom into the composition once. That CSS defines
   hf-texture-text and every hf-texture-* class.
4. Apply this class to the target text:
   class="hf-texture-text hf-texture-brick"
5. For another material, copy one hf-texture-* class
   from the Texture Examples cards.
6. This is the proper way to apply drop shadow
   to textured text: wrap the text and put
   filter on the wrapper, not on the text.
   Use this markup:
   
     TEXT
   
```

Swap `hf-texture-brick` for the class on any texture card below. Every texture also needs the base class `hf-texture-text`.

## Make the texture move

Move the mask position on the text element. Keep the drop shadow on a wrapper so it follows the textured contour.


  
    Animated mask position
    <code className="hf-texture-animate-class">hf-texture-text hf-texture-lava</code>
  
  
    MOTION
  


```html

  MOTION

```

```css
.animated-texture {
  --mask-size: 180% 180%;
  --mask-position: 0% 50%;
}
```

```js
const tl = gsap.timeline({ paused: true });
tl.to(".animated-texture", {
  "--mask-position": "100% 50%",
  duration: 1.2,
  ease: "sine.inOut",
  yoyo: true,
  repeat: 1,
}, 0);
window.__timelines["my-composition"] = tl;
```

## Every texture


  
    <h3 className="hf-texture-example-title">Masonry</h3>
    
      
        Brick<code className="hf-texture-example-class">hf-texture-brick</code>
        BRICK
        Use `hf-texture-text hf-texture-brick`
      
      
        Bricks 104<code className="hf-texture-example-class">hf-texture-bricks-104</code>
        BRICK
        Use `hf-texture-text hf-texture-bricks-104`
      
      
        Bricks 102<code className="hf-texture-example-class">hf-texture-bricks-102</code>
        BRICK
        Use `hf-texture-text hf-texture-bricks-102`
      
      
        Bricks 101<code className="hf-texture-example-class">hf-texture-bricks-101</code>
        BRICK
        Use `hf-texture-text hf-texture-bricks-101`
      
      
        Bricks 075 A<code className="hf-texture-example-class">hf-texture-bricks-075-a</code>
        BRICK
        Use `hf-texture-text hf-texture-bricks-075-a`
      
      
        Concrete<code className="hf-texture-example-class">hf-texture-concrete</code>
        CONCRETE
        Use `hf-texture-text hf-texture-concrete`
      
      
        Concrete 034<code className="hf-texture-example-class">hf-texture-concrete-034</code>
        CONCRETE
        Use `hf-texture-text hf-texture-concrete-034`
      
      
        Concrete 047 A<code className="hf-texture-example-class">hf-texture-concrete-047-a</code>
        CONCRETE
        Use `hf-texture-text hf-texture-concrete-047-a`
      
      
        Concrete 046<code className="hf-texture-example-class">hf-texture-concrete-046</code>
        CONCRETE
        Use `hf-texture-text hf-texture-concrete-046`
      
      
        Concrete 042 A<code className="hf-texture-example-class">hf-texture-concrete-042-a</code>
        CONCRETE
        Use `hf-texture-text hf-texture-concrete-042-a`
      
      
        Plaster 001<code className="hf-texture-example-class">hf-texture-plaster-001</code>
        PLASTER
        Use `hf-texture-text hf-texture-plaster-001`
      
      
        Painted Plaster 017<code className="hf-texture-example-class">hf-texture-painted-plaster-017</code>
        PLASTER
        Use `hf-texture-text hf-texture-painted-plaster-017`
      
    
  
  
    <h3 className="hf-texture-example-title">Stone</h3>
    
      
        Rock<code className="hf-texture-example-class">hf-texture-rock</code>
        ROCK
        Use `hf-texture-text hf-texture-rock`
      
      
        Rock 063<code className="hf-texture-example-class">hf-texture-rock-063</code>
        ROCK
        Use `hf-texture-text hf-texture-rock-063`
      
      
        Rock 058<code className="hf-texture-example-class">hf-texture-rock-058</code>
        ROCK
        Use `hf-texture-text hf-texture-rock-058`
      
      
        Onyx<code className="hf-texture-example-class">hf-texture-onyx</code>
        ONYX
        Use `hf-texture-text hf-texture-onyx`
      
      
        Marble 012<code className="hf-texture-example-class">hf-texture-marble-012</code>
        MARBLE
        Use `hf-texture-text hf-texture-marble-012`
      
      
        Marble 016<code className="hf-texture-example-class">hf-texture-marble-016</code>
        MARBLE
        Use `hf-texture-text hf-texture-marble-016`
      
      
        Travertine 009<code className="hf-texture-example-class">hf-texture-travertine-009</code>
        STONE
        Use `hf-texture-text hf-texture-travertine-009`
      
      
        Paving Stones 150<code className="hf-texture-example-class">hf-texture-paving-stones-150</code>
        STONE
        Use `hf-texture-text hf-texture-paving-stones-150`
      
      
        Paving Stones 138<code className="hf-texture-example-class">hf-texture-paving-stones-138</code>
        STONE
        Use `hf-texture-text hf-texture-paving-stones-138`
      
      
        Tiles 138<code className="hf-texture-example-class">hf-texture-tiles-138</code>
        TILE
        Use `hf-texture-text hf-texture-tiles-138`
      
    
  
  
    <h3 className="hf-texture-example-title">Ground / Road</h3>
    
      
        Ground 103<code className="hf-texture-example-class">hf-texture-ground-103</code>
        GROUND
        Use `hf-texture-text hf-texture-ground-103`
      
      
        Ground 037<code className="hf-texture-example-class">hf-texture-ground-037</code>
        GROUND
        Use `hf-texture-text hf-texture-ground-037`
      
      
        Ground 054<code className="hf-texture-example-class">hf-texture-ground-054</code>
        GROUND
        Use `hf-texture-text hf-texture-ground-054`
      
      
        Ground 104<code className="hf-texture-example-class">hf-texture-ground-104</code>
        GROUND
        Use `hf-texture-text hf-texture-ground-104`
      
      
        Ground 068<code className="hf-texture-example-class">hf-texture-ground-068</code>
        GROUND
        Use `hf-texture-text hf-texture-ground-068`
      
      
        Ground 080<code className="hf-texture-example-class">hf-texture-ground-080</code>
        GROUND
        Use `hf-texture-text hf-texture-ground-080`
      
      
        Road 012 A<code className="hf-texture-example-class">hf-texture-road-012-a</code>
        ROAD
        Use `hf-texture-text hf-texture-road-012-a`
      
      
        Road 008 A<code className="hf-texture-example-class">hf-texture-road-008-a</code>
        ROAD
        Use `hf-texture-text hf-texture-road-008-a`
      
      
        Road 007<code className="hf-texture-example-class">hf-texture-road-007</code>
        ROAD
        Use `hf-texture-text hf-texture-road-007`
      
      
        Road 013 A<code className="hf-texture-example-class">hf-texture-road-013-a</code>
        ROAD
        Use `hf-texture-text hf-texture-road-013-a`
      
      
        Road 012 B<code className="hf-texture-example-class">hf-texture-road-012-b</code>
        ROAD
        Use `hf-texture-text hf-texture-road-012-b`
      
      
        Road 009 C<code className="hf-texture-example-class">hf-texture-road-009-c</code>
        ROAD
        Use `hf-texture-text hf-texture-road-009-c`
      
      
        Asphalt 031<code className="hf-texture-example-class">hf-texture-asphalt-031</code>
        ASPHALT
        Use `hf-texture-text hf-texture-asphalt-031`
      
    
  
  
    <h3 className="hf-texture-example-title">Wood</h3>
    
      
        Wood<code className="hf-texture-example-class">hf-texture-wood</code>
        WOOD
        Use `hf-texture-text hf-texture-wood`
      
      
        Wood 094<code className="hf-texture-example-class">hf-texture-wood-094</code>
        WOOD
        Use `hf-texture-text hf-texture-wood-094`
      
      
        Wood 092<code className="hf-texture-example-class">hf-texture-wood-092</code>
        WOOD
        Use `hf-texture-text hf-texture-wood-092`
      
      
        Wood 051<code className="hf-texture-example-class">hf-texture-wood-051</code>
        WOOD
        Use `hf-texture-text hf-texture-wood-051`
      
      
        Wood 066<code className="hf-texture-example-class">hf-texture-wood-066</code>
        WOOD
        Use `hf-texture-text hf-texture-wood-066`
      
      
        Wood 049<code className="hf-texture-example-class">hf-texture-wood-049</code>
        WOOD
        Use `hf-texture-text hf-texture-wood-049`
      
      
        Wood 058<code className="hf-texture-example-class">hf-texture-wood-058</code>
        WOOD
        Use `hf-texture-text hf-texture-wood-058`
      
      
        Wood Floor 051<code className="hf-texture-example-class">hf-texture-wood-floor-051</code>
        FLOOR
        Use `hf-texture-text hf-texture-wood-floor-051`
      
      
        Wood Floor 064<code className="hf-texture-example-class">hf-texture-wood-floor-064</code>
        FLOOR
        Use `hf-texture-text hf-texture-wood-floor-064`
      
      
        Wood Floor 070<code className="hf-texture-example-class">hf-texture-wood-floor-070</code>
        FLOOR
        Use `hf-texture-text hf-texture-wood-floor-070`
      
      
        Bark 014<code className="hf-texture-example-class">hf-texture-bark-014</code>
        BARK
        Use `hf-texture-text hf-texture-bark-014`
      
    
  
  
    <h3 className="hf-texture-example-title">Metal</h3>
    
      
        Metal<code className="hf-texture-example-class">hf-texture-metal</code>
        METAL
        Use `hf-texture-text hf-texture-metal`
      
      
        Metal 049 A<code className="hf-texture-example-class">hf-texture-metal-049-a</code>
        METAL
        Use `hf-texture-text hf-texture-metal-049-a`
      
      
        Metal 055 A<code className="hf-texture-example-class">hf-texture-metal-055-a</code>
        METAL
        Use `hf-texture-text hf-texture-metal-055-a`
      
      
        Metal 046 B<code className="hf-texture-example-class">hf-texture-metal-046-b</code>
        METAL
        Use `hf-texture-text hf-texture-metal-046-b`
      
      
        Metal 061 B<code className="hf-texture-example-class">hf-texture-metal-061-b</code>
        METAL
        Use `hf-texture-text hf-texture-metal-061-b`
      
      
        Metal 048 A<code className="hf-texture-example-class">hf-texture-metal-048-a</code>
        METAL
        Use `hf-texture-text hf-texture-metal-048-a`
      
      
        Metal 032<code className="hf-texture-example-class">hf-texture-metal-032</code>
        METAL
        Use `hf-texture-text hf-texture-metal-032`
      
      
        Metal 041 A<code className="hf-texture-example-class">hf-texture-metal-041-a</code>
        METAL
        Use `hf-texture-text hf-texture-metal-041-a`
      
      
        Metal 038<code className="hf-texture-example-class">hf-texture-metal-038</code>
        METAL
        Use `hf-texture-text hf-texture-metal-038`
      
      
        Diamond Plate 009<code className="hf-texture-example-class">hf-texture-diamond-plate-009</code>
        PLATE
        Use `hf-texture-text hf-texture-diamond-plate-009`
      
    
  
  
    <h3 className="hf-texture-example-title">Organic / Soft</h3>
    
      
        Lava<code className="hf-texture-example-class">hf-texture-lava</code>
        LAVA
        Use `hf-texture-text hf-texture-lava`
      
      
        Grass 005<code className="hf-texture-example-class">hf-texture-grass-005</code>
        GRASS
        Use `hf-texture-text hf-texture-grass-005`
      
      
        Grass 001<code className="hf-texture-example-class">hf-texture-grass-001</code>
        GRASS
        Use `hf-texture-text hf-texture-grass-001`
      
      
        Grass 004<code className="hf-texture-example-class">hf-texture-grass-004</code>
        GRASS
        Use `hf-texture-text hf-texture-grass-004`
      
      
        Carpet<code className="hf-texture-example-class">hf-texture-carpet</code>
        WOVEN
        Use `hf-texture-text hf-texture-carpet`
      
      
        Fabric 083<code className="hf-texture-example-class">hf-texture-fabric-083</code>
        FABRIC
        Use `hf-texture-text hf-texture-fabric-083`
      
      
        Snow<code className="hf-texture-example-class">hf-texture-snow</code>
        SNOW
        Use `hf-texture-text hf-texture-snow`
      
      
        Snow 015<code className="hf-texture-example-class">hf-texture-snow-015</code>
        SNOW
        Use `hf-texture-text hf-texture-snow-015`
      
      
        Leather 037<code className="hf-texture-example-class">hf-texture-leather-037</code>
        LEATHER
        Use `hf-texture-text hf-texture-leather-037`
      
      
        Fabric 080<code className="hf-texture-example-class">hf-texture-fabric-080</code>
        FABRIC
        Use `hf-texture-text hf-texture-fabric-080`
      
    
  


## Usage

After `npx hyperframes add texture-mask-text`, the installed snippet lives at `compositions/components/texture-mask-text/texture-mask-text.html` inside your current HyperFrames project. Open that file and paste the real `<style>` element near the bottom into your composition once; it defines `hf-texture-text` and every `hf-texture-*` class used by the examples above. Keep the installed texture PNGs in `assets/texture-mask-text/masks/`; the CSS references them with project-root URLs.

{/* hf:generated-footer */}

Tagged `text` `text-effect` `effect` `texture` `mask`.

## Related topics

- [Browse the complete Catalog](/catalog)
- [Add assets and Catalog items in Studio](/studio/assets-and-blocks)
- [Build a richer composition](/go-further)