The spring function animates transforms using real spring physics. This produces more natural-feeling animations.

import { animate, spring } from "motion"
import { animate, spring } from "motion"

  { rotate: 90 },
  { easing: spring() }

spring accepts options to customise your spring. Copy/paste { stiffness: 300, damping: 10 } into the spring function in the above example to see how it changes the animation.

Note: Because spring is a simulation, any provided duration will be overridden.

spring will use real springs to animate independent transforms like x, scale and rotate. All other values will use the defined spring to figure out how long it takes to reach its overshoot point (the bouncy bit) and will automatically create an animation to match.

import { animate, spring } from "motion"

  { scale: 2, opacity: 1 },
  { easing: spring() }

This means that animating values like opacity with a bouncy spring won't create odd flashing effects.


spring will automatically pass velocity from any running animations into the next one, so interrupting an animation will feel natural.

This can be overridden by manually passing velocity to spring. velocity is measured as units per second.

  { x: 100 },
  { easing: spring({ velocity: 1000 }) }

If you want to pass a different velocity per value (for instance for animating at the end of a pointer gesture) you can create value-specific options:

  { x: 0, y: 0 },
    x: { easing: spring({ velocity: 200 }) },
    y: { easing: spring({ velocity: 500 }) }



Default: 100

The attraction force of a spring. Higher values create faster, sharper movement.

spring({ stiffness: 500 })


Default: 10

The opposing force of a spring. Higher values reduce the bounciness of the spring.

spring({ damping: 100 })


mass affects the inertia of a value. Higher values will be slower to start moving and slower to stop.

Default: 1

spring({ mass: 2 })


Default: 2, or 0.05 for scale

A speed (in absolute units per second) below which the spring animation is considered finished.

spring({ restSpeed: 1 })


Default: 0.5, or 0.01 for scale

A distance from the animation target, below which the spring animation is considered finished.

spring({ restDistance: 0.1 })


Default: 0, or the value's current velocity

The velocity (in units per second) at which to start the spring animation.

spring({ velocity: 1000 })


There are currently some limitations with the glide easing.

Limited duration

Springs with 0 damping can last an infinite amount of time, but the Web Animations API needs a finite duration. So springs currently max out at 10 seconds (which is more than long enough for the vast majority of UI animations).

Increase damping relative to stiffness to decrease the duration of your animation.

Timeline keyframes

spring is supported in timeline but independent transforms must be defined with start and end keyframes: { x: [0, 100] }.

No hardware acceleration

spring only works with independent transforms, which are not yet hardware accelerated in browsers.

Did you know?

There's an incredible new set of developer tools for Chrome that let you inspect, edit and export Motion One and CSS animations.