Skill Tracer
Skills › HyperFrames › remotion-to-hyperframes › api-map.md

api-map.md

154 lines · skills/remotion-to-hyperframes/references/api-map.md at a595755

Open on GitHub

Most marks come from matching words in the file, so treat them as pointers.

1# Remotion → HyperFrames API Map
2
3Authoritative translation table. Load this reference when starting a translation
4to know the high-level mapping; load the per-topic references for fragile
5details (timing, transitions, etc.).
6

Remotion → HyperFrames API Map

Authoritative translation table. Load this reference when starting a translation to know the high-level mapping; load the per-topic references for fragile details (timing, transitions, etc.).

Raw lines 1 to 6
7## Reading this table
8
9- **`drop`** = remove from output entirely. The HF runtime handles it.
10- **`see references/X.md`** = the mapping is non-trivial; read the linked file.
11- **`refuse + interop`** = the skill bows out and recommends the runtime adapter
12 pattern from [PR #214](https://github.com/heygen-com/hyperframes/pull/214).

Reading this table

  • **drop** = remove from output entirely. The HF runtime handles it.
  • **see references/X.md** = the mapping is non-trivial; read the linked file.
  • **refuse + interop** = the skill bows out and recommends the runtime adapter pattern from PR #214.
Raw lines 7 to 13
14## Composition root
16| Remotion | HyperFrames |
17| ------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------- |
18| `<Composition id durationInFrames fps width height>` | root `<div id="stage" data-composition-id data-start="0" data-duration="<dur/fps>" data-fps data-width data-height>` |
19| `defaultProps={...}` | `data-*` attributes on `#stage` (one per scalar prop). Nested objects/arrays — see [parameters.md](parameters.md) |
20| `schema={z.object(...)}` | not represented in HTML; the schema lives in the agent's translation step only |
21| `calculateMetadata` (sync) | resolve at translation time, write concrete values into `data-*` |
22| `calculateMetadata` (async) | **refuse + interop** — see [escape-hatch.md](escape-hatch.md) |
23| `registerRoot(RemotionRoot)` | drop |
24| `<AbsoluteFill style>` | `<div style="position:absolute;inset:0;{style}">` |
25| Remotion's render page: `* { box-sizing: border-box }` | the same rule, once, in the root `index.html` `<style>` (see below) |
27Remotion's render page sets `* { box-sizing: border-box }`, so a `width` there already includes the border and padding. A browser's own default is `content-box`, so a port without the rule draws every bordered or padded element larger. This box is 200 by 100 in Remotion and with the rule; without it, it is 260 by 160:
29```html
30<style>
31 * {
32 box-sizing: border-box;
33 }
34</style>
35<div style="width:200px;height:100px;padding:20px;border:10px solid #fff">…</div>
36```

Composition root

RemotionHyperFrames
<Composition id durationInFrames fps width height>root <div id="stage" data-composition-id data-start="0" data-duration="<dur/fps>" data-fps data-width data-height>
defaultProps={...}data-* attributes on #stage (one per scalar prop). Nested objects/arrays — see parameters.md
schema={z.object(...)}not represented in HTML; the schema lives in the agent's translation step only
calculateMetadata (sync)resolve at translation time, write concrete values into data-*
calculateMetadata (async)refuse + interop — see escape-hatch.md
registerRoot(RemotionRoot)drop
<AbsoluteFill style><div style="position:absolute;inset:0;{style}">
Remotion's render page: * { box-sizing: border-box }the same rule, once, in the root index.html <style> (see below)

Remotion's render page sets * { box-sizing: border-box }, so a width there already includes the border and padding. A browser's own default is content-box, so a port without the rule draws every bordered or padded element larger. This box is 200 by 100 in Remotion and with the rule; without it, it is 260 by 160:

<style>
  * {
    box-sizing: border-box;
  }
</style>
<div style="width:200px;height:100px;padding:20px;border:10px solid #fff">…</div>
Raw lines 14 to 37
38## Sequencing
40See [sequencing.md](sequencing.md) for nesting and stagger details.
42| Remotion | HyperFrames |
43| ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
44| `<Sequence from={F} durationInFrames={D}>` | a host `<div data-composition-src="compositions/<name>.html" data-start="<F/fps>" data-duration="<D/fps>" data-track-index="N">` in the root, its content in that sub-composition file (see [sequencing.md](sequencing.md)) |
45| `<Series>` + `<Series.Sequence>` | sibling scene hosts with sequential `data-start` values |
46| `<Loop durationInFrames={D}>` | not a primitive — emit a bounded GSAP repeat from the available duration |
47| `<Freeze frame={F}>` | drop the wrapper; HF doesn't have running animation outside the seek-driven timeline so freeze is a no-op |

Sequencing

See sequencing.md for nesting and stagger details.

RemotionHyperFrames
<Sequence from={F} durationInFrames={D}>a host <div data-composition-src="compositions/<name>.html" data-start="<F/fps>" data-duration="<D/fps>" data-track-index="N"> in the root, its content in that sub-composition file (see sequencing.md)
<Series> + <Series.Sequence>sibling scene hosts with sequential data-start values
<Loop durationInFrames={D}>not a primitive — emit a bounded GSAP repeat from the available duration
<Freeze frame={F}>drop the wrapper; HF doesn't have running animation outside the seek-driven timeline so freeze is a no-op
Raw lines 38 to 48
49## Timing
51See [timing.md](timing.md) — this is the highest-leverage section.
53| Remotion | HyperFrames |
54| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
55| `useCurrentFrame()` | drop — HF seeks the timeline. The math derived from `frame` becomes an animatable property of a paused GSAP tween. |
56| `useVideoConfig()` for `fps` / `durationInFrames` | drop — read from `data-fps` / `data-duration` on `#stage` |
57| `interpolate(frame, [a,b], [x,y])` (linear) | `gsap.fromTo(t, {p:x}, {p:y, duration:(b-a)/fps, ease:"none"})` at offset `a/fps` |
58| `interpolate(frame, [a,b,c,d], [x,y,y,z])` (multi-segment) | three `gsap.to` calls at offsets `a/fps`, `b/fps`, `c/fps` |
59| `interpolate(..., {easing: Easing.bezier})` | GSAP `CustomEase.create("c", "M0,0 C${a},${b} ${c},${d} 1,1")` |
60| `spring({frame, fps, config: {damping, stiffness, mass}})` | GSAP `back.out(N)` — see [timing.md](timing.md) for damping → overshoot table |
61| `interpolateColors(frame, range, colors)` | `gsap.to({...}, { backgroundColor, color, duration, ease })` — GSAP handles color tweens natively |
62| `Easing.in / .out / .inOut(Easing.poly(N))` | GSAP `power<N-1>.in` / `power<N-1>.out` / `power<N-1>.inOut` for integer N=1–5; see [timing.md](timing.md) for other exponents |

Timing

See timing.md — this is the highest-leverage section.

RemotionHyperFrames
useCurrentFrame()drop — HF seeks the timeline. The math derived from frame becomes an animatable property of a paused GSAP tween.
useVideoConfig() for fps / durationInFramesdrop — read from data-fps / data-duration on #stage
interpolate(frame, [a,b], [x,y]) (linear)gsap.fromTo(t, {p:x}, {p:y, duration:(b-a)/fps, ease:"none"}) at offset a/fps
interpolate(frame, [a,b,c,d], [x,y,y,z]) (multi-segment)three gsap.to calls at offsets a/fps, b/fps, c/fps
interpolate(..., {easing: Easing.bezier})GSAP CustomEase.create("c", "M0,0 C${a},${b} ${c},${d} 1,1")
spring({frame, fps, config: {damping, stiffness, mass}})GSAP back.out(N) — see timing.md for damping → overshoot table
interpolateColors(frame, range, colors)gsap.to({...}, { backgroundColor, color, duration, ease }) — GSAP handles color tweens natively
Easing.in / .out / .inOut(Easing.poly(N))GSAP power<N-1>.in / power<N-1>.out / power<N-1>.inOut for integer N=1–5; see timing.md for other exponents
Raw lines 49 to 63
64## Media
66See [media.md](media.md) for trim, volume ramps, and decoder notes.
68| Remotion | HyperFrames |
69| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
70| `<Audio src volume>` | `<audio data-start data-duration data-track-index data-volume src>` |
71| `<Audio playbackRate startFrom endAt>` | `data-playback-rate`, `data-trim-start`, `data-trim-end` |
72| `<Video src>` | `<video playsinline data-has-audio="true" data-start data-duration data-track-index src>` only when the file has an audio stream (check with `ffprobe -v error -select_streams a -show_entries stream=codec_type -of csv=p=0 <file>`: non-empty means it has audio) and the source is not `muted` or `volume={0}`; otherwise `muted` instead |
73| `<OffthreadVideo>` | `<video>` — HF doesn't need the off-thread variant (uses headless Chrome) |
74| `<Img src>` | `<img>` |
75| `<IFrame src>` | `<iframe>` — HF auto-falls back to screenshot mode for nested iframes |
76| `staticFile("x.png")` | `"assets/x.png"` in the root, `"../assets/x.png"` inside a `compositions/` scene file — copy the file into `hf-src/assets/` next to `index.html` |
77| `delayRender()` / `continueRender()` | drop — HF waits on asset readiness via the Frame Adapter pattern |

Media

See media.md for trim, volume ramps, and decoder notes.

RemotionHyperFrames
<Audio src volume><audio data-start data-duration data-track-index data-volume src>
<Audio playbackRate startFrom endAt>data-playback-rate, data-trim-start, data-trim-end
<Video src><video playsinline data-has-audio="true" data-start data-duration data-track-index src> only when the file has an audio stream (check with ffprobe -v error -select_streams a -show_entries stream=codec_type -of csv=p=0 <file>: non-empty means it has audio) and the source is not muted or volume={0}; otherwise muted instead
<OffthreadVideo><video> — HF doesn't need the off-thread variant (uses headless Chrome)
<Img src><img>
<IFrame src><iframe> — HF auto-falls back to screenshot mode for nested iframes
staticFile("x.png")"assets/x.png" in the root, "../assets/x.png" inside a compositions/ scene file — copy the file into hf-src/assets/ next to index.html
delayRender() / continueRender()drop — HF waits on asset readiness via the Frame Adapter pattern
Raw lines 64 to 78
79## Transitions
81See [transitions.md](transitions.md).
83| Remotion | HyperFrames |
84| ------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------- |
85| `<TransitionSeries>` + `<TransitionSeries.Transition presentation={fade()} />` | manual `gsap.to(scene, {opacity: 0/1, duration})` crossfade at the boundary |
86| `slide()`, `wipe()`, `clockWipe()`, `fade()` | HF [shader-transitions](https://hyperframes.heygen.com/catalog/blocks) package presets — pick the closest |
87| `linearTiming({durationInFrames})` | duration in seconds (`/fps`) |
88| `springTiming({config})` | duration in seconds, ease `back.out` — see [timing.md](timing.md) |

Transitions

See transitions.md.

RemotionHyperFrames
<TransitionSeries> + <TransitionSeries.Transition presentation={fade()} />manual gsap.to(scene, {opacity: 0/1, duration}) crossfade at the boundary
slide(), wipe(), clockWipe(), fade()HF shader-transitions package presets — pick the closest
linearTiming({durationInFrames})duration in seconds (/fps)
springTiming({config})duration in seconds, ease back.out — see timing.md
Raw lines 79 to 89
90## Lottie
92See [lottie.md](lottie.md).
94| Remotion | HyperFrames |
95| ------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
96| `<Lottie animationData={data}>` | `<div id="lottie-N">` + `<script>const anim = lottie.loadAnimation({...}); window.__hfLottie.push(anim)</script>` |
97| `loop` / `playbackRate` props | translate only after checking player seek behavior; HF adapter seeks absolute time via `goToAndStop` |
98| `@remotion/lottie` runtime | `lottie-web` from CDN — drop the React wrapper |

Lottie

See lottie.md.

RemotionHyperFrames
<Lottie animationData={data}><div id="lottie-N"> + <script>const anim = lottie.loadAnimation({...}); window.__hfLottie.push(anim)</script>
loop / playbackRate propstranslate only after checking player seek behavior; HF adapter seeks absolute time via goToAndStop
@remotion/lottie runtimelottie-web from CDN — drop the React wrapper
Raw lines 90 to 99
100## Fonts
102See [fonts.md](fonts.md).
104| Remotion | HyperFrames |
105| --------------------------------------------------- | ------------------------------------------------------------------------------------------- |
106| `loadFont()` from `@remotion/google-fonts/<Family>` | `@font-face` rule referencing the Google Fonts CSS, OR `<link>` to Google Fonts in `<head>` |
107| Local font via `@font-face` | same — paste the rule into `<style>` |
108| System font fallback | document the font-fallback divergence cost (see [eval.md](eval.md)) |

Fonts

See fonts.md.

RemotionHyperFrames
loadFont() from @remotion/google-fonts/<Family>@font-face rule referencing the Google Fonts CSS, OR <link> to Google Fonts in <head>
Local font via @font-facesame — paste the rule into <style>
System font fallbackdocument the font-fallback divergence cost (see eval.md)
Raw lines 100 to 109
110## Parameters
112See [parameters.md](parameters.md).
114| Remotion | HyperFrames |
115| ----------------------------- | --------------------------------------------------------------------------------------------- |
116| `z.object({foo: z.string()})` | `data-foo` on `#stage` (the schema is implicit in HTML structure) |
117| nested array prop (`stats[]`) | repeated HTML markup with per-instance `data-*` attrs |
118| Zod default values | bake defaults into the HTML directly |
119| Zod runtime validation | not represented; if validation matters, validate in the translation step before emitting HTML |

Parameters

See parameters.md.

RemotionHyperFrames
z.object({foo: z.string()})data-foo on #stage (the schema is implicit in HTML structure)
nested array prop (stats[])repeated HTML markup with per-instance data-* attrs
Zod default valuesbake defaults into the HTML directly
Zod runtime validationnot represented; if validation matters, validate in the translation step before emitting HTML
Raw lines 110 to 120
121## React patterns
123| Remotion | HyperFrames |
124| -------------------------------------------------- | ---------------------------------------------------------------- |
125| Custom React subcomponent (pure, prop-driven) | inline as repeated HTML using the prop interface as the template |
126| `useState` driving animation | **refuse + interop** |
127| `useReducer` driving animation | **refuse + interop** |
128| `useEffect(fn, [deps])` (non-empty deps) | **refuse + interop** |
129| `useEffect(fn, [])` (mount-once side effect) | drop the effect; use `queueMicrotask` if startup work is needed |
130| `useCallback`, `useMemo` | drop the wrappers — decorative |
131| Custom hook (pure derivation of `useCurrentFrame`) | inline the body |
132| Custom hook with state/effects | refuse + interop |

React patterns

RemotionHyperFrames
Custom React subcomponent (pure, prop-driven)inline as repeated HTML using the prop interface as the template
useState driving animationrefuse + interop
useReducer driving animationrefuse + interop
useEffect(fn, [deps]) (non-empty deps)refuse + interop
useEffect(fn, []) (mount-once side effect)drop the effect; use queueMicrotask if startup work is needed
useCallback, useMemodrop the wrappers — decorative
Custom hook (pure derivation of useCurrentFrame)inline the body
Custom hook with state/effectsrefuse + interop
Raw lines 121 to 133
134## Distributed rendering
136`@remotion/lambda` and `@remotion/cloudrun` are deployment configuration —
137orthogonal to the rendered composition itself. The skill emits these as
138**warnings** (not blockers) and drops them in step 3 (Generate) with a note
139in `TRANSLATION_NOTES.md`. HF is single-machine today; document the gap.
141| Remotion | HyperFrames |
142| -------------------------- | ------------------------------------------------------ |
143| `@remotion/lambda` import | drop the import (warning `r2hf/lambda-import`) |
144| `renderMediaOnLambda(...)` | drop the call; note in `TRANSLATION_NOTES.md` |
145| `@remotion/cloudrun` | drop the import + call; note in `TRANSLATION_NOTES.md` |

Distributed rendering

@remotion/lambda and @remotion/cloudrun are deployment configuration — orthogonal to the rendered composition itself. The skill emits these as warnings (not blockers) and drops them in step 3 (Generate) with a note in TRANSLATION_NOTES.md. HF is single-machine today; document the gap.

RemotionHyperFrames
@remotion/lambda importdrop the import (warning r2hf/lambda-import)
renderMediaOnLambda(...)drop the call; note in TRANSLATION_NOTES.md
@remotion/cloudrundrop the import + call; note in TRANSLATION_NOTES.md
Raw lines 134 to 146
147## When to bow out entirely
149If any blocker pattern is present, recommend the runtime interop pattern from
150[PR #214](https://github.com/heygen-com/hyperframes/pull/214) instead of
151attempting translation. See [escape-hatch.md](escape-hatch.md).
153The blockers are documented in [`scripts/lint_source.py`](../scripts/lint_source.py)
154and tested by [tier-4-escape-hatch](../assets/test-corpus/tier-4-escape-hatch/).

When to bow out entirely

If any blocker pattern is present, recommend the runtime interop pattern from PR #214 instead of attempting translation. See escape-hatch.md.

The blockers are documented in [scripts/lint_source.py](../scripts/lint_source.py) and tested by tier-4-escape-hatch.

Raw lines 147 to 154
Runs code scripts/lint_source.py :153