Mobile — React Native Development

Migrating to the React Native New Architecture (2026): What Breaks and How to Fix It

Direct answer

The React Native New Architecture replaces the asynchronous Bridge with the JSI (a direct JavaScript-to-C++ interface), the old Paper renderer with Fabric, and eager NativeModules with lazy TurboModules. As of React Native 0.82 (October 2025) an app runs entirely on it, and Expo SDK 55 removes the option to turn it off — the legacy architecture was frozen in June 2025. Migrating mostly means upgrading React Native, enabling the flag, rebuilding native, and updating or replacing native libraries that still assume the Bridge. Most pure-JavaScript apps need little to no change; the breakage is concentrated in native modules, custom view managers, and a few deprecated JS APIs like setNativeProps and direct findNodeHandle manipulation.

The New Architecture stopped being optional. If you're on Expo SDK 55 or React Native 0.82+, you're already running it — and if you're on an older app you're migrating whether you planned to or not, because the legacy architecture was frozen in June 2025 and gets no more fixes. This is the migration I actually run for clients: what the three moving parts really are, how to tell where your app stands today, exactly what breaks, and the order to fix it in so you're not staring at a white screen at 2am.

Legacy — the Bridge JavaScript thread serialize to JSONasync message queue Native (UI + modules) batched · asynchronous · the bottleneck New Architecture — JSI JavaScript (Hermes) JSI (C++)direct refs · synchronous Native (Fabric · TurboModules) no serialization · call native like a function

Key facts, with sources

  • React Native 0.82 (October 8, 2025) is the first release that runs entirely on the New Architecture; the legacy renderer is gone at runtime. (React Native blog)
  • The legacy architecture was frozen in June 2025 — no new features or bug fixes are being made for it. (React Native Working Group)
  • Expo SDK 55 and later run entirely on the New Architecture; it is always enabled and cannot be disabled. SDK 54 is the last version that can turn it off. (Expo docs)
  • New projects have shipped with the New Architecture enabled by default since Expo SDK 52 / React Native 0.76. (Expo docs)

The three parts that replaced the Bridge

Fabricnew rendering system TurboModuleslazy native modules Codegentype-safe JS to native JSI — the C++ interface that replaced the Bridgedirect, synchronous access between JavaScript and native

The old architecture had one fundamental bottleneck: every call between JavaScript and native code was serialized to JSON, put on an asynchronous queue, and deserialized on the other side. Nothing could be synchronous, and under load the queue was where jank came from. The New Architecture deletes that queue. It has three pillars, and all of them sit on top of one foundation called the JSI.

The JSI (JavaScript Interface) is a small C++ layer that lets JavaScript hold direct references to native objects and call them like plain functions — synchronously when it needs to. Fabric is the new rendering system built on the JSI; it replaces the old Paper renderer and lets React's concurrent features actually reach the native view tree. TurboModules replace the old NativeModules: instead of loading every native module at startup, they're loaded lazily the first time you touch them, so cold start gets lighter. Codegen is the build-time tool that reads a TypeScript spec of your native interface and generates the type-safe C++, Java, and Objective-C glue, so a mismatch between JS and native becomes a compile error instead of a runtime crash.

Where your app stands right now

Before you plan anything, find out whether you're already on it — a surprising number of apps got migrated by an Expo SDK bump and never noticed. On Expo the source of truth is the newArchEnabled flag in app.json: it has defaulted to true since SDK 52, and on SDK 55+ it's forced on and can't be disabled. On bare React Native, the New Architecture is the only architecture from 0.82 onward. For a definitive answer at runtime, log the two globals below on a development build — both are non-null only when Fabric and TurboModules are actually active. (They're undefined in Expo Go on old SDKs and in the Chrome debugger, so test on a real dev build.)

App.tsx — is the New Architecture actually active?
// Drop this near the top of App.tsx and read the Metro logs on a dev build.
// On the New Architecture, both globals are non-null.
console.log("Fabric renderer:", (global as any).nativeFabricUIManager != null);
console.log("TurboModules:   ", (global as any).__turboModuleProxy != null);

// On Expo you can also just check app.json:
//   "newArchEnabled": true    // default since SDK 52, forced on in SDK 55+

What actually breaks — in order of how often it bites

For a typical app, the breakage is not in your screens — it's at the native boundary. In rough order of how often I see it:

1. Unmaintained native libraries. Any package with native iOS/Android code that hasn't shipped a New Architecture-compatible release is the number-one source of pain. Reflection-heavy or Bridge-assuming libraries either warn loudly or silently render nothing. Check every native dependency against reactnative.directory, which flags New Architecture support per package.

2. Custom native view managers. The interop layer that ships with React Native shims many legacy native modules and even many legacy view components so they keep working unchanged — that's what saves most apps. But complex custom UI components (especially ones that reached into the view hierarchy) are the ones most likely to need a real Fabric port.

3. Deprecated JS APIs. setNativeProps is discouraged and unreliable under Fabric — move those imperative updates to Reanimated or state. Direct manipulation via findNodeHandle, and anything that assumed a synchronous, Paper-style layout pass, can misbehave. UIManager.dispatchViewManagerCommand-style direct calls need the New Architecture equivalents.

4. Startup-order assumptions. Because TurboModules load lazily, code that assumed a native module was fully initialized at app launch can hit it before it exists. Touch the module explicitly where you need it rather than relying on eager init.

Migrating your own native modules and views

If you maintain native code, this is the real work. Under the New Architecture you describe the native interface as a TypeScript spec whose filename starts with Native, and Codegen generates the strongly-typed bindings at build time — you no longer hand-write the bridging glue, and a type mismatch fails the build instead of crashing a user. The payoff beyond safety: methods can be synchronous now, because there's no Bridge round-trip to marshal. Here's the shape of a TurboModule spec.

NativeDeviceInfo.ts — a Codegen spec (filename must start with "Native")
import type { TurboModule } from "react-native";
import { TurboModuleRegistry } from "react-native";

export interface Spec extends TurboModule {
  // Synchronous is now allowed — no async Bridge hop required.
  getDeviceName(): string;
  // Async still works for genuinely async work.
  getBatteryLevel(): Promise<number>;
}

// Codegen reads the Spec above and generates the C++/Java/ObjC bindings.
export default TurboModuleRegistry.getEnforcing<Spec>("DeviceInfo");

The migration path, step by step

1 · Upgraderecent RN / Expo SDK 2 · Enable + rebuildnewArch flag · native build 3 · Run + auditiOS + Android · check libs 4 · Profile + shipcompare, then release Broken lib? update it · lean on the interop layer· Codegen a spec for your own native code loop until clean

Do it in this order and the loop stays short. First, upgrade to a recent React Native or Expo SDK on the OLD architecture and get that stable — never change architecture and version in the same jump, or you won't know which one broke you. On Expo, moving to SDK 54 is a good staging point because it's the last version that still lets you toggle the flag. Second, enable the New Architecture and do a full native rebuild — this is not a JavaScript-only change, so Expo Go on an old SDK won't show it; you need a development build (or SDK 55+, where it's already on). Third, run on both iOS and Android and audit every native library against reactnative.directory; watch for red boxes, missing views, and warnings. Fourth, when something breaks, work the fix loop: update the library, lean on the interop layer for legacy modules, or Codegen a spec for your own native code — then re-run. Only once it's clean do you profile against the old build and ship.

How to verify nothing regressed

Migrating without a before-and-after measurement is how a "faster architecture" ships slower. Capture a baseline on the old build first: cold start time, JS bundle parse, a scroll-heavy screen's frame rate, and memory on your worst screen. Then compare on the New Architecture build. The wins are real but targeted — lighter startup from lazy TurboModules, smoother frames where you were previously bottlenecked on the Bridge (long lists, gesture-driven animation, frequent native calls) — not a blanket speedup on everything. Test on a low-end Android device, not just a flagship or the simulator, because that's where Bridge overhead used to hurt most and where a broken native view will be most obvious. And keep the old build installable for a release cycle so you can A/B against real crash and ANR rates before you delete the escape hatch.

When to hire senior help

Bring in senior React Native help when facing a New Architecture or major version migration, persistent performance regressions, or a first store launch, since these are the phases where inexperienced teams lose the most months. A short senior architecture audit early in the project is consistently cheaper than a rescue or rewrite later. If your stack includes React Native + Python + AI, a senior engineer who owns the full product beats coordinating multiple juniors.

Bottom line

Dhairya Senjaliya ships Mobile — React Native Development projects worldwide — book a scoping call to discuss your specific situation.

Common pitfalls to avoid

  • Staying multiple versions behind on React Native, then facing a compound upgrade to the New Architecture because popular libraries have dropped old-architecture support
  • Treating React Native as write-once-run-anywhere and only QA-testing on iOS, shipping Android builds with broken back-button handling, keyboard behavior, and gesture bugs
  • Pulling in unmaintained third-party native modules without checking TurboModule and Fabric compatibility, which later blocks the New Architecture migration
  • Launching without crash and performance monitoring wired in, so the team only discovers jank and crash clusters from one-star reviews instead of telemetry

Frequently asked questions

Do I actually have to migrate to the New Architecture?

If you want ongoing fixes and new features, yes. The legacy architecture was frozen in June 2025 — it receives no new features or bug fixes — and Expo SDK 55 and later have no option to disable the New Architecture. You can stay on SDK 54 or an older React Native for a while, but you're then pinned to a frozen platform, so the practical question is when you migrate, not whether.

Will my app break the moment I turn it on?

Usually not much. Pure-JavaScript apps often run unchanged, and React Native ships an interop layer that shims many legacy native modules and components so they keep working. The breakage concentrates at the native boundary: unmaintained native libraries, complex custom view managers, and a few deprecated JS APIs like setNativeProps and direct findNodeHandle manipulation. Audit your native dependencies against reactnative.directory before you start and you'll know most of your risk up front.

How long does a New Architecture migration take?

It scales with your native surface area, not your screen count. An Expo app with only well-maintained community libraries can be a same-day SDK bump plus a test pass. An app with several custom native modules, custom UI components, or an unmaintained critical dependency is a multi-week project because each of those needs a Codegen port, a replacement, or an upstream fix. The honest estimate comes from counting your native dependencies and how many still lack New Architecture support.

Is migrating easier on Expo or bare React Native?

Expo is generally easier: an SDK upgrade pulls New-Architecture-ready versions of all the Expo modules together, and from SDK 55 the New Architecture is simply on. Bare React Native gives you more control but you own every native dependency bump and native build change yourself. Either way, reactnative.directory is the tool for checking third-party library support before you commit.

Do I get an automatic performance win from migrating?

You get targeted wins, not a blanket speedup. Removing the serialized Bridge helps most where it used to hurt: cold start (TurboModules load lazily), long lists, gesture-driven animation, and code that makes frequent native calls. Screens that were never Bridge-bound won't feel different. Always measure a real before-and-after on a low-end device rather than assuming the new architecture is faster everywhere.

Is React Native still a good technology bet in 2026?

Yes for teams with JavaScript or React skills; the New Architecture has been the default since version 0.76 in late 2024, and the framework is used in production by Meta, Microsoft, Shopify, and Amazon. In the latest State of React Native survey, 88% of developers said the framework is heading in a positive direction.

Can a React Native app feel as fast as a fully native app?

For most business, e-commerce, and content apps, yes; Shopify runs its entire app portfolio on React Native with sub-500ms P75 screen loads and over 99.9% crash-free sessions. Workloads like heavy 3D, AR, or real-time audio processing still warrant native modules or fully native builds.

How much code is actually shared between iOS and Android?

Production teams commonly report 85 to 95%+ shared code; published examples include Instagram at 85 to 99% and Shopify at roughly 86%. The remainder is platform-specific work such as payments, widgets, and deep OS integrations.

Bottom line: Dhairya Senjaliya ships Mobile — React Native Development projects worldwide. Book a scoping call at https://dhairyasenjaliya.com/#book-call.

Sources

Related guides

Keep up with new guides

New deep-dive guides on React Native, Python, and AI ship regularly. Subscribe via RSS or follow on LinkedIn.

Want help implementing this?

30-minute scoping call · Clear milestones · Senior engineer ownership