Motion (formerly Framer Motion) for Svelte 5: animations, gestures, layout and exit animations, scroll and motion values, built on the same engine as Motion for React and Vue.
Read the docs at motion.hyprsonic.dev. The site's in docs/; run it locally with bun install and bun run docs.
npm install motion-svThen import the motion component:
<script lang="ts">
import { motion } from "motion-sv";
</script>
<motion.div animate={{ x: 100 }}>Hello</motion.div>- Svelte Animations: 90+ free, open-source animated components and effects.
Most of the API is identical. The main differences:
-
Layout animations need to know which state the layout depends on, because Svelte has no hook that runs before the DOM updates. Render the elements through a namespace from
createLayoutMotion(), with a getter for that state, or call itsupdate()with the state change. Shared layout animations withlayoutId, exits inAnimatePresenceandReorderlists work without it.<script lang="ts"> import { createLayoutMotion } from "motion-sv"; let isOn = $state(false); const layout = createLayoutMotion(() => isOn); </script> <button class={{ on: isOn }} onclick={() => (isOn = !isOn)}> <layout.div class="handle" /> </button>
-
AnimatePresenceworks with Svelte's{#if},{#each}and{#key}blocks. -
Props:
whilePressinstead ofwhileTap,inViewOptionsinstead ofviewport, andbind:reffor the element. -
Hooks take getters for inputs that change, like elements bound after setup:
useScroll(() => ({ target: el })).
The documentation covers all of these in detail.