An open API service indexing awesome lists of open source software.

https://github.com/humanspeak/svelte-motion

An API-compatible Svelte wrapper for Framer Motion’s React API — bring Motion components, variants, transitions, gestures, and layout animations to Svelte via a thin compatibility layer.
https://github.com/humanspeak/svelte-motion

animation api-wrapper framer-motion gestures layout-animations motion svelte sveltekit transitions

Last synced: about 1 month ago
JSON representation

An API-compatible Svelte wrapper for Framer Motion’s React API — bring Motion components, variants, transitions, gestures, and layout animations to Svelte via a thin compatibility layer.

Awesome Lists containing this project

README

          

# Svelte Motion — Framer Motion API for Svelte 5

[![NPM version](https://img.shields.io/npm/v/@humanspeak/svelte-motion.svg)](https://www.npmjs.com/package/@humanspeak/svelte-motion)
[![Build Status](https://github.com/humanspeak/svelte-motion/actions/workflows/npm-publish.yml/badge.svg)](https://github.com/humanspeak/svelte-motion/actions/workflows/npm-publish.yml)
[![Coverage Status](https://coveralls.io/repos/github/humanspeak/svelte-motion/badge.svg?branch=main)](https://coveralls.io/github/humanspeak/svelte-motion?branch=main)
[![License](https://img.shields.io/npm/l/@humanspeak/svelte-motion.svg)](https://github.com/humanspeak/svelte-motion/blob/main/LICENSE)
[![Downloads](https://img.shields.io/npm/dm/@humanspeak/svelte-motion.svg)](https://www.npmjs.com/package/@humanspeak/svelte-motion)
[![CodeQL](https://github.com/humanspeak/svelte-motion/actions/workflows/codeql.yml/badge.svg)](https://github.com/humanspeak/svelte-motion/actions/workflows/codeql.yml)
[![Install size](https://packagephobia.com/badge?p=@humanspeak/svelte-motion)](https://packagephobia.com/result?p=@humanspeak/svelte-motion)
[![Code Style: Trunk](https://img.shields.io/badge/code%20style-trunk-blue.svg)](https://trunk.io)
[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)
[![Types](https://img.shields.io/npm/types/@humanspeak/svelte-motion.svg)](https://www.npmjs.com/package/@humanspeak/svelte-motion)
[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](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) | Supported |
| `whileHover` / `whileTap` / `whileFocus` / `whileInView` | Supported |
| Drag (`drag`, constraints, momentum, controls, callbacks) | Supported |
| `AnimatePresence` (`initial`, `mode`, `onExitComplete`) | Supported |
| Layout (`layout`, `layout="position"`) | Supported (single-element FLIP) |
| Shared layout (`layoutId`) | Supported |
| Pan gesture API (`whilePan`, `onPan*`) | Not yet 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.

## 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: `259 passed`
- E2E tests: `78 passed`, `1 skipped`

## Known gaps vs Framer Motion

- No shared layout API (`layoutId`, `LayoutGroup`).
- No pan gesture API (`whilePan`, `onPan*`).
- `whileInView` does not yet expose Framer-style viewport options.
- `MotionConfig` currently only provides `transition` defaults.
- `reducedMotion`, `features`, and `transformPagePoint` are not implemented.

## External dependencies

- `motion`
- `motion-dom`

## License

MIT © [Humanspeak, Inc.](LICENSE)

## Credits

Made with ❤️ by [Humanspeak](https://humanspeak.com)