Understanding the New React Native Architecture: Fabric, TurboModules, and How They Impact Enterprise Apps

React Native's New Architecture replaces the asynchronous, JSON-serializing bridge with a direct C++ interface between JavaScript and native code. It has four parts: JSI (the JavaScript Interface), the Fabric renderer, TurboModules, and bridgeless mode, which removes the legacy bridge from the runtime entirely. For enterprise apps, the practical effects are more predictable UI performance, type-safe native modules, support for concurrent React features, and a one-time migration cost that falls mostly on custom native code and third-party dependencies.
If you maintain a large React Native codebase, you have probably seen the warnings and changelog entries, and you may be wondering how urgent this is. This post explains what each piece does, why it matters at enterprise scale, and how we would approach a migration.
Why the Old Bridge Became a Problem
In the legacy architecture, JavaScript and native code ran in separate worlds and communicated through a bridge. Every call was serialized to JSON, queued, and processed asynchronously on the other side. This design was simple and portable, but it had structural limits:
- Serialization overhead. Large payloads, such as list data or image metadata, had to be encoded and decoded on every crossing.
- Asynchronous-only communication. JavaScript could not synchronously read a native value, which made things like measuring layout before paint awkward.
- Eager module initialization. Native modules were typically initialized at startup whether or not the user ever reached a screen that needed them.
- Weak type contracts. Nothing enforced that the JavaScript signature of a native module matched its Objective-C, Swift, Java, or Kotlin implementation. Mismatches surfaced at runtime.
For a small app, these costs were tolerable. For enterprise apps with dozens of native modules, heavy lists, and strict startup budgets, they became recurring sources of jank and hard-to-reproduce bugs.
The Building Blocks of the React Native New Architecture
JSI: The Foundation
JSI is a lightweight C++ API that lets JavaScript hold direct references to C++ host objects and call methods on them. No JSON, no queue. Everything else in the React Native New Architecture builds on JSI. It also decouples React Native from a specific JavaScript engine, which is part of what made Hermes a first-class default.
The Fabric Renderer
Fabric is the new rendering system. Its core is written in C++ and shared across iOS and Android, which reduces platform drift in layout and rendering behavior. Key characteristics of the Fabric architecture:
- Synchronous layout access.
useLayoutEffectcan read layout information and update before the frame is painted, eliminating the visible "jump" common with tooltips and popovers in the old renderer. - Concurrent React support. Features from React 18 and later, such as transitions, Suspense for data fetching, and automatic batching, depend on the renderer supporting interruptible rendering. Fabric does.
- Immutable shadow tree. The UI tree is represented as immutable data, which makes it safe to process across threads and to prioritize urgent updates.
TurboModules
TurboModules are the new native module system. They differ from legacy modules in three important ways:
- Lazy loading. A module is initialized the first time JavaScript accesses it, not at app launch.
- Direct invocation through JSI. Calls skip serialization, and synchronous methods are possible where appropriate.
- Typed contracts via Codegen. You write a TypeScript (or Flow) spec, and Codegen generates the native interface scaffolding. If the native side does not conform, the build fails.
Here is a minimal TurboModule spec:
// src/specs/NativeSecureStore.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
getItem(key: string): Promise<string | null>;
setItem(key: string, value: string): Promise<void>;
// Synchronous reads are possible, but use them sparingly.
hasKeySync(key: string): boolean;
}
export default TurboModuleRegistry.getEnforcing<Spec>('SecureStore');
And the corresponding Codegen configuration in package.json:
{
"codegenConfig": {
"name": "SecureStoreSpec",
"type": "modules",
"jsSrcsDir": "src/specs",
"android": {
"javaPackageName": "com.example.securestore"
}
}
}
For enterprise teams, the typed contract is often the most valuable part. It moves an entire category of integration bugs from production crash reports to compile time.
What Bridgeless Mode Actually Changes
Even with Fabric and TurboModules enabled, early versions of the New Architecture still initialized the legacy bridge for things like error handling, timers, and backward compatibility. Bridgeless mode removes that remaining dependency. The runtime starts without creating the bridge at all, and all communication flows through JSI.
Why this matters:
- Simpler runtime. There is one communication path instead of two, which makes behavior easier to reason about and debug.
- Less startup work. The bridge's initialization cost goes away.
- A clear end state. Bridgeless is where the platform is headed. Code that relies on bridge internals, such as accessing
RCTBridgedirectly in iOS modules, needs to be updated.
According to the React Native team, the New Architecture, including bridgeless mode, became the default in React Native 0.76, released in October 2024 (React Native blog: "New Architecture is here"). Subsequent releases have continued removing the ability to opt back into the legacy architecture, so check the release notes for the version you target. To soften the transition, React Native ships interop layers that let many legacy native modules and components run under the new system without immediate rewrites.
How the New Architecture Impacts Enterprise Apps
Performance You Can Reason About
We avoid promising specific speedups, because React Native performance depends heavily on the app. What the architecture does provide is the removal of known bottlenecks: no serialization on native calls, lazy module loading, and synchronous layout where it is needed. Teams should measure their own cold start, time to interactive, and frame drops before and after, using tools like the Hermes profiler, Android Studio Profiler, and Xcode Instruments.
Dependency Risk Becomes the Critical Path
In our experience, application code written in plain React rarely needs changes. The real work is in:
- Third-party libraries that have not been updated for Fabric or TurboModules. The React Native Directory indicates New Architecture support for many packages.
- In-house native modules, especially older ones written against bridge APIs.
- Custom native UI components, which need Fabric-compatible implementations or must rely on the interop layer.
Brownfield and Multi-Team Codebases
Many enterprise apps embed React Native inside existing native shells. Bridgeless mode changes how the React Native host is initialized, so brownfield integration code needs review. If several teams own different native modules, the migration needs a coordination plan, not just a version bump.
Long-Term Supportability
Staying on the legacy architecture is a shrinking option. New library releases increasingly target the New Architecture only. Deferring migration indefinitely means accumulating version debt, which is usually more expensive to unwind later.
A Practical React Native Migration Plan for the Enterprise
Here is the sequence we would recommend for a React Native migration in an enterprise setting:
Inventory dependencies. List every package with native code and check its New Architecture status. Flag anything unmaintained.
Upgrade React Native incrementally. Use the React Native Upgrade Helper and avoid jumping many minor versions at once.
Enable the New Architecture in a branch. On versions where it is still opt-in, this is a flag:
# android/gradle.properties newArchEnabled=true# iOS (on versions where the flag is still respected) cd ios && RCT_NEW_ARCH_ENABLED=1 bundle exec pod installRun your full test suite and manual regression passes, focusing on screens that use native modules, custom views, gestures, and animations.
Migrate in-house modules to TurboModule specs, starting with the most heavily used ones. Lean on the interop layer for the rest while you work through the backlog.
Roll out progressively. Use staged releases in the app stores and watch crash and performance telemetry closely.
If your team needs help planning or executing this, our engineering capabilities cover mobile platform modernization alongside cloud and backend work. The constraints also vary by sector, which is why we look at regulatory and device-fleet requirements across the industries we work in before recommending a rollout strategy.
Key Takeaways
- JSI is the foundation that replaces serialized bridge calls with direct C++ references.
- Fabric brings synchronous layout and concurrent React features to the UI layer.
- TurboModules add lazy loading and Codegen-enforced type safety to native modules.
- Bridgeless mode removes the legacy bridge entirely and is now the default runtime path.
- For enterprise mobile app development, the main migration cost is in native dependencies, not React components.
FAQ
What is bridgeless mode in React Native?
Bridgeless mode is the runtime configuration in which React Native starts and operates without initializing the legacy bridge. All communication between JavaScript and native code goes through JSI, Fabric, and TurboModules. It became the default alongside the New Architecture in React Native 0.76.
Do I have to rewrite my React components to adopt the New Architecture?
Usually not. Components written in standard React and React Native APIs generally work unchanged. The work concentrates on native modules, custom native UI components, and third-party libraries that depend on bridge internals.
Can legacy native modules still run under the New Architecture?
Many can, through the interop layers React Native provides for legacy modules and components. Treat this as a bridge for the transition, not a permanent solution, and plan to migrate critical modules to TurboModules with Codegen specs.
Will the New Architecture automatically make my app faster?
It removes structural bottlenecks such as JSON serialization and eager module initialization, but actual gains depend on your app. Measure startup time, frame rates, and interaction latency before and after migration rather than assuming a fixed improvement.
How should an enterprise team prioritize a React Native migration?
Start with a dependency audit, upgrade React Native in small increments, enable the New Architecture in a branch, and run thorough regression testing. Then migrate high-traffic native modules first and use staged rollouts with close monitoring of crash and performance data.


