Thanks for helping out! This guide covers everything you need to get a local checkout running, send a PR, and (if you have publish access) cut a release.
- Node: see
.nvmrc(nvm useorfnm usepicks it up).engines.nodeis the same version. - pnpm: pinned via
packageManagerin the rootpackage.json. Enable Corepack so the correct version activates automatically:corepack enable
git clone https://github.com/pmndrs/react-spring
cd react-spring
pnpm install
pnpm exec playwright install chromium # one-off, needed for browser-mode VitestNow you're cooking. 👨🏻🍳🥓
| Task | Command |
|---|---|
| Watch-build all packages | pnpm dev |
| Run the docs site | pnpm docs:dev |
| Run the demo hub | pnpm demo:dev |
| Full test suite | pnpm test (types + unit + e2e) |
| Unit tests (watch) | pnpm vitest --project unit |
| Single test file | pnpm vitest run packages/core/src/SpringValue.test.ts |
| Type-check | pnpm test:ts |
| Lint | pnpm lint |
| Format | pnpm format |
Vitest aliases @react-spring/* to the package source, so unit tests don't need a prior build. Anything outside Vitest (docs, publishing) does — run pnpm build first.
pnpm isolation gotcha:
node_modulesis non-hoisted. If you hitCannot find module 'foo'after adding an import, addfooto the workspace'spackage.json— don't add a hoist rule.
- Target branch:
next(the active line).mainmay exist but isn't the merge base. - Commits: follow Conventional Commits (
feat:,fix:,chore:, …). commitlint enforces this on thecommit-msghook. - Changeset: if your change affects published behaviour, run
pnpm changesetand flag only the package(s) you changed (usually one). All@react-spring/*packages are version-locked (afixedgroup in.changeset/config.json), so changesets bumps the rest to the same version automatically — you don't flag them yourself. Docs-only or internal-tooling changes don't need one. - Pre-commit:
oxfmt --checkruns via husky. If it fails, runpnpm formatand re-commit. - Keep PRs small and focused — easier to review, easier to land.
(Maintainers only — needs npm publish access.) We use changesets. All packages are version-locked.
Changesets are added per PR (see Sending a PR) and accumulate on next, so a release just bumps and publishes them:
- Apply the bump (updates package versions and internal deps):
pnpm vers
- Publish. This cleans, installs, builds, type-checks, runs unit tests, and publishes via changesets:
Tags are not pushed automatically (
pnpm release
pnpm releaserunschangeset publish --no-git-tag). After publishing, draft the GitHub release notes manually and update the changelog onreact-spring.dev.
Enter pre-mode first, then follow the simple release flow:
pnpm changeset pre enter beta # or alpha, nextIf you're stuck in pre-mode and need a normal release:
pnpm changeset pre exit