Files
hyperframes/docs/guides/hyperframes-vs-remotion.mdx
T
Ular Kimsanov 0390f3f908 docs(studio): the browser editor in six pages, named the browser editor (#6379)
* docs(studio): the browser editor in six pages, named the browser editor

* docs(studio): mute where the editor has it, and no solo control

The audio pages still described a solo control and a group-row mute that
the editor does not render. Muting is the speaker button on an audio
track (Mute track / Unmute track), the same toggle on a selected clip,
and the Muted switch; a group is silenced through its members' tracks.
The audio reference drops its solo section for the same reason.
2026-10-26 06:24:53 +00:00

200 lines
8.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "HyperFrames vs Remotion"
sidebarTitle: "vs Remotion"
description: "The same launch video made by an agent with Remotion and with HyperFrames, side by side; the same title card in both codes; and an honest read on which fits your project."
---
import { DocsVideo } from "/snippets/docs-video.jsx";
Both tools make video out of web pages. Both open a real browser, draw each
frame, and encode the result. The difference is what you write.
Remotion asks for a React component. HyperFrames asks for an HTML file.
## Same request, two agents
We gave Claude Code (Opus 5.5) the same one-paragraph request twice: once with only Remotion's official agent skills
installed, once with only HyperFrames'. One run each, no retries, nothing edited afterwards.
> Make a 15-second 1920x1080 launch video for a fictional note-taking app called Inkwell (tagline: "Write it down. Find
> it later."). Logo reveal, three short feature lines, then an end card with the tagline. No voice. Render the final MP4
> to out.mp4 in this folder. Don't ask me questions; make the choices yourself.
<div className="hf-versus">
<div>
<p><strong>Remotion</strong></p>
<DocsVideo title="Inkwell, made with Remotion" src="https://static.heygen.ai/hyperframes-oss/docs/films/vs-remotion-v1.mp4" poster="/public/images/films/vs-remotion-v1.jpg" />
</div>
<div>
<p><strong>HyperFrames</strong></p>
<DocsVideo title="Inkwell, made with HyperFrames" src="https://static.heygen.ai/hyperframes-oss/docs/films/vs-hyperframes-v1.mp4" poster="/public/images/films/vs-hyperframes-v1.jpg" />
</div>
</div>
| | Remotion | HyperFrames |
| --- | --- | --- |
| Time to a rendered MP4 | 12 min 30 s | 11 min 50 s |
| What it wrote | 10 TypeScript files, 1,037 lines | 4 HTML files, 822 lines |
| Installed into the project | about 950 MB of `node_modules` | nothing |
| Sound | none | a music bed and five sound effects it chose |
Both are good videos; a single run decides nothing about quality. The difference that lasts is what you are left
holding: a React project to keep building in code, or HTML files you can open in a browser, edit with an agent, or
keep changing in the [Studio app](/studio-app/index).
## The same title card, written both ways
Here is the same three seconds — a title that fades in, holds, and fades out —
written both ways. Neither version is padded or crippled to make a point.
**Remotion.** The component is a function of the current frame number. You do
the timing math yourself, in frames.
```tsx
import { AbsoluteFill, interpolate, useCurrentFrame } from "remotion";
export const TitleCard = () => {
const frame = useCurrentFrame();
// fade in over frames 0-15, hold to 75, fade out by 90
const opacity = interpolate(frame, [0, 15, 75, 90], [0, 1, 1, 0], {
extrapolateLeft: "clamp",
extrapolateRight: "clamp",
});
return (
<AbsoluteFill
style={{ backgroundColor: "#0a0a0a", justifyContent: "center", alignItems: "center" }}
>
<div style={{ fontSize: 160, fontWeight: 800, color: "#fff", opacity }}>HELLO</div>
</AbsoluteFill>
);
};
```
A `<Composition>` entry in another file registers it as 90 frames at 30fps,
1280×720.
**HyperFrames.** The markup declares when things are on screen. A GSAP timeline
declares how they move. Both live in one file.
```html
<style>
#stage { position: relative; width: 1280px; height: 720px; overflow: hidden; background: #0a0a0a; }
.clip { position: absolute; inset: 0; display: grid; place-items: center; }
#title { font-size: 160px; font-weight: 800; color: #fff; opacity: 0; }
</style>
<div id="stage" data-composition-id="title-card" data-start="0"
data-width="1280" data-height="720" data-duration="3" data-fps="30">
<div id="card" class="clip" data-start="0" data-duration="3" data-track-index="0">
<div id="title">HELLO</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.2/dist/gsap.min.js"></script>
<script>
// same fade, written in seconds instead of frames
const tl = gsap.timeline({ paused: true });
tl.to("#title", { opacity: 1, duration: 0.5, ease: "none" }, 0);
tl.to("#title", { opacity: 1, duration: 2.0, ease: "none" }, 0.5);
tl.to("#title", { opacity: 0, duration: 0.5, ease: "none" }, 2.5);
window.__timelines = window.__timelines || {};
window.__timelines["title-card"] = tl;
</script>
```
That is the whole file apart from `<head>` boilerplate. Three rules make it
render: every visible slot carries `class="clip"` with an `id`, `data-start`,
`data-duration`, and `data-track-index`; the timeline is created **paused**; and
it is registered on `window.__timelines` under the same id as the root element.
Miss the last one and you get a still frame with no motion. The
[HTML schema](/reference/html-schema) lists every attribute.
Neither file is obviously better. The Remotion one is a pure function you can
reason about in your head. The HyperFrames one is a page you can open in a
browser and inspect with devtools.
## Where they actually differ
| | HyperFrames | Remotion |
| --- | --- | --- |
| What you write | HTML, CSS, and JavaScript | React and TypeScript |
| How motion is timed | The renderer pauses your animation and *seeks* it — jumps it to an exact moment — before capturing each frame | Your code reads the frame number and returns the values for that frame |
| Existing web material | HTML, CSS, and a GSAP or Lottie animation usually drop in close to as-is | Rewritten as React components |
| License | [Apache 2.0](https://github.com/heygen-com/hyperframes/blob/main/LICENSE) | Its own license — free for individuals and companies up to three people, paid above that. Check the [current terms](https://www.remotion.pro/license) |
The seeking model is the interesting one. Because HyperFrames drives the
animation rather than watching a clock, GSAP, Web Animations, Lottie, and other
browser runtimes render deterministically — the same frame comes out the same
every time. See [Frame adapters](/concepts/frame-adapters) and
[Deterministic rendering](/concepts/determinism).
Both projects ship a visual editor and both save changes back to source.
[The HyperFrames browser editor](/studio) edits the same DOM the renderer captures. Remotion
Studio edits React compositions. They are not interchangeable, and neither
replaces editing the source for real structural changes.
Both render on AWS Lambda. HyperFrames also renders locally, on HeyGen's hosted
cloud, and on Google Cloud Run — see [rendering paths](/deploy/overview).
## What Remotion does better
Say this plainly, because it matters if you are choosing today.
Remotion is older and much more established. It has more templates, more
tutorials, more answered questions, and far more production history. Remotion
Lambda in particular is a mature, heavily documented rendering system; ours is
newer.
If your team already writes React, Remotion gives you your components, your
design system, your charting libraries, and typed, validated composition inputs
for free. Nothing to translate.
And its model is genuinely simpler to hold in your head. One pure function of
the frame number, no timeline to register, no contract to get subtly wrong.
HyperFrames asks you to follow rules — paused timeline, no wall clocks, no
unseeded randomness — and breaks quietly if you don't.
## What HyperFrames does better
You do not need React, a build step, or a component rewrite. A website, an HTML
prototype, an exported design, or an existing browser animation is already
close to a composition.
It is built for an AI agent to author. The [agent skills](/guides/skills)
encode the framework's rules, so the agent writes valid compositions instead of
guessing, and a human can then edit the same file in the browser editor.
And Apache 2.0 means no seat count and no license review.
## Moving a Remotion project across
There is a real migration path, not a promise. Install the skill:
```bash
npx skills add heygen-com/hyperframes --skill remotion-to-hyperframes
```
Then ask your agent to port the composition. It maps `useCurrentFrame` and
`interpolate` onto timeline tweens, `Sequence` onto clips, and converts frames
to seconds.
The harder cases are the point of the skill. It refuses to translate what does not
fit: React state machines built on `useState` or `useEffect`, async metadata,
third-party React UI libraries. Those get flagged instead of silently
mistranslated. It also grades its own output — it renders both versions and
compares them frame by frame, and it writes down anything it dropped.
Migrate because your source material or your team fits better on this side. Not
because one framework looks newer.
## Related topics
- [How a HyperFrames composition works](/concepts/compositions)
- [Install and use the agent skills](/guides/skills)
- [Choose a rendering path](/deploy/overview)