DEV Community

Cover image for React Native New Architecture in 2026: What Developers Need to Know
Lucas Martin
Lucas Martin

Posted on

React Native New Architecture in 2026: What Developers Need to Know

For years, "should we enable the New Architecture?" was a real question in React Native projects. In 2026 it isn't. The New Architecture is the only architecture React Native runs, the legacy code is being deleted release by release, and the JavaScript engine underneath it has been upgraded too.

If you're starting an app, you get all of this by default. If you're maintaining one that's a few versions behind, the gap is getting harder to cross the longer you wait. This post covers what the New Architecture actually is, how we got here, what it changes in your day-to-day code, and a practical checklist for upgrading.

What "the New Architecture" actually means

It's four pieces that replaced the old asynchronous bridge:

Piece What it replaced What it does
JSI (JavaScript Interface) The JSON-serialized bridge Lets JavaScript hold references to C++ objects and call them directly, without serializing messages
Fabric The old UI manager The new renderer: builds the UI tree in C++, supports synchronous layout and React's concurrent features
TurboModules Legacy native modules Native modules loaded lazily and called through JSI, synchronously when the method is sync
Codegen Hand-written glue code Generates the typed C++ interface between your TypeScript specs and native code at build time

Together they make React Native bridgeless: there's no message queue between JavaScript and native any more. Calls go straight through JSI.

The practical effects you'll notice:

  • Layout can be measured synchronously. useLayoutEffect behaves like it does on the web, so tooltips and popovers no longer flash in the wrong position for a frame.
  • Concurrent React works. Features like startTransition and Suspense behave as they do in React DOM.
  • Native modules start lazily, which helps startup time in apps with many modules.

How we got here

Release What changed
0.76 (2024) New Architecture enabled by default for new projects
0.82 New Architecture becomes the only runtime option; the opt-out flags are ignored
0.83 Experimental flag to strip legacy architecture code on iOS
0.84 (Feb 2026) Hermes V1 becomes the default engine; legacy iOS code removed by default; precompiled iOS binaries by default
0.86 (Jun 2026) More legacy APIs deprecated as part of the removal; repo moves to the react GitHub organization

A few details from the official release notes are worth knowing.

Hermes V1 is the default as of 0.84. If you were already on Hermes, which has been the default since 0.70, you get V1 automatically with no configuration changes.

Legacy code is actually being deleted, not just disabled. 0.84 continued removing Legacy Architecture code from both iOS and Android, building on 0.82 making the New Architecture the only runtime. On Android that release removed a list of old bridge classes outright.

The compatibility shim is still there. The release notes are explicit that apps already on the New Architecture shouldn't break, because the Interop Layer code required for compatibility remains in place. That's what lets many older libraries keep working, for now.

iOS builds got faster. 0.84 ships precompiled iOS binaries by default, which the team says significantly reduces build times. They're downloaded automatically during pod install.

0.86 kept the momentum, quietly. It has no user-facing breaking changes, deprecates ViewUtil.getUIManagerType as part of the legacy removal, and moves 0.83 to unsupported.

What this changes in your code

For most app code written in plain React and TypeScript, almost nothing. The differences show up at the edges.

1. Native module errors are synchronous now (for sync methods)

With the bridge, a native exception often got swallowed somewhere in the queue. With TurboModules, a synchronous native method that throws unwinds straight into your JavaScript call site. Wrap sync calls that depend on user input or device state:

function readSetting(key: string) {
  try {
    return MySettingsModule.getSync(key);   // sync TurboModule method
  } catch (e) {
    console.warn('Setting unavailable', key, e);
    return null;
  }
}
Enter fullscreen mode Exit fullscreen mode

Async methods still return promises, so existing await and .catch() handling keeps working.

2. Codegen mismatches fail loudly

If your TypeScript spec says a prop is a string and the native implementation reads it as a number, you no longer get a silent no-op. You get a native crash at render. The fix is usually to regenerate and rebuild, but it's worth knowing that a hard crash on first render of a custom native component often points here.

3. Old timing hacks can now cause bugs

Code that wrapped layout reads in setTimeout(…, 0) or requestAnimationFrame to wait for the bridge often isn't needed any more, and occasionally causes a visible flicker now that layout is synchronous. When you touch that code, try the straightforward version first.

4. Your debugger changed

React Native DevTools is the debugger: press j in the Metro terminal and a Chrome DevTools-based window attaches to Hermes on your device. Remote JS debugging (running your code in Chrome's V8) is gone, which also removes a whole class of "works only when the debugger is attached" bugs. If your Metro terminal went quiet after an upgrade, your console.log output moved to the DevTools console.

Libraries: the real migration work

Your own code is rarely the blocker. Dependencies are.

Check every native dependency against the React Native Directory (reactnative.directory), which marks New Architecture support for each library. For each one, you'll land in one of three buckets:

  1. Supports the New Architecture. Upgrade to the current version.
  2. Works through the Interop Layer. It runs, but it's living on borrowed time as legacy code is removed. Look for an alternative or an upstream fix.
  3. Unmaintained, doesn't work. Replace it. In 2026 there's almost always a maintained alternative, often an Expo module.

Common categories to check first: navigation, gesture and animation libraries, maps, camera, video, in-app purchases, and anything with a custom native UI component.

An upgrade checklist

If you're on a version older than 0.82, this is the order that usually goes smoothest:

  • [ ] Audit native dependencies against the React Native Directory and upgrade or replace the ones without New Architecture support
  • [ ] Upgrade React Native in steps, using the community Upgrade Helper to diff native files between versions, rather than jumping several majors at once
  • [ ] If you use Expo, upgrade one SDK at a time and run npx expo-doctor and npx expo install --check after each step
  • [ ] Check your Node version before upgrading; 0.84 requires Node.js 22.11 or later
  • [ ] Rebuild native projects from scratch (npx expo prebuild --clean, or clean Pods and Gradle caches) instead of trusting cached builds
  • [ ] Test custom native modules and components first; that's where Codegen and threading issues show up
  • [ ] Remove setTimeout layout workarounds you added for the bridge, and retest those screens
  • [ ] Wrap sync TurboModule calls that can fail in try/catch
  • [ ] Run release builds on real devices, not just debug builds in a simulator; many New Architecture issues only appear in release mode
  • [ ] Watch crash reporting closely for the first release after the upgrade, with source maps uploaded so stack traces are readable

Should you upgrade now?

If you're on 0.82 or later, you're already on the New Architecture. The remaining upgrades are mostly smooth, and staying current keeps you inside the supported window: each release moves an older one to unsupported.

If you're still on an older version, the honest answer is that it doesn't get easier. Every release removes more legacy code, and every month more libraries drop support for the old architecture. Start with the dependency audit. That alone tells you whether the upgrade is a week of work or a quarter.


Shipping an RN app in 2026 means shipping on Fabric and bridgeless by default. If you want to see what that generated code looks like without wiring any of it up yourself, RapidNative generates RN + Expo projects targeting the current stack from a prompt.

If you've migrated a real app to 0.82, I'd be curious what broke for you. Drop it in the comments.

Top comments (0)