https://github.com/humanspeak/svelte-motion
Framer Motion for Svelte 5. Declarative motion.<tag> components with AnimatePresence exit animations, gestures (hover, tap, drag, focus, in-view), variants, FLIP layout animations, shared-layout transitions, spring physics, and scroll-linked motion values. The drop-in Framer Motion alternative for Svelte and SvelteKit.
https://github.com/humanspeak/svelte-motion
animate-presence animation animation-library drag framer-motion framer-motion-alternative framer-motion-svelte gestures layout-animations motion scroll-animation spring-animation ssr svelte svelte-5 svelte-animation svelte-motion sveltekit typescript variants
Last synced: 9 days ago
JSON representation
Framer Motion for Svelte 5. Declarative motion.<tag> components with AnimatePresence exit animations, gestures (hover, tap, drag, focus, in-view), variants, FLIP layout animations, shared-layout transitions, spring physics, and scroll-linked motion values. The drop-in Framer Motion alternative for Svelte and SvelteKit.
- Host: GitHub
- URL: https://github.com/humanspeak/svelte-motion
- Owner: humanspeak
- License: mit
- Created: 2025-02-21T02:38:20.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2026-07-23T18:04:22.000Z (9 days ago)
- Last Synced: 2026-07-23T18:05:07.553Z (9 days ago)
- Topics: animate-presence, animation, animation-library, drag, framer-motion, framer-motion-alternative, framer-motion-svelte, gestures, layout-animations, motion, scroll-animation, spring-animation, ssr, svelte, svelte-5, svelte-animation, svelte-motion, sveltekit, typescript, variants
- Language: TypeScript
- Homepage: https://motion.svelte.page
- Size: 7.94 MB
- Stars: 80
- Watchers: 2
- Forks: 2
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- Funding: .github/FUNDING.yml
- License: LICENSE
- Agents: AGENTS.md
Awesome Lists containing this project
README
# Svelte Motion — Framer Motion API for Svelte 5
[](https://www.npmjs.com/package/@humanspeak/svelte-motion)
[](https://tokenmaxing.app/card/humanspeak/svelte-motion)
[](https://github.com/humanspeak/svelte-motion/actions/workflows/npm-publish.yml)
[](https://coveralls.io/github/humanspeak/svelte-motion?branch=main)
[](https://github.com/humanspeak/svelte-motion/blob/main/LICENSE)
[](https://www.npmjs.com/package/@humanspeak/svelte-motion)
[](https://github.com/humanspeak/svelte-motion/actions/workflows/codeql.yml)
[](https://packagephobia.com/result?p=@humanspeak/svelte-motion)
[](https://trunk.io)
[](http://www.typescriptlang.org/)
[](https://www.npmjs.com/package/@humanspeak/svelte-motion)
[](https://github.com/humanspeak/svelte-motion/graphs/commit-activity)
Svelte Motion brings a Framer Motion-style API to Svelte 5 with `motion.` components, gestures, variants, exit animations, layout animation, and utility hooks.
For the latest documentation and examples, visit [motion.svelte.page](https://motion.svelte.page).
## Install
```bash
npm install @humanspeak/svelte-motion
```
```svelte
import { motion } from '@humanspeak/svelte-motion'
Hello motion
```
## Framer Motion API Parity
Goal: Framer Motion API parity for Svelte where common React examples can be translated with minimal changes.
| Capability | Status |
| ---------------------------------------------------------------------- | ------------------------------------------ |
| `initial` / `animate` / `transition` | Supported |
| `variants` (string keys + inheritance, function-form `custom`) | Supported |
| `whileHover` / `whileTap` / `whileFocus` / `whileDrag` / `whileInView` | Supported (inline + variant keys / arrays) |
| Drag (`drag`, constraints, momentum, controls, callbacks) | Supported |
| `AnimatePresence` (`initial`, `mode`, `onExitComplete`) | Supported |
| Layout (`layout`, `layout="position"`) | Supported (single-element FLIP) |
| Shared layout (`layoutId`, `LayoutGroup`, `layoutScroll`) | Supported |
| Reorder (`Reorder.Group`, `Reorder.Item`, edge auto-scroll) | Supported |
| View Transitions (`animateView`, shared-element morphs) | Supported |
| Vanilla values (`motionValue`, `styleEffect`, `toMotionValue` bridge) | Supported |
| Pan gesture API (`onPan*`, `onPanSessionStart`) | Supported |
| `MotionConfig` parity beyond `transition` | Partial |
| `reducedMotion`, `features`, `transformPagePoint` | Not yet supported |
## Supported elements
Motion components are generated from canonical HTML/SVG tag lists and exported from `src/lib/html/`.
- `motion.div`, `motion.button`, `motion.svg`, `motion.path`, etc.
- Most standard tags are included.
- Excluded by generation: `script`, `style`, `link`, `meta`, `title`, `head`, `html`, `body`.
## Core components
### `motion.`
Use motion components the same way you use regular elements, with animation props:
```svelte
```
### `MotionConfig`
`MotionConfig` currently supports default `transition` values for descendants.
```svelte
import { MotionConfig, motion } from '@humanspeak/svelte-motion'
```
### `AnimatePresence`
Exit animations on unmount with support for `mode="sync" | "wait" | "popLayout"` and `onExitComplete`.
```svelte
import { AnimatePresence, motion } from '@humanspeak/svelte-motion'
let show = $state(true)
console.log('done')}>
{#if show}
{/if}
(show = !show)}>Toggle
```
Notes:
- Direct children of `AnimatePresence` require `key`.
- Exit transition precedence: base `{ duration: 0.35 }` < merged `transition` < `exit.transition`.
## Interaction props
### `whileHover`
```svelte
```
- Uses true-hover gating (`(hover: hover)` and `(pointer: fine)`).
- Supports `onHoverStart` and `onHoverEnd`.
### `whileTap`
```svelte
```
- Supports `onTapStart`, `onTap`, `onTapCancel`.
- Keyboard accessible (Enter/Space).
### `whileFocus`
```svelte
```
- Supports `onFocusStart` and `onFocusEnd`.
### `whileInView`
```svelte
console.log('entered')}
onInViewEnd={() => console.log('left')}
/>
```
- Uses `IntersectionObserver`.
- Current implementation uses a fixed threshold behavior (no Framer-style `viewport` options yet).
## Drag
Supported drag props:
- `drag`: `true | 'x' | 'y'`
- `dragConstraints`: pixel object or element ref
- `dragElastic`, `dragMomentum`, `dragTransition`
- `dragDirectionLock`, `dragPropagation`, `dragSnapToOrigin`
- `dragListener`, `dragControls`
- `whileDrag`
- Callbacks: `onDragStart`, `onDrag`, `onDragEnd`, `onDirectionLock`, `onDragTransitionEnd`
```svelte
import { createDragControls, motion } from '@humanspeak/svelte-motion'
const controls = createDragControls()
controls.start(e)}>Start drag
```
## Variants
```svelte
import { motion, type Variants } from '@humanspeak/svelte-motion'
let open = $state(false)
const parent: Variants = {
open: { opacity: 1 },
closed: { opacity: 0 }
}
const child: Variants = {
open: { x: 0, opacity: 1 },
closed: { x: -16, opacity: 0 }
}
Item A
Item B
```
- String variant keys are resolved from `variants`.
- Variant state inherits through context.
- A variant entry can be a `(custom) => keyframes` factory. The `custom` prop is forwarded — useful for staggered lists where each child needs its own offset or delay. Children without `custom` inherit the nearest motion ancestor's value.
```svelte
import { motion, type Variants } from '@humanspeak/svelte-motion'
const variants: Variants = {
hidden: { opacity: 0, x: -100 },
visible: (i) => ({
opacity: 1,
x: 0,
transition: { delay: (i as number) * 0.1 }
})
}
const items = ['Alpha', 'Beta', 'Gamma', 'Delta']
{#each items as item, i}
{item}
{/each}
```
## Layout animation
Single-element FLIP layout animation:
```svelte
```
- `layout`: translate + scale.
- `layout="position"`: translate only.
- Shared layout (`layoutId`) is not implemented yet.
## Utilities
- `useAnimationFrame`
- `useMotionTemplate`
- `useSpring`
- `useTime`
- `useTransform`
- `useVelocity`
- `styleString`
- `stringifyStyleObject` (deprecated)
- `createDragControls`
The package also re-exports core helpers from `motion` (for example `animate`, `stagger`, `transform`, easings, and utility functions).
## SSR behavior
- Initial visual state is rendered server-side from `initial` (or first `animate` keyframe when `initial` is empty).
- `initial={false}` skips initial enter animation.
- Hydration path is designed to avoid flicker.
## Verification snapshot
Validated against current source and test suite (local run):
- Unit/component tests: `676 passed`
- E2E tests: `290 passed`, `2 skipped`
## Known gaps vs Framer Motion
- `whileInView` does not yet expose Framer-style viewport options.
- `MotionConfig` currently only provides `transition` defaults.
- `reducedMotion`, `features`, and `transformPagePoint` are not implemented as `MotionConfig` props.
## External dependencies
- `motion`
- `motion-dom`
## Svelte 5 ecosystem
Part of the [Humanspeak](https://humanspeak.com) family of runes-native Svelte 5 packages:
| Package | Description |
| --- | --- |
| [@humanspeak/svelte-markdown](https://markdown.svelte.page) | Runtime markdown renderer for Svelte |
| [@humanspeak/svelte-virtual-list](https://virtuallist.svelte.page) | Virtual scrolling for Svelte |
| **[@humanspeak/svelte-motion](https://motion.svelte.page)** — _this package_ | Framer Motion for Svelte 5 |
| [@humanspeak/svelte-headless-table](https://table.svelte.page) | Headless data tables for Svelte |
| [@humanspeak/svelte-diff](https://diff.svelte.page) | Diff comparison for Svelte |
| [@humanspeak/svelte-purify](https://purify.svelte.page) | HTML sanitisation for Svelte |
| [@humanspeak/svelte-virtual-chat](https://virtualchat.svelte.page) | Virtual chat viewport for Svelte 5 |
| [@humanspeak/memory-cache](https://memory.svelte.page) | In-memory cache for TypeScript |
| [@humanspeak/svelte-json-view-lite](https://jsonview.svelte.page) | JSON tree viewer for Svelte 5 |
| [@humanspeak/svelte-scoped-props](https://scoped.svelte.page) | Scoped class props for Svelte |
## License
MIT © [Humanspeak, Inc.](LICENSE)
## Credits
Made with ❤️ by [Humanspeak](https://humanspeak.com)