Getting started
damped is a family of three packages that share one spring. This page gets you from an empty project to an element that you can interrupt mid-flight.
Pick a package
Section titled “Pick a package”| You build with | Install | What you get |
|---|---|---|
| The DOM, with or without a framework | @damped/core |
animate, layout, morph, enter and exit, createSpringValue and the spring itself. |
| React 19 | @damped/react and @damped/core |
useSpring, useSpringValue, useLayout, useMorph and <Presence>. Values reach the DOM without re-rendering on every frame. |
| React Native with Reanimated 4 (Expo SDK 57) | @damped/native |
withDamped and toReanimated, which keep velocity on reversal. See React Native. |
@damped/react builds on @damped/core, so the two are installed together.
Install
Section titled “Install”bun add @damped/corenpm install @damped/corepnpm add @damped/coreFor React, install the React package next to the core:
bun add @damped/react @damped/corenpm install @damped/react @damped/corepnpm add @damped/react @damped/coreThe packages are ES modules with no runtime dependencies. They are tested in Chromium; @damped/react needs React 19.
Your first spring on the web
Section titled “Your first spring on the web”animate(element, values, options) moves an element to the values you give it. x and y are pixels, scale is a ratio, opacity runs from 0 to 1.
import { animate } from "@damped/core";
const card = document.querySelector<HTMLElement>("#card");
if (card) { let open = false;
card.addEventListener("click", () => { open = !open; animate( card, { x: open ? 240 : 0, opacity: open ? 0.6 : 1 }, { duration: 0.5, bounce: 0.2 }, ); });}Click the card twice quickly. The second call does not wait for the first one and does not restart from rest: it starts from the position and the velocity the card has at that moment, so the card turns around smoothly. That is the property the whole library is built around, and the interruption guide explains it.
Your first spring in React
Section titled “Your first spring in React”useSpring returns a ref. Attach it to an element and give the hook the styles the element should spring to.
import { useState } from "react";import { useSpring } from "@damped/react";
export function Card() { const [open, setOpen] = useState(false); const ref = useSpring<HTMLButtonElement>( { x: open ? 240 : 0, opacity: open ? 0.6 : 1 }, { duration: 0.5, bounce: 0.2 }, );
return ( <button ref={ref} type="button" onClick={() => setOpen((value) => !value)}> Corner Grocery </button> );}The component renders when open changes and not once per animation frame: every frame is written to the DOM through the ref. Changing open again mid-flight retargets the running spring and keeps its velocity.
See the numbers
Section titled “See the numbers”A spring is a pure function of time, so you can sample it without animating anything. This is handy for understanding what your duration and bounce do.
import { createSpring } from "@damped/core";
// Move from 0 to 100, starting at rest.const spring = createSpring(0, 100, 0, { duration: 0.5, bounce: 0.15 });
const { position, velocity } = spring.at(0.25);console.log(position.toFixed(1), velocity.toFixed(1), spring.settleTime().toFixed(2));// 89.5 164.6 1.16After a quarter of a second the value is at 89.5 and still moving at 164.6 units per second. It comes to rest after 1.16 s. Note that duration is not the time to rest; Springs explained covers what it is.