Composable, physics-accurate springs for Svelte 5 runes applications. This package provides a drop-in Spring class built on Svelte's internal runes primitives so you can simulate real-world motion for numbers, arrays, objects, and dates with precise control.
svelte, spring, motion, animation, physics, runesDate instances.set() calls only after the spring settles, enabling async flows.spring API from svelte/motion with added hooks for velocity control.Spring.of helper to couple the spring to any reactive source inside a rune.npm install svelte-physics-spring
# or
pnpm add svelte-physics-spring
Peer dependency: svelte@^5.0.0. This library relies on runes internals and is not meant for Svelte 3/4.
<script>
import { Spring } from "svelte-physics-spring";
let target = $state({ x: 0, y: 0 });
const pointer = Spring.of(() => target, {
stiffness: 220,
damping: 28,
});
function handlePointerMove(event) {
target = { x: event.clientX, y: event.clientY };
}
</script>
<div
class="cursor"
on:pointermove={handlePointerMove}
style={`transform: translate(${pointer.current.x}px, ${pointer.current.y}px);`}
/>
If you prefer to manage the lifecycle yourself:
import { Spring } from "svelte-physics-spring";
const opacity = new Spring(0, { damping: 18 });
await opacity.set(1); // resolves when settled
await opacity.set(0.3, { velocity: -0.2 });
Spring.ofSpring.of(() => source, options) evaluates source within a render_effect. Whenever source changes, the spring receives the new value automatically. Use this when pairing springs with $state or $derived signals.
new Spring(value, options?)Creates a spring anchored to the provided value.
| Option | Default | Description |
|---|---|---|
stiffness |
170 |
Spring stiffness (higher = snappier). |
damping |
26 |
Damping factor (higher = less overshoot). |
mass |
1 |
Effective mass of the body. |
precision |
0.01 |
Threshold for considering the spring settled. |
velocity |
0 |
Initial velocity. Mirrors the value shape. |
spring.set(value, options?)Returns a promise that resolves when the spring settles. Options:
instant: skip animation and jump to value immediately.velocity: override the initial velocity for this transition.spring.currentGetter returning the animated value. Access within reactive contexts to track updates.
spring.targetGetter/setter for the target value. Writing to target is equivalent to calling set.
Each spring exposes accessors for mass, stiffness, damping, and precision. Updating them mid-flight influences the ongoing simulation.
Spring.of(fn, options?)Creates a spring bound to the result of fn. The return value is the Spring instance. The optional velocity is used whenever fn recomputes, while other options match the constructor.
# Run the playground app
npm run dev
# Type-check and lint
npm run check
npm run lint
# Package for npm
npm run build # runs vite build + svelte-package + publint
npm pack # inspect the tarball before publishing
npm publish
The published package exposes dist/index.js and dist/index.d.ts. Any example pages inside src/routes act as documentation and will not be shipped.
MIT © lixiaolin94