Skip to main content
All articles

HyperFrames: the launch video is just an HTML file

Motion graphics written by a prompt: studio-grade work, minus the studio

AIArchitectureBusiness

7 min read

The feature is live, the video isn't

Friday afternoon. The feature is deployed, it works, and in two hours you will have forgotten about it. What is left is telling someone: a post, a changelog card, three lines to the customer who asked for it six weeks ago.

I have always done one of two things here. Post a screenshot, which slides past in the feed without anyone slowing down. Or open OBS, record the flow, trim it, and ship something that is visibly a screen recording: the cursor hunting for the button, the system font, the browser chrome with my twenty-seven tabs in it.

Knowing what to show was never the bottleneck. The bottleneck was that showing it decently went through someone who opens After Effects, and that person has a two-week queue.

A video is an HTML file with time in it

HyperFrames is an Apache-2.0 framework from HeyGen that renders MP4s out of HTML. Not "exports to HTML", not HTML as a template format. The composition is an .html file you can open in a browser and watch move, with no build step and no bundler.

The contract lives in two places. data-* attributes say when things are on screen. A paused GSAP timeline says how they move.

index.html
<div
  id="stage"
  data-composition-id="feature"
  data-start="0"
  data-width="1920"
  data-height="1080"
  data-duration="4"
  data-fps="30"
>
  <div
    id="card"
    class="clip"
    data-start="0"
    data-duration="4"
    data-track-index="0"
  >
    <h1 id="title">Saved filters</h1>
    <p id="sub">Shipping today</p>
  </div>
</div>
 
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<script>
  const tl = gsap.timeline({ paused: true });
 
  tl.fromTo(
    "#title",
    { y: 40, opacity: 0 },
    { y: 0, opacity: 1, duration: 0.6 },
    0
  );
  tl.fromTo(
    "#sub",
    { y: 20, opacity: 0 },
    { y: 0, opacity: 1, duration: 0.5 },
    0.25
  );
  tl.to("#card", { opacity: 0, duration: 0.4 }, 3.6);
 
  window.__timelines["feature"] = tl;
</script>

Three things make it render. Every visible slot carries class="clip" with data-start and data-duration. The timeline is created paused. It is registered on window.__timelines under the same id as the root. Everything else is ordinary CSS, so the stylesheet your product already has works in here untranslated.

Then there is the part that actually changes the model. The renderer never watches a clock. It does not press play and film the result. It holds the animation still, seeks it to the moment it needs, captures the frame, moves on. That is why the same file renders the same MP4 today and six months from now, and why GSAP, Lottie and Web Animations all behave identically here: none of them is deciding the time.

The price is a rule worth knowing up front. Inside a composition there is no Date.now(), no unseeded Math.random(), no infinite loops. A repeat: -1 is not a syntax error. It is a frame you cannot reproduce.

What actually happens when you run it

npx skills add heygen-com/hyperframes   # teach the framework to your agent
npx hyperframes init feature-video
cd feature-video
npx hyperframes preview                 # browser, live reload
npx hyperframes check                   # lint, layout, motion, contrast
npx hyperframes render                  # MP4

It is the same shape as Archify, the skill I use for architecture diagrams: one command, and from then on the agent can do something it could not do before.

What I did not expect is that it does not start writing. It asks questions, and they are the right ones. What kind of video, who for, how long, what aspect ratio, what should stick in the viewer's head. Then it closes the interview by writing a BRIEF.md, and from that point the brief is the only document the rest of the pipeline reads. When the video comes out wrong you have a file to fix, not a conversation to run again.

From there it picks a route based on what you handed it: a product URL, a pull request, an article, an audio track, existing footage with a face in it. Those are genuinely different paths with different rules, not one generator behind different prompts.

The part that changed the output for me is something else though. Install it inside the project rather than in a scratch folder and the video inherits the project: the design tokens sitting in globals.css, the components, the logo, the screenshots already in public/. You do not explain them, it finds them. The gap between a video that looks generated and a video that looks like your product is almost entirely there.

npx hyperframes check is where it stops feeling like a toy. It runs lint, layout, motion and contrast checks, and tells you no before you have waited three minutes on a render to find out.

When a design tool cuts the first pass

There is one job a coding agent does worse than a design tool: deciding what the video looks like. Palette, type, hierarchy, what each scene actually says.

The HyperFrames repo ships a guide that teaches Claude Design to emit a valid composition directly instead of its own default video artifact. Two paths come out of that, and they are not interchangeable:

  • Download ZIP. You get a real HyperFrames project, open it with the agent you already use, and refine locally. Eases, scene durations, pacing. Then npx hyperframes render on your own machine.
  • Send to HyperFrames. One self-contained HTML file, fonts and images inlined as base64, imported into a hosted project and rendered in the cloud. A relative path to a fonts/ folder simply does not arrive on the other side.

If you would rather not depend on a closed product for the first pass, Open Design does the same job under Apache-2.0, locally, on your own API key instead of a subscription. And this is not a third-party bolt-on: the HyperFrames repo itself publishes the SKILL.md you drop into an Open Design checkout.

HyperFrames or Remotion

Underneath they are the same machine: headless Chrome drawing frames, FFmpeg packing them. HyperFrames says openly that it is inspired by Remotion. The bet is what differs.

HyperFramesRemotion
What you writeHTML, CSS and JavaScriptReact components and TypeScript
How motion is timedthe renderer seeks your animation to a moment, then capturesyour code reads the frame number and returns values
Web material you haveHTML, CSS and a GSAP or Lottie animation mostly drop straight ingets rewritten as components
LicenseApache-2.0its own license, free up to three employees

Said plainly, because it is the thing that matters most if you are choosing today: Remotion is more mature. More templates, more tutorials, more answered questions, far more production history, and a Remotion Lambda that has been hardened for years against a much younger distributed render path. If your team already writes React and keeps its design system in components, Remotion hands you those components, your charting libraries and typed composition inputs.

HyperFrames wins when the video has to be written by an agent, when you are starting from web material that already exists, or when the license is a procurement problem. In my experience those three arrive together more often than I expected.

One thing to know before attempting a migration: it runs one way, Remotion to HyperFrames. The port lints the source first and refuses compositions driven by useState or a useEffect with dependencies, because a React state machine is not a deterministic capture target. What it does translate, it grades: render the original with Remotion, render the translation, diff the two with SSIM. A translation that looks right but lands a few hundredths under the threshold is wrong, and it says so instead of letting you find out after publishing.

When I open it again

At the next feature that deserves a video instead of a screenshot. At the changelog for the big PR nobody will read line by line. At the chart for the monthly report, which people watch in a twelve-second MP4 and skip in a table.

The file stays in the repository next to the code it describes. When the feature changes, the video updates in a diff instead of an email to somebody.

Facing something similar?

If you are dealing with the same problem on your product, get in touch. Worst case, you get a free opinion.

Let's talk

Read next

ArchitectureAI

Archify: a diagram of the system you are about to change

An agent skill you install once: the diagram you would have drawn yourself, if you had the afternoon

5 min read

AIDevOps

DeepSeek V4-Flash instead of Opus: where it holds

Three weeks on the preview inside Claude Code, and this morning the 0731 weights under MIT

5 min read