The core resolves a MotionDoc to a tree of final numbers. An adapter is a thin painter that walks that tree and draws it for one backend. Because they all paint the same tree, an animation looks and times identically wherever it runs.

Paint backends

These packages actually draw pixels / DOM / native views:

@blinn-motion/dom

Full-fidelity CSS: nested divs, gradients, SVG vector paths, masks and shaders.

@blinn-motion/canvas

Pure-JS 2D canvas — one immediate-mode draw per frame, zero DOM nodes.

@blinn-motion/react-native

Native <View> / <Text> on iOS/Android (Expo or bare RN).

Framework bindings

These wrap dom and/or canvas with idiomatic components / actions / elements. Playback surface matches React: play, pause, seek, progress (0…1), rate.

@blinn-motion/react

<BlinnMotion /> + useBlinnMotionrenderer="dom" | "canvas".

@blinn-motion/vue

Vue 3 component + useBlinnMotion composable.

@blinn-motion/svelte

use:blinnMotion action + attachBlinnMotion.

@blinn-motion/angular

Standalone <blinn-motion> component.

@blinn-motion/lit

<blinn-motion> custom element for any stack.

Meta-frameworks (no extra package)

Use an existing adapter inside the host framework: Runnable demos live under examples/ in the monorepo (vue, svelte, angular, lit, next, astro, expo, …).

Same control surface

Every painter builds on the core Ticker: Framework bindings expose the same surface via refs, composables, component methods, or the custom element instance.

Fidelity at a glance

* React / Vue / Svelte / Angular / Lit with renderer="dom" inherit DOM fidelity; renderer="canvas" inherits Canvas fidelity.
The DOM adapter is the fidelity reference. Canvas and React Native trade some rarer effects for portability.