Svelte Motion (@humanspeak/svelte-motion) is an animation library for Svelte 5 that provides declarative and imperative animation APIs, gesture handling, layout animations, and more. It follows Svelte 5 conventions with rune-based hooks and attachment-based scoping.

Motion Component

The <Motion> component provides declarative animations with variants, transitions, gesture callbacks, and layout animation support:

<Motion
  initial={{ opacity: 0, scale: 0.5 }}
  animate={{ opacity: 1, scale: 1 }}
  transition={{ duration: 0.5 }}
>
  <div>Animated</div>
</Motion>

Hooks

HookPurpose
useAnimateImperative animation with scoped CSS selector API
useAnimationControlsProgrammatic control over <Motion> animations
useAnimationFrameRun code on every animation frame
useScrollTrack scroll position and progress
useSpringPhysics-based spring animations
useTimeReactive time value
useTransformMap one range of values to another
useVelocityTrack velocity of motion values
useInViewDetect when elements enter the viewport
useCycleCycle through a set of values
useMotionValueCreate and manage motion values
useMotionTemplateCombine motion values into CSS strings
useMotionValueEventListen to motion value changes
useFollowValueFollow another motion value with spring physics
usePresence / usePresenceDataAnimate elements entering/leaving
useReducedMotion / useReducedMotionConfigRespect user motion preferences

AnimatePresence

Animate elements as they mount and unmount from the component tree:

<AnimatePresence>
  {#if visible}
    <Motion initial={{ opacity: 0 }} animate={{ opacity: 1 }} exit={{ opacity: 0 }}>
      <div>Hello</div>
    </Motion>
  {/if}
</AnimatePresence>

Variants

Define named animation states that can be referenced by multiple elements:

<script>
  const variants = {
    hidden: { opacity: 0, y: 20 },
    visible: { opacity: 1, y: 0 }
  }
</script>

<Motion variants={variants} initial="hidden" animate="visible">
  <div>Content</div>
</Motion>

Variants support propagation to child motion elements and orchestration with delayChildren and staggerChildren.

Layout Animations

  • layout prop: Animate a single element when its size/position changes (FLIP)
  • layoutId prop: Animate between different elements sharing the same ID

Gestures

Built-in gesture support:

  • Hover and tap: whileHover, whileTap props with visual feedback
  • While focus: whileFocus for accessibility-friendly focus animations
  • While in view: whileInView for scroll-triggered animations
  • Drag: drag prop with drag constraints, elastic bounds, and direction locking
  • Pan: onPan callbacks for custom pan gesture handling

Motion Values

Motion values track numerical or color values over time and can be:

  • Spring-based: Physics-driven with configurable stiffness, damping, and mass
  • Tweened: Timing-based with easing functions
  • Transformed: Mapped through input/output ranges with useTransform
  • Templated: Combined into CSS strings with useMotionTemplate
  • Followed: Spring-animated followers with useFollowValue

Optimized Appear

optimizedAppear enables the motion component to animate from its server-rendered state to the client state without layout shift.

Style String & Transform Template

  • Style string: Pass animation values as a CSS string
  • Transform template: Define transform properties (translate, scale, rotate) as template strings

Performance & Tree Shaking

Svelte Motion is tree-shakable — unused hooks and components are removed from the production bundle. The motion package re-exports animation primitives (animate, easing, spring) for standalone use.

Examples

The library includes extensive examples covering: animated buttons, tabs, toggle switches, notifications stacks, path morphing, color interpolation, conic gradients, fancy like buttons, scroll progress indicators, character counters, layout groups, reordering, motion paths, shared layout animations, and more.

See Also