React
The sprungdesign/react adapter is a single hook, useSpring. It wraps the
core controller and re-renders your component with the live value each frame.
npm install sprungdesignReact is an optional peer dependency (17+); installing sprungdesign doesn’t pull in React.
useSpring(target, config?)
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)` }} />;
}- It returns a
numberyou render directly. - The value starts at
targeton mount — there’s no entrance animation. If you want one, mount with one target and change it (e.g. in an effect). - When
targetchanges, it retargets velocity-continuously — interrupt an in-flight animation and it never jumps.
Config is read once
config is read a single time, when the underlying controller is created.
Changing it across renders is a no-op. Pass a stable feel:
// ✅ stiffness/damping fixed for the life of the component
const x = useSpring(target, { stiffness: 320, damping: 14 });
// ❌ this won't switch feel — the second config is ignored
const x = useSpring(target, fast ? presetA : presetB);If you genuinely need to swap physics at runtime, remount the component with a
key, or drop down to the core spring()
controller and recreate the handle yourself.
Reduced motion
useSpring honors prefers-reduced-motion: when the user has it enabled, the
value snaps to the target instead of animating. The preference is evaluated
at each retarget, not tracked live — so a user who toggles it mid-animation sees
the new behavior on the next target change.
Server rendering & StrictMode
- SSR-safe — returns
targeton the server and the first client render, so hydration matches. Nothing touches the DOM at import. - StrictMode / concurrent-safe — the double-invocation and effect remounting that StrictMode does won’t desync the animation.
Animating multiple values
useSpring animates one number. Call it once per dimension:
function Card({ active }: { active: boolean }) {
const scale = useSpring(active ? 1.05 : 1, { stiffness: 260, damping: 18 });
const lift = useSpring(active ? -8 : 0, { stiffness: 260, damping: 18 });
return (
<div style={{ transform: `translateY(${lift}px) scale(${scale})` }} />
);
}Next steps
- See every option in the API Reference.
- Choose the right
stiffness/damping/bouncein the Configuration guide.