mrkeyoor.com_
Thu 24 Sept 09:33 UTC
Webevaluationupdated 24 Sept 2026

react-spring review

react-spring is a TypeScript animation library for React that moves values with spring physics or timed easing. Its hooks connect component state to motion on the web and in React Three Fiber, so developers can build interactive movement without writing each frame by hand.

Verdict

Our react-spring run installed 1,035 packages and used 931 MB, then passed its 32-second build but failed the test command with 1 error before Vitest reported any tests. That result makes the repository a cautious choice for contributors, even though the published library remains a strong fit for React teams that want state-driven spring motion across the DOM and Three. Adopt it for the physics model and direct spring control, but prototype useTransition, reduced motion, and mixed targets against your exact app before committing.

We ran it

Lab card: what happened when we ran react-springScreenshot of react-spring (www.react-spring.dev)
Install✓ · 20s1035 packages · 931 MB
Build✓ · 32s
Tests✗ · 10sran, no count parsed
Repo854 files~34,632 lines of source · 35.1 MB · 7 CI workflows · Dockerfile · tests dir

Answers from our run

Does react-spring build from source?

Dependencies installed in 20 seconds (1035 packages), and the build succeeded in 32 seconds. We cloned commit f6262d1 into a clean Debian container with 3 CPUs and no project-specific setup.

Do react-spring's tests pass?

The test command failed in our container, and its output did not report a pass or fail count.

Who should not use react-spring?

Contributors who need a small checkout and a green test command immediately: our install added 1,035 packages and used 931 MB, then the test run ended with 1 error and no tests executed.

What are the alternatives to react-spring?

Motion, React Transition Group, GSAP. Our react-spring run installed 1,035 packages and used 931 MB, then passed its 32-second build but failed the test command with 1 error before Vitest reported any tests.

Setup3/5Simple app package; repo install is 931 MB and tests failed
Docs4/5Hook examples are clear, while useTransition remains confusing
Community5/529,160 stars with code and issue activity in September 2026
Maturity4/5Stable v10 release and active v11 work, with old bugs still open

Who it’s for

React developers who want motion to respond to changing state with physical spring behavior.
Teams animating DOM, SVG, or React Three Fiber scenes through one family of hooks.
Interface builders who need direct control through both declarative props and imperative spring APIs.
Products prepared to wire the documented reduced-motion hook into the application root.

Who it’s NOT for

Contributors who need a small checkout and a green test command immediately: our install added 1,035 packages and used 931 MB, then the test run ended with 1 error and no tests executed.
Teams wanting a simple presence component for enter and exit animation: open issue #2540 calls useTransition the library's most reported source of confusion and proposes a rewrite.
Projects that require per-property spring settings inside useTransition: open issue #2136 reports that its config callback receives an item rather than the animated property.
Apps combining global skipAnimation with looping springs without a regression test: open issue #2409 reports a main-thread lock in version 10.0.3.
Teams mixing the web and Three targets without testing their import order: open issue #1586 documents an incompatibility on version 9.2.3 and remains open.

Setup reality

Our commit f6262d1 checkout installed 1,035 pnpm packages in 20 seconds and occupied 931 MB. The build passed in 32 seconds. Tests failed with exit code 1 after 10 seconds: Vitest listed 30 test files, no tests, and 1 error, but the supplied log tail did not identify the cause.

Application use starts with a target package such as @react-spring/web or @react-spring/three. Repository work is a different commitment: this is an 854-file monorepo with about 34,632 source lines, 7 CI workflows, workspaces, a Dockerfile, and a tests directory.

The current next branch declares Node 24.21.0 or newer and pnpm 12.5.1. That requirement landed after our measured Node 22 commit, so a new contributor should follow the current package file rather than treating our successful install as proof that Node 22 remains supported.

State changes become spring motion instead of hand-written frames

react-spring starts with a useful idea: describe where a value should go, then let a spring calculate the movement. useSpring can turn a visibility flag into changing opacity and position values, and animated.div applies them without rerendering every frame through ordinary React state.

A config object gives you declarative motion, while the function form returns an imperative controller for changing a spring later. The library asks you to learn its controllers, spring values, lifecycle callbacks, and configuration rules rather than treating animation as a CSS class toggle.

Web and Three share an engine, but target boundaries still matter

The README points browser users to @react-spring/web and React Three Fiber users to @react-spring/three. Both sit on the same core packages, with a separate parallax package in the monorepo. Peer ranges cover React 16.8 through 19, while the Three package accepts React Three Fiber 6 or newer and Three 0.126 or newer.

Shared primitives are useful when one product has interface motion and a 3D scene. Open issue #1586 shows a version 9.2.3 reproduction where importing the Three target before a web animation in another file stops the web spring. The report does not establish a current version 10 defect, but its open state is enough reason to keep a mixed-target regression in your app.

What happened when we ran it

Our sandbox installed commit f6262d1 in 20 seconds, pulling 1,035 pnpm packages and consuming 931 MB on disk. The build completed successfully in 32 seconds. The checkout contained 854 files, about 34,632 lines of source, and 35.1 MB before installation, so the contributor environment is much larger than the single package an application adds.

The test command failed with exit code 1 after 10 seconds. Its Vitest summary listed 30 test files, no tests, and 1 error. The supplied tail includes a location at line 1053, column 55, followed by pnpm lifecycle failures, but it does not include the error message that would support a diagnosis. The full command did not reach a passing result in our Node 22 container.

This monorepo has 7 CI workflow files, a Dockerfile, a tests directory, and workspace configuration. Those signals do not turn our failed run green. The current next branch now requires Node 24.21.0 or newer with pnpm 12.5.1. That engine update landed after our measured commit, so the lab's Node 22 install is evidence for f6262d1 only.

useTransition is the part most likely to slow a team down

useTransition handles items entering and leaving the tree, including dialogs and changing lists. Its config differs from useSpring, and rendering uses a function that receives the calculated style and item. Open issue #2540 says developers repeatedly struggle to see where the item comes from and how exit timing works. The proposed answer is an API rewrite, not a documented release plan.

Open issue #2136 concerns different spring settings per animated property inside useTransition. In its version 9.6.0 example, the config callback receives the transitioned item where the developer expects the property name. An app that mixes a duration for opacity with a spring for movement should reproduce that pattern. A basic fade does not expose this part of the API.

Reduced motion is built in, with one loop warning

The documented useReducedMotion hook reads the operating-system preference and sets the global skipAnimation value. Springs then jump to their destination, much like the immediate option. Calling the hook at the application root gives every spring the same preference.

Open issue #2409 reports a sharp edge in version 10.0.3: combining Globals.assign({ skipAnimation: true }) with a looping SpringValue can lock the main thread. The report includes a small reproduction and remains open. It does not say every reduced-motion use crashes. Looping decorations still deserve a test with reduced motion enabled.

Version 10 is stable while the next branch carries version 11 beta

GitHub's latest release is v10.1.2, published June 24, 2026. It fixed partial from type inference, an onChange result mismatch, and a React Native Hermes crash. The repository was pushed again on September 23. Current package files identify the next line as 11.0.0-beta.0, so buyers should distinguish stable npm documentation from unreleased branch work.

GitHub recorded 29,160 stars and 69 open issues and pull requests when fetched. The combined count is not a bug total. Recent commits and a June release show active maintenance, while older open reports show that some awkward behavior has lasted across major versions. The broad surface rewards a small app-specific motion test before a design system adopts it.

Choose react-spring when the physics model earns its API cost

react-spring is strongest when motion responds continuously to state, input, or another animated value. It reaches both DOM and Three scenes. For simple fades, React Transition Group plus CSS asks less of the team. For layout and presence work, Motion offers a higher-level model.

Our failed test command keeps this from being an easy contributor recommendation. For application use, start with one target package, wire reduced motion on day one, and prototype the hardest transition rather than the landing-page fade. If that transition behaves under interruption, react-spring's spring model has earned the extra concepts.

Alternatives

ProjectWhat it isPick it when
Motion gh↗A React and JavaScript animation library with higher-level layout and presence APIs.pick this instead when layout animation, gestures, and a direct presence component matter more than spring-level control.
React Transition GroupA small set of React components for managing enter and exit states.pick this instead when you only need component lifecycle states and will supply the CSS animation yourself.
GSAPAn imperative JavaScript animation engine built around timelines and direct sequencing.pick this instead when complex timelines span DOM, SVG, and non-React code and React hooks are not the center of the design.

What people are saying

  1. [velocity-scout] pmndrs/react-spring

Sources

  1. react-spring README
  2. react-spring v10.1.2 release
  3. useTransition documentation
  4. useReducedMotion documentation
  5. useTransition rewrite proposal
  6. skipAnimation loop crash report

More web reviews

cloudflare-turnstile-examples · You-Dont-Need-jQuery · mimik · vapor · univer · MovieBox-Tui · the whole board →