npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

motion-components

v0.5.0

Published

Framework-agnostic web components with physics-based motion. Built on Motion and Lit.

Readme

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

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/dist/index.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/motion-components/dist/preload.css" />

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

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 |

// vite.config.js
vue({
  template: {
    compilerOptions: {
      isCustomElement: (tag) => tag.startsWith('motion-'),
    },
  },
})
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

Text 🔗

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

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

Code 🔗

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/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.


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 run typecheck    # tsc --noEmit
npm run lint         # ESLint
npm run format       # Prettier
npm run check:preload # validate FOUC preload rules
npm run size         # bundle size budget check

Repo layout

src/
├── reveal/      entrance & transition effects
├── respond/     input-driven interactivity
├── text/        typography effects
├── scroll/      scroll-driven components
├── components/  ready-made widgets
└── code/        code-display components

See CONTRIBUTING.md for component authoring conventions.


Documentation

www.motion-components.dev


Showcase

Showcase 🔗 · Parallax 🔗 · Scene 🔗 · Motion Font 🔗


License

MIT © Tanja Gomilar