react-brain
Browse decisions
React & language foundations 3App architecture 9UI 12Platform & native 9Build, test, observe, secure 6AI in React apps 3stack composerdecision recordscensusstaleness bencharchitecturechangelogmethodologyroadmap

entriesui · verified 2026-07-13 · react + react-native

Animation & gestures

reviewedconfidence: mediumthis tier holds 50% on the public scorecard (3/19 graded · 0 overturned) →

cited by: svg

re-verified 3× — 2026-07-13 · 2026-07-10 · 2026-07-06 · changelog

recommendation

React Native → Reanimated 4 + Gesture Handler 3 for real UI-thread animation & gestures (core Animated only for trivial cases). Web (React DOM) → Motion (framer-motion's successor) for declarative layout/exit/gesture animation.

  • web animation (React DOM) → Motion / framer-motion — Reanimated & Gesture Handler are React Native only
  • custom/GPU drawing or visuals → react-native-skia
  • designer-made animations → lottie-react-native (or Skia/Skottie)
  • designer animations that need INTERACTIVITY/state machines, or many Rive views sharing files → Rive; new work goes to the Nitro line @rive-app/react-native (0.4.x, early — pin), not the quiet legacy package
  • image-to-image morph transition → react-native-morph-view (GPU shader; niche, lead-level)
  • simple fade/slide, want declarative → Moti / LayoutAnimation (RN); Motion (web)
  • custom screen / shared-element transitions on React Navigation → react-native-screen-transitions (new; pin)
  • hundreds of concurrently-animating views blowing the frame budget → benchmark react-native-ease (fully native-driven; young)
  • heavy animation perf → route to react-native-best-practices

Options & tradeoffs

the field considered — and why each one isn’t the default here

optiontradeoffevidence
Reanimated 4UI-thread + CSS-style animations/transitions; worklets split into react-native-worklets; requires New Arch5.6M/wk · ships in 12/34
Gesture Handler 3.0native gestures; v3 adds a hook-based API built for the React Compiler + Reanimated 44.6M/wk · ships in 12/34
react-native-worklets 8.0the worklets runtime under Reanimated 4 (now its own package); Shareable values across isolated runtimes4.7M/wk · ships in 8/34
react-native-skia (2.x)GPU 2D drawing; v2.1 plays Lottie via Skottie; pairs with Reanimated1.2M/wk · ships in 3/34
lottie-react-nativedesigner Lottie/JSON animations; v7 adds visionOS1.4M/wk · ships in 7/34
Rive — @rive-app/react-native (Nitro) / rive-react-native (legacy)designer-driven INTERACTIVE vector animation (state machines) — the Lottie alternative; the SDK was rewritten on Nitro under Rive's official scope (@rive-app/react-native, 0.4.x EARLY line): files/view-models become shared typed HybridObjects — Margelo-measured up to 94× multi-view loads + ~4.7× lower memory vs legacy (rewrite authors' own benchmark); legacy unscoped pkg at 9.8.3, quiet since 2026-04
react-native-morph-view (Software Mansion)GPU image-morph transitions (Metal/AGSL shaders, metaball blend); RN 0.76+, iOS 15.1+/Android 13+; niche/new
Animated (core)built-in; RN 0.85 shared backend allows layout-prop animation with the native driver (from 0.85.1)5.6M/wk · ships in 12/34
Moti / LayoutAnimationdeclarative transitions; Moti wraps Reanimated — but last published 2025-01 (verified vs npm 2026-07): drifting toward maintenance; fine if installed, prefer plain Reanimated/LayoutAnimation for new work528k/wk · ships in 2/34
react-native-screen-transitionscustom screen/shared-element transitions FOR React Navigation (blank-stack navigator, bounds-driven navigation.zoom(), gesture choreography); featured on the official React Navigation blog; v3.8 active 2026-07, newer245k/wk
react-native-easeanimations driven entirely by Core Animation/ObjectAnimator — no per-frame JS OR UI-thread worklet work; author-run benchmark shows it holding frame budget at view counts where Reanimated saturates; young, and see the benchmark-bias caveat in reading20k/wk
Motion / framer-motion (WEB)the web (React DOM) animation default — declarative layout/exit/gesture animation; Motion is framer-motion's successor; React Native uses Reanimated instead12.9M/wk · ships in 3/34

evidence: npm weekly downloads (signals snapshot) · “ships in n/D” = adoption across the production-app census, honest denominators

npm weekly downloads (from the corpus's last signals run): react-native-reanimated 5.6M · react-native-gesture-handler 4.6M · react-native-worklets 4.7M · framer-motion 38.7M · motion 12.9M · lottie-react-native 1.4M · @shopify/react-native-skia 1.2M · moti 528k · react-native-screen-transitions 245k · react-native-ease 20k

Verified notes

RN 0.85 (2026-04) introduced a shared C++ animation backend so Animated and Reanimated ride one engine (built with Software Mansion). Heavy-animation perf routes to react-native-best-practices. RIVE (added 2026-07-13, Margelo blog pass): the RN SDK's Nitro rewrite ships as NEW scoped @rive-app/react-native (0.4.14) while legacy rive-react-native sits at 9.8.3 (both verified vs npm 2026-07-13) — a supersession in progress; WATCH for the new line reaching 1.0 or a formal legacy deprecation before adding a migrate rule. WEB: Motion (the framer-motion successor) is the web animation default — added 2026-06-25 after the evidence-loop corpus self-audit flagged that this [react]-platform entry had options/recommend for React Native only, no web pick (caught from ledgerhr's framer-motion usage). Verified vs the official RN 0.85 blog.

Canonical reading

Editorial annotations on why each piece matters — the articles themselves are the originals; read them there.

CSS vs. JavaScript AnimationsJosh W. Comeau

First-principles explainer on the real distinction (main-thread contention, compositor-friendly properties, WAAPI) rather than the CSS-is-always-faster myth. A durable animation mental model that applies to web and RN reasoning alike.

How react-native-ease runs animations with no JavaScript loopPeter Piekarczyk

Deep dive on driving animations entirely via Core Animation / ObjectAnimator with no per-frame JS, incl. iOS model vs presentation layers and cross-platform spring physics. The mental model for truly native-driven RN animation.

Chasing a Phantom Jump: making Skia + Reanimated smooth on low-end AndroidVishesh Raheja (Margelo)

A low-end-Android profiling deep-dive: smoothness is frame-cadence timing, not curve math; the dominant fix is SurfaceView over TextureView (no per-frame texture upload, ~50-65% less RenderThread CPU), plus stable-reference buffer mutation and quantizing per-frame values. With profiler-triangulation methodology (gfxinfo/Perfetto/Hermes).

The real cost of React Native animations: benchmarking every approachJanic Duplessis (Expo; react-native-ease author)

The only cross-library per-frame benchmark: UI-thread cost of core Animated vs Reanimated (shared values AND the CSS API) vs Ease on real devices — at ~500 animating views only the fully native-driven approach stays under frame budget (Reanimated SVs measured ~36ms/frame). CAVEAT: the author created Ease, the approach that wins — treat the numbers as vendor-run and re-measure on your own screens; the methodology and the per-frame cost model are the durable part.

A React trick to improve exit animationsMax Barvian

Uses Suspense to freeze exiting content during animations; explains Fragment refs, useInsertionEffect, and Suspense DOM-update behavior. A durable web exit-animation technique grounded in React internals.

Rewriting Rive React Native with Nitro Modules: up to 94× Faster Multi-View LoadsMiklós Fazekas (Margelo)

Why the Rive RN SDK's wins came from MODELING, not micro-optimization: the legacy module flattened files/view-models into a per-view God object, so every view re-parsed state; Nitro HybridObjects make them shared typed objects (parse once, render many) — 94× on a 24-view load, ~4.7× lower memory, ~0.3-0.4µs calls vs ~1.5µs TurboModule / ~21µs legacy bridge (iPhone 13 mini, release; the rewrite authors' own benchmark). A general lesson for native-module design: model objects, not modules.

Sources

Depth (in-domain rules) is owned by the react-native-best-practices skill — this entry is selection breadth.

The full explanation

The reviewed long-form essay behind this entry — the why, not a how-to. Also on GitHub.

About animation & gestures — where the per-frame work runs

Diataxis: Explanation. This page builds understanding of the animation landscape — the reasoning behind the picks. It is not an API guide. Animation performance rules (thresholds, profiling) are owned by react-native-best-practices; GPU drawing by RB-E-GAMES/RB-E-SVG. Read this for the why.

The one question that organises everything: which thread pays, every frame?

An animation is a piece of work that must complete every ~16ms, forever, while the rest of your app keeps running. So the durable selection axis is not API style — it is where that per-frame work executes. There are four tiers, each cheaper than the one before:

  1. JS thread (core Animated with useNativeDriver: false) — every frame crosses into your busiest thread. One GC pause, one heavy render, and the animation stutters.
  2. UI thread via worklets (Reanimated) — JS code compiled to run on the UI thread's own runtime (react-native-worklets, now a standalone package). Immune to JS-thread jank, but the worklet itself still costs UI-thread time per frame.
  3. Fully native drivers (native-driven Animated, react-native-ease) — the animation is handed to Core Animation / ObjectAnimator once and no per-frame JS or worklet runs at all.
  4. GPU canvas (Skia) — for drawing that isn't view-property animation at all.

Everything in the entry falls out of this ladder, including the failure modes.

The default, and why

React Native → Reanimated 4 + Gesture Handler 3 for real UI-thread animation and gestures. Web (React DOM) → Motion (framer-motion's successor).

Reanimated 4 sits at tier 2 and is the ecosystem's center of gravity: CSS-style transitions, shared values, and — since RN 0.85 — a shared C++ animation backend with core Animated, so the built-in and the library ride one engine instead of two competing ones. Gesture Handler 3 completes it: gestures are recognized natively and feed worklets directly, and its v3 hook-based API was rebuilt for the React Compiler era (RB-E-REACT-CORE). On the web the same reasoning lands on Motion: declarative layout/exit/gesture animation over compositor-friendly properties — Reanimated and Gesture Handler are React Native-only.

The landscape, tier by tier

Reanimated 4 / react-native-worklets — the tier-2 workhorse. Worklets are now their own package, which matters beyond animation (VisionCamera frame processors, Expo UI synchronous state — RB-E-NATIVE-UI).

Gesture Handler 3 — native gesture recognition; the input half of the animation story.

Core Animated — fine at tier 3 (native driver) for simple cases; since 0.85.1 it can even drive layout props natively. Its trap is tier 1: useNativeDriver: false silently moves the work to the JS thread (the corpus's source-signal rule flags exactly this).

react-native-ease — the tier-3 specialist: animations driven entirely by Core Animation / ObjectAnimator, zero per-frame JS or worklet work. The author's cross-library benchmark shows it holding frame budget at view counts where worklet approaches saturate — read with the stated caveat that the benchmark's author built the winner; the cost model is the durable part.

react-native-screen-transitions — screen/shared-element choreography for React Navigation (RB-E-NAV); featured on the official React Navigation blog, new — pin.

Skia / Lottie / morph-view — tier 4 and specials: react-native-skia for custom GPU drawing (and Lottie via Skottie), lottie-react-native for designer-made animation files, react-native-morph-view for GPU image-morph transitions (niche).

Moti — declarative sugar over Reanimated; dormant since early 2025. Fine if installed; prefer plain Reanimated or LayoutAnimation for new work.

Tradeoffs and failure modes to name out loud

  • useNativeDriver: false — the classic tier-1 trap: JS-thread animation that jitters under load. Native-drive it or move it to Reanimated.
  • Hundreds of concurrently animating views — even tier 2 pays per-frame worklet cost per view; at scale (~hundreds) only tier 3 stays under budget. Benchmark before committing an animation-heavy screen design.
  • Reaching for Skia to animate view properties — GPU canvas is for drawing; transform/ opacity animation belongs in tiers 2–3.
  • Two animation systems fighting — pre-0.85 this was real (Animated vs Reanimated timing); the shared C++ backend resolved it. On ≥0.85 mixing them is no longer an architectural smell.
  • Web habits on native (and vice versa) — Motion doesn't exist on RN; Reanimated doesn't exist on the web. Shared-codebase teams keep animation platform-local (RB-E-CROSSPLATFORM).

How it interacts with the rest of the stack

  • Navigation (RB-E-NAV). Screen transitions are animations with navigation semantics — react-native-screen-transitions builds them on React Navigation rather than forking it.
  • Native (RB-E-NATIVE). Worklets are the same machinery VisionCamera v5 frame processors use; understanding tier 2 here pays off there.
  • Lists (RB-E-LISTS). List re-renders and animations compete for the same frame budget — the "render once" discipline in the STATE/LISTS readings is the other half of smoothness.
  • React core (RB-E-REACT-CORE). Gesture Handler 3's hook API assumes the Compiler era; animation values deliberately live outside React state to avoid re-render coupling.

In one paragraph

Pick animation tooling by which thread pays every frame. React Native's default is Reanimated 4 + Gesture Handler 3 — UI-thread worklets, one shared C++ engine with core Animated since RN 0.85 — with core Animated (native-driven) for trivial cases, ease when hundreds of concurrent animations demand zero per-frame work, Skia for GPU drawing, and react-native-screen-transitions for shared-element navigation choreography. On the web, use Motion. The failure modes are all the same mistake in different clothes: putting per-frame work on a thread that has better things to do.


*See also: RB-E-NAV (screen transitions), RB-E-NATIVE (worklets/JSI machinery), RB-E-GAMES

  • RB-E-SVG (GPU drawing), RB-E-LISTS (the other half of the frame budget). Performance rules and thresholds: the react-native-best-practices skill.*

Related in ui: styling · component-libs · lists · a11y · i18n · charts · editors · svg · maps · calendars · polish