Skip to Content
DocsIntroduction

Introduction

sprungdesign models motion as a real spring — mass, stiffness, damping — and solves it analytically. Because the solution is closed-form, it’s frame-rate independent and exact at any timestep. Retarget mid-flight and the velocity carries over with no jump — the thing that makes spring UIs feel alive.

Think in physics (stiffness / damping / mass) or in feel (duration / bounce). Use it in React with a hook, or in any framework with a plain controller.

The library is named sprung, but it’s published on npm as sprungdesign — that’s the name you install and import.

Why sprungdesign?

  • Real physics, solved exactly — a damped harmonic oscillator with three proper damping regimes, not a per-frame approximation.
  • Velocity-continuous interruptionset() a new target mid-flight and the current velocity is preserved. No snapping.
  • ~1 kB min+gzip for the core, zero dependencies, tree-shakeable.
  • SSR-safe — nothing touches the DOM at import; the React hook returns the target on the server.
  • Dual ESM + CJS with complete TypeScript types in the box.

Install

npm install sprungdesign

Quick example

React

import { useSpring } from "sprungdesign/react"; function Box({ open }: { open: boolean }) { const x = useSpring(open ? 200 : 0, { stiffness: 320, damping: 14 }); return <div style={{ transform: `translateX(${x}px)` }} />; }

Anything else

import { spring } from "sprungdesign"; const handle = spring({ stiffness: 180, damping: 12, onUpdate: (value) => { el.style.transform = `translateX(${value}px)`; }, }); el.addEventListener("click", () => handle.set(300)); // Call set() again mid-flight — the current velocity is preserved, no jump.

Think in feel, not physics

import { fromFeel, spring } from "sprungdesign"; // bounce ∈ [-1, 1]: >0 bouncy · 0 critical (no overshoot) · <0 sluggish const handle = spring({ ...fromFeel({ duration: 0.5, bounce: 0.3 }), onUpdate });

Ready to go deeper? Head to Getting Started.

Last updated on