About
The motion layer
your is missing
Motion is not only decoration
.
We live in an era of instantaneous interfaces. Pages snap in. Modals appear. Content jumps into place. Every interaction is a hard cut — and every hard cut teaches the brain that this world has no physics, no weight, no continuity.
Motion is the connective tissue of experience. When an element moves with mass — when it overshoots and settles, when it carries velocity from one state into the next — it stops being a component and starts being something you can trust. Your finger knows the difference. Your eye knows the difference.
motion-components exists because good motion shouldn't require a dedicated animation engineer or a working knowledge of bezier curves. It should be a tag you drop in. The physics come free.
-
composable components -
import. registers everything. - ~
brotlied, all 37 — tree-shake from there.
What are web components?
Web components are native browser APIs for defining custom HTML elements. A tag like
Most frameworks work with custom elements, but some require a small amount of configuration to prevent their compilers treating unknown tags as errors. See the framework setup section below.
Framework setup
Vanilla HTML / Astro / Svelte / SolidJS / Alpine
No configuration needed. Import the library once and use the tags directly.
Vue 3
Vue's template compiler warns on unknown tags by default. Tell it to treat any motion-* tag as a custom element:
Angular
Angular's template compiler errors on unknown elements. Add CUSTOM_ELEMENTS_SCHEMA to any module or standalone component that uses motion-components:
For standalone components:
React
React 19 has full custom element support. For React 18 and earlier, boolean attributes and custom events require extra handling. Full React wrappers are coming soon.
Customising components
1. HTML attributes
The primary API is plain HTML attributes. Every tunable value — spring duration, scale, direction — is exposed as an attribute with a sensible default.
2. CSS custom properties
CSS custom properties inherit across the shadow DOM boundary. Components that render visible
UI expose custom properties you can override from the outside. For example,
3. Extending components
Each component is a standard custom element class. Subclass it to change defaults or add behaviour:
4. Composing primitives
Wrap primitives inside each other — they each do one thing and never interfere:
How it's built
Components are authored with Lit — a small library that adds reactive properties and declarative templates on top of the native custom element APIs. Lit is bundled into the output and never appears as a peer dependency.
All animations go through Motion — a spring physics animation library. Springs replace cubic-bezier easing curves, so animations are naturally interruptible: interrupt one mid-flight and it continues from its current velocity rather than snapping.
Design philosophy
- Motion-first. Animation is not a coating applied after the fact — it is a core part of how interfaces communicate. Every component is designed from that premise.
- No janky animations. Springs replace duration-based easing. An interrupted spring continues from its current velocity; an interrupted cubic-bezier snaps. The difference is felt immediately.
- One responsibility per component. Primitives do one thing well. Complexity comes from composition, not configuration.
- Accessibility is not optional.
prefers-reduced-motionis checked at the animation layer. Components degrade gracefully without any extra work from the consumer.