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

entriesreact-foundations · verified 2026-08-18 · react-native

React Native release timeline — what each version changed

reviewedconfidence: highthis tier holds 83% on the public scorecard (6/11 graded · 0 overturned) →

related decisions: animation

cited by: typescript · ota

re-verified 6× — 2026-08-18 · 2026-07-28 · 2026-07-16 · 2026-07-13 · 2026-07-10 · 2026-07-06 · changelog

recommendation

Target the latest stable RN (0.87); the New Architecture is non-optional from 0.82, so plan any migration around that line.

  • on RN < 0.82 → budget a New-Arch migration; Legacy was frozen at 0.80 (no fixes)
  • on RN ≥ 0.86 → drop react-native-edge-to-edge (now in core)
  • moving to 0.87 → the Strict TypeScript API is the default: fix deep imports into react-native/Libraries/* (the /migrate-to-strict-api skill + the ESLint fixers do most of it), or set the react-native-legacy-deep-imports customCondition as a bridge — that escape hatch exists only through 0.88
  • still importing InteractionManager / core SafeAreaView / deep paths → 0.87 removed them; migrate now
  • on iOS and tempted by SwiftPM → it is experimental and additive in 0.87; CocoaPods stays the default and the supported path — but trunk goes read-only 2026-12-02 (no NEW podspec versions after that; existing ones keep resolving), so audit which iOS deps still depend on it
  • quoting a pre-0.84 row as authoritative → verify against that version's RN blog first

Options & tradeoffs

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

optiontradeoff
RN 0.76 (2024-10)New Arch ON by default; React Native DevTools; boxShadow + filter; iOS 15.1 / Android API 24 min; `react-native init` deprecated → Expo recommended
RN 0.77CSS-ish styling (display:contents, box-sizing, mixBlendMode, outline); Android 15 16KB pages + edge-to-edge
RN 0.78 (2025-02)React 19 (Actions, useActionState, useOptimistic, use, React Compiler); ref-as-prop (forwardRef deprecated)
RN 0.79Metro ~3x faster cold start (deferred hashing); remote-JS Chrome debugging removed
RN 0.80 (2025-06)opt-in Strict TypeScript API (types from source); Legacy Architecture FROZEN (2025-06-02)
RN 0.81Android 16 (API 36) + mandatory edge-to-edge; SafeAreaView deprecated → safe-area-context; JavaScriptCore removed (Hermes-only); precompiled iOS opt-in; React Compiler in default template (RC)
RN 0.82New Architecture MANDATORY (opt-out ignored); Hermes V1 experimental; debugOptimized Android variant; DOM Node APIs
RN 0.83React 19.2 (<Activity>, useEffectEvent); Intersection Observer; DevTools network inspector; prebuilt artefacts
RN 0.84 (2026-02-11) ✓Hermes V1 DEFAULT; precompiled iOS binaries default; Node 22.11+ min; Legacy-Arch stripped; bi-monthly cadence
RN 0.85 (2026-04-07) ✓shared C++ animation backend; Jest preset → @react-native/jest-preset; layout-prop native driver (0.85.1)
RN 0.86 (2026-06-11) ✓Android-15+ edge-to-edge in core (drop react-native-edge-to-edge); DevTools light/dark; 2nd zero-breaking-change release
RN 0.87 (2026-08-11) ✓Strict TypeScript API becomes the DEFAULT (types generated from source; deep imports into react-native/Libraries/* are now a type error; opt out through 0.88 with the "react-native-legacy-deep-imports" tsconfig customCondition, then the legacy types go); Metro 0.84→0.87 (source maps 2x faster, half the source-map memory, stable TS/ESM config files, .es6 + YAML configs dropped); EXPERIMENTAL Swift Package Manager for iOS (`npx react-native spm`, CocoaPods still the default and the supported path — the docs say not for production yet); AGP 9 support (opt out of built-in Kotlin + new DSL via android.builtInKotlin=false / android.newDsl=false); toolchain floor rises to Node ≥22.13, Kotlin 2.0+, minCompileSdk 34, compileSdk/buildTools 37. Removals: InteractionManager (→ requestIdleCallback), Modal `animated`, StatusBar backgroundColor/translucent, boolean keyboardShouldPersistTaps, the useTurboModules flag, *Properties type aliases. backgroundImage loses its experimental_ prefix. 0.84.x moves to UNSUPPORTED

Migration lines

version and deprecation lines this decision tracks — for YOUR repo's sequenced plan: the doctor or npx -y @heart-it/react-brain migrate .

react-native < 0.87.0 → React Native 0.87 (current stable) [upgrade · effort L]

the ladder crosses hard lines: New Architecture is the ONLY runtime ≥0.82 (Legacy frozen at 0.80, stripped at 0.84), Hermes V1 + precompiled iOS binaries default at 0.84 (Node 22.11+ min), the Jest preset moves to @react-native/jest-preset at 0.85, Android edge-to-edge lands in core at 0.86, and 0.87 makes the Strict TypeScript API the default (deep imports into react-native/Libraries/* become type errors) while raising the floor to Node 22.13 / Kotlin 2.0 / compileSdk 37 and dropping InteractionManager. Every New-Arch-gated upgrade below unblocks at 0.82+; budget the 0.87 step as type-codemod work.

reactnative.dev/blog/2026/02/11/react-native-0.84 · reactnative.dev/blog/2026/06/11/react-native-0.86 · reactnative.dev/blog/2026/08/11/react-native-0.87

react-native-edge-to-edge → remove the package — Android-15+ edge-to-edge is in RN core since 0.86 [conditional · effort S]

RN 0.86 handles edge-to-edge in core; once there, the polyfill package is redundant

reactnative.dev/blog/2026/06/11/react-native-0.86

Verified notes

Use this to tell a project what it gains/loses by moving RN versions. Rows marked ✓ (0.84–0.87) are verified vs official RN blogs; 0.76–0.83 are from release history + RN Rewind — verify a specific row against the RN blog before quoting it as authoritative. Expo SDK mapping: SDK 55 = RN 0.83 + React 19.2; SDK 56 = RN 0.85 + Expo UI stable; SDK 57 = RN 0.86 + React 19.2 (2026-06, verified vs the SDK 57 changelog — skipped the beta phase, since RN 0.86 was breaking-change-free; Expo is testing near-immediate optional upgrades as RN moves to 6 releases/yr). APPLE PLATFORM FLOOR (2026-07-10, verified vs the Expo post's body): since 2026-04-28, App Store Connect uploads MUST be built with Xcode 26 / iOS-26-family SDKs — Expo SDK 54/55 EAS images already run Xcode 26, SDK ≤53 needs an explicit image opt-in; practically, stay ≥SDK 54. 0.87 IS THE STRICT-API LINE (2026-08-11, verified vs the release blog + the v0.87.0 CHANGELOG): the 0.80 opt-in preview became the default, so a 0.87 bump is a TYPE migration first and a runtime migration second — plan it as codemod work (the /migrate-to-strict-api skill and the ESLint fixers), and treat the react-native-legacy-deep-imports customCondition as a bridge that expires after 0.88. It also raises the toolchain floor (Node ≥22.13, Kotlin 2.0+, compileSdk 37), so CI images move with it. Expo: 0.87 ships in expo@canary first, not in SDK 57 (= RN 0.86). Hermes: 0.87 pins hermes-compiler 250829098.0.16 (verified vs the tag's package.json), past the .15 backport that fixes the worklet debug-metadata memory regression — see RB-E-ANIMATION. WHY SWIFTPM NOW, AND WHAT IS ACTUALLY HAPPENING TO COCOAPODS (verified vs the CocoaPods blog, because the newsletter framing of this is overstated): CocoaPods has been in declared MAINTENANCE MODE since 2024-08-13, and on 2026-12-02 trunk goes READ-ONLY — the server will permanently refuse NEW Podspecs and the Specs repo gets archived (a test run runs 2026-11-01→07). That is not a shutdown: the Specs repo and CDN keep serving, so existing builds and existing pod versions keep working, and private specs repos are unaffected. The real consequence is that from December no library can publish a NEW version through trunk. So 0.87's experimental SwiftPM path is the ecosystem's answer to a dated deadline, not a preference — but it is still experimental, so the planning move today is to know which of your iOS dependencies still resolve only through trunk.

Canonical reading

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

React Native Architecture: From Bridge to FabricFelipe Ramalho (Codeminer42)

Traces RN's architecture from the old async JSON bridge to the New Architecture (JSI, Fabric's immutable C++ shadow tree, Turbo Modules, Codegen), explaining why each piece exists. The 'why it changed' narrative behind the 0.76→0.82 version arc — not a release note.

Sources

Depth (in-domain rules) is owned by the react-native-jsi 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 the React Native release timeline — the version ladder

Diataxis: Explanation. This page builds understanding of what an RN version number means — why the release timeline reads as an architecture timeline, not a changelog. It is not an upgrade how-to; the sequenced upgrade knowledge lives in the index entry's migrate: block (assembled by react-brain migrate), and the per-version rows themselves live in the index entry RB-E-RN-VERSIONS. New-Architecture internals — JSI, Fabric, TurboModules, Codegen — are owned by the react-native-jsi skill. Read this for the why.

The one idea that organises everything: the version number is a rung, not a date

A React Native version tells you more than when a project last ran npm install — it tells you what code that project is allowed to write. The entry's own migrate guidance says it plainly: "the ladder crosses hard lines." Climb the rows and three kinds of permission change under your feet:

  1. Architecture permission. New Architecture ON by default (0.76) → Legacy Architecture FROZEN (0.80, dated 2025-06-02) → New Architecture MANDATORY — opt-out ignored (0.82) → Legacy-Arch stripped (0.84). Below 0.82 legacy code still runs, but on an architecture receiving no fixes; at 0.82 the opt-out stops working; at 0.84 the code you would fall back to is no longer shipped.
  2. Engine permission. JavaScriptCore removed — Hermes-only (0.81) → Hermes V1 experimental (0.82) → Hermes V1 DEFAULT plus precompiled iOS binaries by default (0.84). The engine stopped being a choice at 0.81; from 0.84 its next generation is simply what you get.
  3. API permission. react-native init deprecated → Expo recommended (0.76); forwardRef deprecated → ref-as-prop (0.78, with React 19); core SafeAreaView deprecated → safe-area-context (0.81); and the 0.87 RC is a cleanup release that removes long-deprecated APIs (InteractionManager, SafeAreaView), restricts deep imports, and deprecates ImageBackground. Deprecations on one rung become removals a few rungs up.

The floors move too, on other people's schedules: iOS 15.1 / Android API 24 minimums (0.76), Android 15's 16KB pages (0.77), Android 16 / API 36 with mandatory edge-to-edge (0.81), Node 22.11+ (0.84) — and, outside RN's ladder entirely, Apple's rule that since 2026-04-28 App Store Connect uploads must be built with Xcode 26 / iOS-26-family SDKs.

The default, and why

Target the latest stable RN (0.86); the New Architecture is non-optional from 0.82, so plan any migration around that line.

The recommendation names one line, because one line dominates: 0.82 is where the New Architecture became the only runtime. Everything below it sits on an architecture frozen at 0.80 (no fixes) and stripped at 0.84 — the entry's when-clause is blunt: on RN < 0.82, budget a New-Arch migration. And per the migrate block, every New-Arch-gated upgrade elsewhere in a stack "unblocks at 0.82+" — the line is a dependency of other decisions, not just this one.

Meanwhile the top of the ladder got cheaper to stand on: RN runs a bi-monthly cadence (0.84), 0.86 was the second zero-breaking-change release, and Expo shipped SDK 57 against it having skipped the beta phase precisely because 0.86 was breaking-change-free — with Expo testing near-immediate optional upgrades as RN moves to six releases a year. Staying current is routine; falling behind the architecture line is the expensive state.

The landscape: reading the rungs

The entry's twelve rows (0.76 → 0.87 RC) are one row per version, each carrying that version's durable change. Beyond the three permission lines above, the rows carry a steady capability drip: CSS-ish styling — display:contents, box-sizing, mixBlendMode, outline (0.77) after boxShadow + filter (0.76); React 19 with Actions, useActionState, useOptimistic, use, and the React Compiler (0.78), the Compiler reaching the default template as RC (0.81), React 19.2 with <Activity> and useEffectEvent (0.83); DOM Node APIs (0.82) and Intersection Observer (0.83); Metro ~3x faster cold start via deferred hashing, with remote-JS Chrome debugging removed (0.79); React Native DevTools (0.76), its network inspector (0.83), light/dark (0.86); opt-in Strict TypeScript API with types from source (0.80); debugOptimized Android variant (0.82); prebuilt artefacts (0.83), precompiled iOS opt-in (0.81) then default (0.84); a shared C++ animation backend and the Jest preset moving to @react-native/jest-preset (0.85), the layout-prop native driver landing in 0.85.1; Android-15+ edge-to-edge in core (0.86).

Two usage notes carry the entry's trust model:

  • Verification is per-row. Rows marked ✓ (0.84–0.86) are verified against the official RN release blogs; 0.76–0.83 come from release history + RN Rewind — verify a specific row against the RN blog before quoting it as authoritative. The 0.87 row is RC-verified against npm's next tag (per TWiR #289) and should be re-verified against the release blog when stable lands.
  • Most teams ride the ladder via Expo. The entry's mapping: SDK 55 = RN 0.83 + React 19.2; SDK 56 = RN 0.85 + Expo UI stable; SDK 57 = RN 0.86 + React 19.2 (2026-06, verified against the SDK 57 changelog). The Apple floor lands here too: SDK 54/55 EAS images already run Xcode 26, SDK ≤ 53 needs an explicit image opt-in — practically, stay ≥ SDK 54.

For the why it changed behind the 0.76→0.82 arc — the old async JSON bridge giving way to JSI, Fabric's immutable C++ shadow tree, Turbo Modules, Codegen — the entry's reading is Felipe Ramalho's "React Native Architecture: From Bridge to Fabric" (Codeminer42): a narrative, not a release note.

Tradeoffs and failure modes to name out loud

  • Camping below 0.82. Legacy has been frozen since 0.80 and stripped since 0.84; the when-clause is to budget a New-Arch migration, and the migrate block prices it at effort L with urgency upgrade. This is the rung where waiting compounds.
  • Carrying polyfills past the rung that absorbed them. react-native-edge-to-edge is redundant on ≥ 0.86 — Android-15+ edge-to-edge is in core; the entry's second migrate row exists to delete the package.
  • Importing on borrowed time. Still importing InteractionManager, core SafeAreaView, or deep paths → the when-clause says migrate now; the 0.87 RC removes and restricts them.
  • Quoting pre-0.84 rows as gospel. The corpus's own discipline: history-sourced rows get verified against the RN blog before load-bearing use.
  • Missing floors that aren't RN's. Node 22.11+ arrived with 0.84; the Xcode 26 upload rule binds since 2026-04-28 regardless of your RN version. Floors don't negotiate.
  • Assuming an upgrade only touches app code. 0.85 moved the Jest preset to @react-native/jest-preset — some rungs break config, not components.

How it interacts with the rest of the stack

  • New Architecture depth (react-native-jsi, RB-E-NATIVE). The ladder is the schedule of the New Architecture; what JSI, Fabric, TurboModules, and Codegen actually are belongs to the skill and the native entry.
  • Build & engine (RB-E-BUILD). Hermes V1, precompiled iOS binaries, prebuilt artefacts, and Metro's cold-start work are the build-time face of the same rungs.
  • React itself (RB-E-REACT-CORE). RN versions pin React versions — 0.78 → React 19, 0.83 → React 19.2. The Actions/Compiler era arrives via this ladder.
  • Testing (RB-E-TESTING). The 0.85 Jest-preset move is where the ladder reaches into test config.
  • The migrate tool. The entry's migrate: block is this page made executable: installed react-native below 0.86 → a sequenced, receipted upgrade case assembled by react-brain migrate.

In one paragraph

The React Native version number is an architecture timeline wearing a release number: where you stand on the ladder decides what code you're allowed to write. The New Architecture went default (0.76) → Legacy frozen (0.80) → mandatory, opt-out ignored (0.82) → Legacy stripped (0.84); the engine went Hermes-only (0.81) → Hermes V1 default with precompiled iOS binaries (0.84); deprecated APIs (InteractionManager, core SafeAreaView, deep imports) fall off at the 0.87 cleanup release. Target the latest stable (0.86 — second consecutive zero-breaking-change release, bi-monthly cadence, Expo SDK 57 tracking it same-cycle), plan any migration around the 0.82 line, verify pre-0.84 rows against the RN blog before quoting them, and respect the floors that move on Apple's and Node's schedules, not yours.


See also: RB-E-NATIVE (what the New Architecture is), RB-E-BUILD (Hermes, precompiled binaries, Metro), RB-E-REACT-CORE (the React versions each RN pins), RB-E-TESTING (the 0.85 Jest-preset move). New-Arch internals — JSI, Fabric, TurboModules, Codegen: the react-native-jsi skill. Background reading: Felipe Ramalho, "React Native Architecture: From Bridge to Fabric" (Codeminer42).

Related in react-foundations: react-core · typescript