Last updated: May 22, 2026
On React Native, Reanimated has already won the animation contest, and the reason is structural rather than ergonomic: its worklet runtime executes on the UI thread, higher-level RN animation libraries increasingly sit on top of it, and Expo documents it as a supported SDK library. React Spring is far from dead — it remains a credible web choice — but on React Native its real opponent has lost shelf space. The matchup that still matters is React Spring against Framer Motion on the web.
More on React Spring Reanimated.
- Modern Reanimated’s
withSpringexposes both stiffness/damping and duration/dampingRatio configs, closing React Spring’s old ergonomic edge. - Expo documents
react-native-reanimatedas a supported SDK library configured via a Babel plugin;@react-spring/nativeis rarely a first-class dependency in current RN apps. - Moti, react-native-skia, Tamagui, and react-native-redash all use Reanimated as part of their animation story.
- On the web, Reanimated has no production story — React Spring’s live competitor there is Framer Motion, not Reanimated.
The opening visual mirrors the article’s argument: one board has a fallen king while a second board behind it is still set up. That second board is the React Spring vs Framer Motion contest on the web, where neither side has conceded and the decision still rewards a closer look.
The verdict: on React Native, Reanimated already won
The polite framing is the problem with the existing roundup-style coverage of react spring vs reanimated. The major RN animation libraries that ship fresh code today tend to build on Reanimated as their primitive. @react-spring/native exists, but it does not appear in the dependency graph of the libraries that anchor the modern RN UI stack. That is not a popularity claim — it is an architectural one. When a primitive becomes the runtime that other libraries import, the contest at that primitive layer is over.
This is the part the existing comparisons miss. They rank libraries by GitHub stars, which conflates the web React Spring with its native counterpart. The star count for the pmndrs/react-spring repository reflects years of web adoption by Three.js and 3D scenes, not React Native deployment. Treat the two targets as separate products and the answer flips.
Why this was settled at the runtime layer, not the API
Reanimated’s value is its worklet model: a JavaScript function annotated 'worklet' that is serialized and executed on the UI thread through a separate JS runtime, mutating shared values without crossing the React Native bridge. The Reanimated glossary describes worklets as small pieces of JavaScript run synchronously on the UI thread — that synchronicity is the whole game. Animation libraries that lack an equivalent UI-thread runtime — which, in the case of @react-spring/native, appears to mean updates flow through React’s render cycle on the JS thread rather than a documented separate UI-thread runtime — can be starved by re-renders, scroll handlers, or anything else competing for the bridge.
For animations tied to gestures, scrolls, or high-refresh-rate scroll-linked work, that thread choice is not a tunable — it is the architecture. No amount of API polish closes a gap that lives below the API.
Background on this in Reanimated’s 60 FPS guarantees.

The diagram shows the same animation expressed twice: once as a Reanimated worklet that mutates a shared value on the UI thread, and once as a typical hook-based animation — the pattern most React Spring usage falls into — that drives updates through React’s render cycle on the JS thread. The shape of the two pipelines explains why a UI-thread-driven animation tends to hold frames under load where a JS-thread-driven one tends to drop them.
The ergonomics excuse died with duration-based springs
The strongest argument for React Spring on RN used to be authoring ergonomics. Designers reason in “800 ms with a little bounce”, not in “stiffness 180, damping 12, mass 1”. Reanimated closed that gap. The withSpring reference exposes two interchangeable configuration shapes:
// Physics-based config
withSpring(targetValue, {
mass: 1,
damping: 10,
stiffness: 100,
});
// Duration-based config
withSpring(targetValue, {
duration: 600,
dampingRatio: 0.8,
});
The duration/dampingRatio mode is the same mental model React Spring exposes through its config presets such as config.gentle and the duration field on tween animations. Reanimated did not replace its physics engine; it added a second authoring surface so that designers and engineers who think in time and bounce never have to compute stiffness. The ergonomic case for choosing React Spring on RN got materially weaker the day that landed.
Related: declarative layout animations.
Expo’s documented SDK path made Reanimated the easy install
Distribution shapes adoption. The Expo SDK reanimated page documents Reanimated as a supported SDK library, with the required Babel plugin wired through Expo’s documented setup. A developer running npx create-expo-app and reaching for an animation library has a well-trodden Reanimated path — the Babel plugin and Metro configuration are spelled out in the SDK docs rather than something a new learner has to assemble from a native-install rabbit hole. @react-spring/native is not in that path. It is an opt-in dependency in a world where Expo is the path many new React Native projects take.
Documented defaults compound. Tutorials written against a current Expo template implicitly recommend Reanimated. Component libraries that target Expo apps inherit the assumption that Reanimated is installed. Once the supported SDK path crystallizes around one animation library, the contest at the runtime layer is no longer easily winnable by the alternative.
If you need more context, shared element transitions in v3 covers the same ground.
Captured output from running it locally.
The terminal output reflects what a fresh Expo-centered setup feels like: react-native-reanimated is part of the documented SDK path, with the Babel plugin and its configuration described on Expo’s Reanimated SDK page. That is the install experience teams compare against when they evaluate any animation choice on RN.
Look at what’s built on top: Moti, Skia, Tamagui, redash
The strongest evidence Reanimated has won the RN contest is not stars or downloads — it is consolidation. Read the package documentation of the libraries that define the current RN UI experience:
- Moti, the declarative motion library cited in RN starters, declares
react-native-reanimatedas a required peer dependency. ItsMotiViewAPI compiles down to Reanimated shared values. - react-native-skia from Shopify integrates with Reanimated through
useAnimatedReactionand shared-value bridging, treating Reanimated as a source of animated values that drive Skia draws. - Tamagui’s animation driver ships
@tamagui/animations-react-nativeand@tamagui/animations-moti, both of which resolve to Reanimated under the hood on native. - react-native-redash, the long-running collection of animation utilities, is published as helpers for Reanimated.
No equivalent shelf has consolidated around @react-spring/native. That asymmetry is the empirical answer to the comparison question. Engineers vote with their imports, and they imported Reanimated.
Tamagui’s universal components goes into the specifics of this.
The honest tax: New Architecture coupling, CMake pain, install friction
The verdict reads as judgment rather than cheerleading only if the trade is acknowledged honestly. Reanimated is not free. Its tighter coupling to the React Native New Architecture means upgrades and Android NDK installs surface real failures. CMake errors during Android builds — usually traceable to an NDK version mismatch with the project’s android/build.gradle — show up regularly in the Reanimated issue tracker. The library’s worklet model also demands a Babel plugin and a discipline around closure capture that React Spring’s plain React hooks never required.
React Spring’s install story is genuinely lighter. A plain npm install @react-spring/web and a hook gets a developer animating with no native build pain. That advantage is real on the web. On RN, it is a smaller advantage than it sounds, because the install pain a team avoids by picking React Spring is install pain they will pay later as soon as they reach for any of the libraries on top of Reanimated.
Related: sticky collapsible headers.

The radar chart compares the two libraries across five axes — runtime thread, ergonomic API, ecosystem gravity, install simplicity, and platform coverage. React Spring wins install simplicity outright; Reanimated wins everywhere else on the RN target. That shape is the article’s argument rendered visually.
The strongest counter-argument
The strongest objection: not every RN app needs UI-thread performance, and for a settings screen with a fade-in card, React Spring’s lighter install and friendlier API are real wins. Choosing a runtime-tier dependency to animate two opacity transitions is over-engineering.
This is fair as far as it goes, and fails on the second-order effect. The animation library a project picks for the easy cases is the one designers and engineers reach for when the hard cases arrive — a draggable bottom sheet that has to stay locked to the finger, a scroll-linked header that cannot stutter, a gesture-driven carousel.
Migrating from React Spring to Reanimated mid-project is a non-trivial rewrite because the value model differs (animated values via hooks vs shared values via worklets). Starting on Reanimated costs more upfront and zero later. Starting on React Spring costs less upfront and the migration tax later.
For most RN projects expected to live past a year, the discount-now-pay-later trade is the worse deal.
The contest you should actually be having: React Spring vs Framer Motion on the web
This is the comparison most teams actually need. On the web, React Spring is alive and competitive, and its real opponent is Framer Motion (now distributed under the motion package on npm). The honest current question for a Next.js, Remix, Vite, or Gatsby project animating a hero, a list, or a layout transition is which of those two to pick.
The split is roughly: React Spring’s physics-first model and composable hook surface still win for procedural, interruption-heavy animations and for 3D scenes where it ties into @react-three/fiber. Framer Motion wins for layout animations, declarative variants, and orchestrated sequences where the API affordances (layout, AnimatePresence, motion.div) make the code shorter and easier to maintain. That is a fight with no obvious winner — exactly the comparison React teams benefit from, and exactly the one the existing coverage skips.
There is a longer treatment in Framer Motion’s layout magic.
A one-screen decision rubric
| Target | Primary use case | Pick | Why |
|---|---|---|---|
| React Native (Expo or bare) | Any animation, including gestures and scrolls | Reanimated | UI-thread worklets, Expo support, ecosystem consolidation |
| React Native | Declarative ergonomics on top of Reanimated | Moti | Compiles to Reanimated shared values; no second runtime |
| React Native | Canvas-style scenes, charts, custom drawing | react-native-skia + Reanimated | Skia draws driven by Reanimated shared values |
| Web React (Next.js, Remix, Vite, Gatsby) | Physics, interruption-heavy, 3D via react-three-fiber | React Spring | Composable hooks, physics model, @react-spring/three integration |
| Web React | Layout animations, variants, presence transitions | Framer Motion (motion) | Shorter declarative API for layout-driven cases |
The practical takeaway is narrow: choose Reanimated for any React Native project expected to live past its first ship, layer Moti on top if a declarative API is preferred, and reserve React Spring for the web — where its real fight is against Framer Motion, not Reanimated.
A related write-up: scroll-driven web animations.
Does React Spring still work on React Native?
Yes, @react-spring/native is still published and runs, but it is not part of Expo’s documented SDK path, and the higher-level RN animation libraries that anchor the modern stack — Moti, Skia, Tamagui, redash — do not consolidate around it. It works, but it is an opt-in dependency in a world that has standardized on Reanimated for the runtime layer.
Can I mix Reanimated and React Spring in the same React Native app?
Technically yes — they coexist as separate npm packages — but their value models do not interop. Reanimated shared values mutate on the UI thread through worklets, while @react-spring/native values flow through React’s render cycle on the JS thread. There is no shared bridge, so mixing them produces two parallel animation systems rather than a composed one, and any cross-library orchestration has to be glued together by hand.
Which animation library should I pick for a new Expo project in 2026?
Reanimated. The Expo SDK documents react-native-reanimated as a supported library with the Babel plugin and Metro setup spelled out, and the libraries new Expo projects routinely reach for — Moti, react-native-skia, Tamagui — assume Reanimated is installed as a peer dependency. Picking anything else introduces install pain and ecosystem friction that the documented Expo path otherwise avoids entirely.











