* perf(studio): tag each scene's parts in the preview so one can be swapped With sceneParts (Studio preview only) the bundler tags each top-level scene's host, styles and inline scripts with data-hf-scene; nested scenes belong to their top-level scene. The preview route then adds a manifest: a hash of everything outside the scenes and one hash per scene, so the preview can tell when a rebuilt document differs only inside some scenes. Renders are unchanged. * fix(core): keep scene order in the preview manifest and mark unswappable scenes A moved or reordered scene now changes the shared hash, a nested scene keeps its @import first, and a scene whose script leaves work running is marked so edits to it take the full reload. * refactor(core): keep the scene swap side-effect check in the bundler * fix(core): refuse swapping a scene that runs its own script file A swap never re-runs external scripts, so a scene file keeps driving the replaced nodes. Library URLs stay swappable. * fix(core): refuse swaps for async scene setup and keep the shared @import first Scenes that finish building after an await or a .then, animate elements directly or touch the page head and body now take the full reload, and splitting out scene styles no longer leaves the shared import late. * fix(core): refuse swaps for scene scripts that throw when run again Custom element and CSS property registration, sockets, draggables and infinite tweens now refuse too, and ticker or animate inside a name no longer does. * fix(core): refuse swapping a scene that runs a module script or import map * fix(core): run a scene's local script file in source order in the preview * fix(core): refuse a scene swap only for defineProperty on a global * refactor(core): cut scene swap comments to what names and types do not say * fix(core): find the head tag for the scene manifest in linear time * fix(core): leave a document with an unclosed head tag without a scene manifest * fix(core): keep preview scene parts in render order and refuse scene-only script URLs * fix(core): keep render @import precedence in the preview and swap only known libraries * fix(core): keep preview scene styles where a render merges them and resolve library URLs * fix(core): scene swap refuses standalone gsap tweens and root scripts that hold scene nodes * fix(core): refuse to swap exactly the scenes a script outside them selects * perf(core): the preview scene scan looks up ids and classes once instead of querying per string * docs(core): trim three scene-parts comments to the facts a reader needs * fix(core): refuse to swap a scene a script outside it reaches by tag name * fix(core): keep scenes swappable when a script outside them only creates elements by tag * test(core): check scene tags on elements, not in the inlined runtime's text * fix(core): refuse swaps for chained scene timelines and any-case or universal root selectors * fix(core): refuse swaps for root selectors through tags above the scenes * fix(core): put the scene manifest inside the head when a head attribute holds a quoted > * fix(core): place the scene manifest with the shared head scanner instead of a regex
@hyperframes/core
Types, parsers, generators, compiler, linter, runtime, and frame adapters for the Hyperframes video framework.
Install
npm install @hyperframes/core
Most users don't need to install core directly — the CLI, producer, and studio packages depend on it internally.
What's inside
| Module | Description |
|---|---|
| Types | TimelineElement, CompositionSpec, Asset, canvas dimensions, defaults |
| Parsers | parseHtml — extract timeline elements from HTML; parseGsapScript — parse GSAP animations |
| Generators | generateHyperframesHtml — produce valid Hyperframes HTML from a composition spec |
| Compiler | compileTimingAttrs — resolve data-start / data-duration into absolute times |
| Linter | lintHyperframeHtml — validate Hyperframes HTML (missing attributes, overlapping tracks, etc.) |
| Runtime | IIFE script injected into the browser — manages seek, media playback, and the window.__hf protocol |
| Frame Adapters | Pluggable animation drivers (GSAP, Lottie, CSS, or custom) |
Generated composition trust
Composition generators require trusted authors for code-bearing inputs. styles and
generateHyperframesStyles preserve authored CSS, which can load external resources.
animations may contain __raw: values that are emitted as JavaScript;
includeScripts: true includes executable timeline code. serializeGsapAnimations
also accepts raw preamble, postamble, and a code-bearing timelineVar. Never fill
these inputs with untrusted data. Attribute encoding and closing-tag containment
are not a sandbox; render untrusted compositions in an appropriately isolated
execution environment and never serve them on a privileged origin.
Text content retains the supported inline-formatting sanitizer contract. The clip parser intentionally flattens inner formatting to text, so parse/generate is not a lossless replacement for editing the source HTML.
Frame Adapters
A frame adapter tells the engine how to seek your animation to a specific frame:
import { createGSAPFrameAdapter } from "@hyperframes/core";
const adapter = createGSAPFrameAdapter({
getTimeline: () => gsap.timeline(),
compositionId: "my-video",
});
Implement FrameAdapter for custom animation runtimes:
import type { FrameAdapter } from "@hyperframes/core";
const myAdapter: FrameAdapter = {
id: "my-adapter",
getDurationFrames: () => 300,
seekFrame: (frame) => {
/* seek your animation */
},
};
Parsing and generating HTML
import { parseHtml, generateHyperframesHtml } from "@hyperframes/core";
const { elements, metadata } = parseHtml(htmlString);
const html = generateHyperframesHtml(spec);
Linting
import { lintHyperframeHtml } from "@hyperframes/core/lint";
const result = lintHyperframeHtml(htmlString);
// result.findings: { severity, message, elementId }[]
Documentation
Full documentation: hyperframes.heygen.com/packages/core
Related packages
@hyperframes/engine— rendering engine that drives the browser@hyperframes/producer— full render pipeline (capture + encode)hyperframes— CLI