React Native New Architecture
React Native lets you build iOS and Android apps with React and JavaScript, rendering real native views rather than a web view. How JavaScript communicates with native code has changed fundamentally. The legacy bridge, which serialized every message as JSON and sent it asynchronously, was replaced by the New Architecture: JSI for direct calls between JavaScript and C++, the Fabric renderer, TurboModules, and Codegen for type-safe native interfaces.
The New Architecture has been the default since React Native 0.76, and newer releases remove the legacy architecture entirely. It enables synchronous native calls, React 18+ concurrent features, faster startup, and better interop, and it changes how native modules and libraries are written.
TL;DR
- React Native runs your JS on a JavaScript thread, and renders native UI on the main (UI) thread, with layout computed by Yoga.
- The legacy bridge batched asynchronous JSON messages, causing serialization overhead and no synchronous access.
- JSI (JavaScript Interface) lets JS hold references to C++ objects and call native methods directly, even synchronously.
- Fabric is the new renderer: a C++ shadow tree shared across platforms, supporting concurrent React features.
- TurboModules are lazily loaded native modules built on JSI, with interfaces generated by Codegen from typed specs.
- Hermes is the default JS engine: bytecode precompilation for faster startup and lower memory use.
Quick Example
A TurboModule spec in TypeScript, from which Codegen generates native interfaces:
Codegen reads the spec at build time and generates the C++, Objective-C, and Java/Kotlin scaffolding that native code implements, so JS and native types can't drift apart.
Core Concepts
Threads
Keeping the JS thread free matters: long JavaScript tasks delay responses to touches and updates, which is visible as jank. See React Native performance.
The Legacy Bridge
Before the New Architecture, JS and native communicated by serializing messages to JSON and passing them asynchronously in batches across the bridge. Limitations:
- Serialization overhead for every call and every view update.
- No synchronous calls, which caused awkward workarounds for things like measuring layout.
- All native modules initialized at startup, slowing launch.
- Untyped boundaries, so mismatches surfaced at runtime.
JSI: JavaScript Interface
JSI is a C++ API that lets the JavaScript engine hold references to host objects (C++ objects exposed to JS) and invoke their methods directly. There's no JSON serialization and no mandatory async queue. It enables:
- Synchronous native calls when appropriate (reading device values, measuring).
- High-performance libraries (Reanimated worklets, MMKV storage, Skia rendering, VisionCamera frame processors) that share memory with native code.
- Engine independence: JSI abstracts over Hermes, JavaScriptCore, and others.
Fabric Renderer
Fabric reimplements rendering in cross-platform C++:
- React commits produce an immutable shadow tree in C++, laid out with Yoga, then mounted as native views.
- It supports concurrent React: transitions, Suspense, and automatic batching, with interruptible rendering.
- It enables synchronous layout reads and better interop with native views.
- The shared C++ core means more consistent behavior between iOS and Android.
TurboModules and Codegen
- TurboModules replace legacy native modules. They're built on JSI, and lazily loaded on first use, improving startup.
- Codegen generates native interfaces from TypeScript or Flow specs, for both TurboModules and Fabric components, so the boundary is typed and checked at build time.
- Fabric native components use the same spec-driven approach for custom native UI.
See React Native native modules.
Bridgeless Mode
With the New Architecture fully enabled, React Native runs bridgeless: the legacy bridge isn't initialized at all. An interop layer lets many legacy modules and components keep working during migration, but libraries should adopt TurboModules and Fabric for full support.
Hermes
Hermes is a JS engine built for React Native: it compiles JavaScript to bytecode at build time, so apps skip parsing at startup, and it's tuned for low memory and fast time-to-interactive on mobile. It's the default engine, supports modern JavaScript, and integrates with Chrome DevTools-style debugging via React Native DevTools.
What It Means for Your App
- New projects (including Expo SDKs) use the New Architecture by default.
- Existing apps: upgrade React Native (the Upgrade Helper diffs templates), check library compatibility (React Native Directory lists New Architecture support), and test thoroughly, especially with native modules, custom views, and animation libraries.
- Library authors: provide TurboModule and Fabric implementations with Codegen specs.
create-react-native-libraryand Expo Modules scaffold compatible packages.
Best Practices
Use Expo or the Community CLI Templates
Current templates configure Hermes, the New Architecture, and build tooling correctly. Expo's managed workflow and prebuild (Continuous Native Generation) keep native projects in sync with configuration.
Check Library Compatibility Before Upgrading
Most popular libraries support the New Architecture. For those that don't, look for maintained alternatives, or rely on the interop layer temporarily, testing carefully.
Prefer Typed Native Interfaces
Write Codegen specs (or Expo Modules) for native functionality instead of ad hoc bridging. Types catch mismatches at build time.
Don't Overuse Synchronous Native Calls
JSI makes sync calls possible, but blocking the JS thread with slow native work causes jank. Keep synchronous calls fast, and use async (Promises) for I/O and heavy computation.
Common Mistakes
Assuming the Bridge Still Exists
Code relying on bridge internals (NativeModules for new modules, or bridge references in native code) breaks in bridgeless mode. Use TurboModule APIs.
Upgrading Without Auditing Native Dependencies
An unmaintained library using legacy view managers or old bridge APIs can crash or misrender under Fabric. Audit dependencies before bumping versions.
Heavy Work on the JS Thread
The New Architecture speeds up communication, but long JavaScript tasks (big JSON parsing, large list computations) still block interactions. Offload, chunk, or move work to native or worklets.
FAQ
What is the React Native New Architecture?
A rewrite of React Native's core, made up of JSI (direct JS-to-C++ interaction), the Fabric renderer, TurboModules, and Codegen, replacing the asynchronous JSON bridge. It improves performance and startup, enables concurrent React features, and provides type-safe native interfaces. It's the default since React Native 0.76.
Is the bridge completely gone?
In bridgeless mode, which is the default with the New Architecture, the legacy bridge isn't initialized. An interop layer supports many legacy modules and components during the transition, and later releases have been removing the legacy architecture code paths entirely.
What does JSI enable?
Direct references between JavaScript and C++ objects, so native functions can be called without serialization, including synchronously. It powers high-performance libraries for animation, storage, graphics, and camera processing, and it makes React Native independent of any single JS engine.
Do I need to rewrite my app for the New Architecture?
Usually not for app-level JavaScript and React code. The work is mainly upgrading React Native, ensuring dependencies are compatible, and migrating any custom native modules or components to TurboModules and Fabric.
Related Topics
- React Native — The framework overview
- React Native Native Modules — Writing TurboModules and native components
- React Native Performance — Keeping threads responsive
- Expo — The recommended framework for React Native apps
- React — The UI library React Native builds on
- Mobile Development — Cross-platform and native approaches