Remotion to HyperFrames
Overview
Translate Remotion (React-based) video compositions into HyperFrames (HTML + GSAP) compositions. Most Remotion idioms have direct HyperFrames equivalents — the translation is mechanical for ~80% of typical compositions. This skill encodes the mapping and guards against the lossy 20% by refusing to translate patterns that don't fit HF's seek-driven model and recommending the runtime interop pattern from
PR #214 instead.
The skill ships with a tiered test corpus (T1–T4, 4 fixtures total) that grades translations against measured SSIM thresholds. Don't translate without running the eval — a translation that "looks right" but renders 0.05 SSIM lower than the validated baseline is silently wrong.
Workflow
Step 1: Lint the source
Run
over the Remotion source directory. The lint detects patterns that can't translate cleanly:
- Blockers (refuse + recommend interop): , , / with non-empty deps, async , third-party React UI libraries (MUI, Chakra, Mantine, antd, shadcn, Radix, NextUI).
- Warnings (translate after dropping the construct): config, , , , custom hooks.
- Info (translate with note): , .
If any blocker fires,
stop. Read
references/escape-hatch.md
and surface the recommendation message. Warnings don't stop translation — drop the offending construct in step 3 and note the gap in
.
config is the canonical warning case: the skill drops the import +
calls but translates the rest of the composition.
Step 2: Plan the translation
Read
— the index of every Remotion API and its HF equivalent or per-topic reference. Identify which topic references you'll need based on what the source uses:
| Source contains | Load reference |
|---|
| , , , | |
| , , , , | |
| , , , , | |
| , , , , , | |
| , | |
| |
@remotion/google-fonts/<Family>
, , | |
Don't load all of them — load only what the specific source needs.
Step 3: Generate the HF composition
- Root carrying the composition's , , (in seconds), , , , plus one per scalar prop.
- A flat list of scene divs with / / .
- Inline for layout; CSS sets the state of every animated property.
- A single tag at the bottom containing one paused
gsap.timeline({paused: true})
. Every Remotion derivation becomes a tween on this timeline at the right offset.
window.__timelines["<composition-id>"] = tl;
registers the timeline with HF's runtime.
Custom React subcomponents inline as repeated HTML using the prop interface as the template (see
for the per-instance
pattern).
Step 4: Validate
Run the eval harness —
for the full guide. Quick path:
bash
# Render Remotion baseline (after npm install in the fixture)
cd remotion-src && npx remotion render <CompositionId> out/baseline.mp4
# Render HF translation
cd ../hf-src && npx hyperframes render --output ../hf.mp4
# SSIM diff
../../scripts/render_diff.sh ./remotion-src/out/baseline.mp4 ./hf.mp4 ./diff
Threshold: ~0.02 below
of the source's complexity tier (see
's validated thresholds table). If the diff fails, run
to see
which frames diverged, then re-read the relevant timing/sequencing/media reference.
Critical: both renders must use matching pixel format. Set
Config.setVideoImageFormat("png")
+
Config.setColorSpace("bt709")
in the Remotion source's
— otherwise the diff measures encoder differences (~0.05 SSIM hit), not translation fidelity.
Step 5: Document gaps
Anything that didn't translate cleanly (volume ramps dropped, custom presentations approximated, fonts substituted) gets a
written next to the HF output. See
references/limitations.md
for the format.
What this skill explicitly does NOT do
- Translate React state machines. Compositions that drive animation via + are not deterministic frame-capture targets in HyperFrames' seek-driven model. Recommend the runtime interop pattern.
- Run Remotion's render pipeline alongside HyperFrames. That's the runtime interop pattern from PR #214 — a separate solution for compositions that fail this skill's lint.
(
is
not a blocker — Lambda config is deployment, not animation. The skill drops it as a warning and translates the rest. See
references/escape-hatch.md
.)
How to grade your own translation
Run the test corpus orchestrator:
bash
./assets/test-corpus/run.sh
It runs T1, T2, T3 (render + diff) and T4 (lint validation), prints a per-tier pass/fail table, and emits an aggregate JSON report. Use this to verify the skill is working end-to-end on a clean checkout — and as a regression check after editing any reference.
Validated baseline (as of 2026-04-27):
| Tier | Composition shape | Mean SSIM | Threshold |
|---|
| T1 | single-element fade-in | 0.974 | 0.95 |
| T2 | multi-scene + spring + audio + image | 0.985 | 0.95 |
| T3 | data-driven, custom subcomponents, count-up | 0.953 | 0.90 |
| T4 | escape-hatch (8 lint cases) | 8/8 pass | n/a |