Skip to content

About

Web components with spring physics animations. Drop into any HTML page or framework. Built around motion from the start, not retrofitted with it. Every component uses spring physics, interruptible animations, and composable primitives so interactions feel natural.

Topics

Resources

Contributing

Stars

14 stars

Watchers

2 watching

Forks

Repository files navigation

npm size CI

motion-components

Drop-in web components with spring-physics animations. Works in any framework - or no framework at all.

Architected with animation as a core concern from day one - not bolted on as an afterthought. Every component leverages spring physics, interruptible animations, and composable primitives to deliver interactions that feel natural and responsive.

β–Έ Reveal elements on scroll  ▸ Hover/press/tilt responses  ▸ Character-by-character text effects  ▸ Parallax & scroll scenes  ▸ Sliders, dialogs, image comparisons & more

πŸ‘‰ Docs & Live Preview

Built with Motion and Lit. Full TypeScript types included.


Quick start

1. Install

npm install motion-components@^1

2. Import & use

// Import all components
import 'motion-components'

// Import separate components (tree shakable)
import 'motion-components/motion-reveal'
import 'motion-components/motion-hover'
import 'motion-components/motion-stagger'

// Prevent content flash before animations run
import 'motion-components/preload.css'
<motion-reveal>
  <h1>Animates in when scrolled into view</h1>
</motion-reveal>

<motion-hover scale="1.05">
  <button>Hover me</button>
</motion-hover>

<motion-stagger interval="0.06">
  <p>First child</p>
  <p>Second child</p>
  <p>Third child</p>
</motion-stagger>

CDN - no build step

<script type="module" src="https://cdn.jsdelivr.net/npm/motion-components@1/+esm"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/motion-components@1/dist/preload.css" />

<motion-reveal>
  <h1>Animates in when scrolled into view</h1>
</motion-reveal>

CommonJS

require('motion-components') works on Node 20.19+, 22.12+ and 23+. Jest needs ES module support turned on.


Framework setup

Framework Config needed?
Astro, Svelte, Solid, Preact None
React Use React 19+ (native web component support). React 18 has limited support - upgrade if possible.
Vue 3 Tell the compiler to treat motion-* as custom elements
Angular Add CUSTOM_ELEMENTS_SCHEMA
Plain HTML Use the CDN script tag above
Vue 3 config
// vite.config.js
vue({
  template: {
    compilerOptions: {
      isCustomElement: (tag) => tag.startsWith('motion-'),
    },
  },
})
Angular config
import { CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core'

@Component({
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class MyComponent {}

Components

Reveal πŸ”—

Entrance & transition effects

motion-reveal motion-stagger motion-blur motion-blur-in

Respond πŸ”—

Input-driven interactivity

motion-hover motion-press motion-magnetic motion-tilt

Typography & character effects

motion-split motion-typewriter motion-counter motion-scramble motion-ticker motion-words motion-curve motion-circle motion-arc motion-headline motion-glitch motion-gravity motion-liquid motion-perspective motion-stretch motion-swap motion-text-mask motion-font motion-marker motion-underline motion-strike motion-ring

Icons πŸ”—

Animated and state-morphing icons

motion-icon motion-icon-state

Scroll πŸ”—

Scroll-driven animation

motion-parallax motion-scene

Components πŸ”—

Ready-made interactive components

motion-slider motion-gallery motion-dialog motion-countdown motion-spotlight motion-progress motion-image-compare motion-flip-card motion-theme-toggle motion-theme-icon

Charts πŸ”—

Animated bar, line, pie and donut charts

motion-chart motion-pie motion-sparkline

Syntax-highlighted code display

motion-code motion-code-inline


JavaScript API

Every animation component implements the same playback interface, so you can drive animations imperatively:

const el = document.querySelector('motion-typewriter')

await el.play()   // start if idle/finished, resume if paused
el.pause()        // freeze in place
el.finish()       // jump to the end state
el.cancel()       // reset to the initial state

el.playState      // 'idle' | 'running' | 'paused' | 'finished'
await el.finished // per-run promise, resolves on finish or cancel

Components emit motion-start, motion-finish, and motion-cancel events (bubbling and composed), so you can also listen at any ancestor:

document.addEventListener('motion-finish', (e) => console.log(e.target, 'done'))

Input-reactive components (motion-hover, motion-press, motion-magnetic, motion-tilt) expose a disabled property/attribute instead β€” set it to make them settle and stop responding to input.

Global controls

import { pauseAll, resumeAll, cancelAll } from 'motion-components'

pauseAll()          // pause every running animation, disable input-reactive components
resumeAll()         // resume what pauseAll paused, re-enable what it disabled
cancelAll()         // reset everything to its initial state

pauseAll(sidebar)   // all three accept a root node to scope the effect

When prefers-reduced-motion: reduce is set, play() skips straight to the final state β€” the finished promise and events still fire, so control flow keeps working.


Flash prevention (FOUC)

Web components upgrade asynchronously, so content can flash before animations are ready. Choose your prevention method:

Static stylesheet

import 'motion-components/preload.css'

CDN link

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/motion-components@1/dist/preload.css" />

Programmatic

import { preload } from 'motion-components'
preload(['motion-reveal', 'motion-split', 'motion-dialog'])

Call preload() with no arguments to cover all preload-registered components.

Raw CSS string (for Astro, Svelte, etc.)

import { preloadCSS } from 'motion-components'
// inject preloadCSS into your framework's <head> mechanism

Which components need preloading? Only those that hide content on initialization - reveal, text, stagger, dialog, and a few widgets. The build validates preload entries automatically via npm run check:preload.


Using with AI

AI assistants write better code from the current docs than from what they learned in training. Point yours at:

  • llms.txt: every component, docs page and recipe, with one line each
  • llms-full.txt: every attribute, event, slot and CSS custom property in one file
  • Any docs page as Markdown: add .md to its address, for example motion-marker.md

The package also ships editor data in dist/: custom-elements.json, VS Code custom data and web-types.json for JetBrains IDEs. Using with AI has a rules block to paste into AGENTS.md or CLAUDE.md, and the editor setup.


Why motion-components?

  • Motion-first. Built around animation from the start, not retrofitted.
  • Spring physics by default. No linear easing, no jank.
  • Interruptible. Interactions never queue or stutter - even mid-animation.
  • Per-component imports. Each component is a standalone subpath export - no dead weight, no bundler magic required.
  • Composable. Shared primitives instead of reimplemented animations.
  • Accessible. Honors prefers-reduced-motion. Keyboard-navigable.

Development

npm install           # install dependencies
npm run build         # build library to ./dist
npm run dev           # rebuild on file change
npm test              # browser tests
npm run typecheck     # tsc --noEmit
npm run lint          # ESLint
npm run format        # Prettier
npm run check:preload # validate FOUC preload rules
npm run check:exports # validate subpath exports
npm run check:ssr     # import every entry in Node
npm run size          # bundle size budget check

Repo layout

src/
β”œβ”€β”€ reveal/      entrance & transition effects
β”œβ”€β”€ respond/     input-driven interactivity
β”œβ”€β”€ text/        typography effects
β”œβ”€β”€ icons/       animated and state-morphing icons
β”œβ”€β”€ scroll/      scroll-driven components
β”œβ”€β”€ components/  ready-made widgets
β”œβ”€β”€ charts/      data visualization
β”œβ”€β”€ code/        code-display components
β”œβ”€β”€ utils/       shared helpers
└── test/        shared test helpers

See CONTRIBUTING.md for component authoring conventions.


Documentation

www.motion-components.dev


Showcase

Showcase πŸ”— Β· Parallax πŸ”— Β· Scene πŸ”— Β· Motion Font πŸ”—


License

MIT Β© Tanja Gomilar

About

Web components with spring physics animations. Drop into any HTML page or framework. Built around motion from the start, not retrofitted with it. Every component uses spring physics, interruptible animations, and composable primitives so interactions feel natural.

Topics

Resources

Contributing

Stars

14 stars

Watchers

2 watching

Forks

Releases

Packages

Contributors

Languages