React Native New Architecture Explained
Deep dive into React Native new architecture with Fabric, TurboModules, and the JSI. Understand how it improves performance and developer experience.
Published on • August 13, 2026
AI Assistant

React Native has undergone a significant architectural overhaul that promises to revolutionize how we build cross-platform mobile applications. The new architecture replaces the aging bridge-based system with a modern, high-performance foundation built on JavaScript Interface (JSI), Fabric, and TurboModules. This guide breaks down everything you need to know to understand, adopt, and migrate to this new paradigm.
Introduction: Why the Change Matters
For years, React Native relied on an asynchronous bridge to communicate between JavaScript and native code. While this approach worked, it introduced performance bottlenecks, limited concurrency, and made debugging challenging. The new architecture addresses these fundamental issues by:
- Eliminating the asynchronous bridge bottleneck
- Introducing true concurrency with Fabric
- Providing synchronous access to native modules via JSI
- Enabling better type safety with Codegen
If you’re building production React Native apps, understanding these changes isn’t optional—it’s essential for maintaining performance and developer experience.
Prerequisites
Before diving into the new architecture, ensure you have:
- React Native 0.68+ (new architecture is opt-in)
- Node.js 16+ and npm/yarn
- Android Studio (for Android development)
- Xcode 14+ (for iOS development)
- Basic understanding of React Native components and hooks
- Familiarity with native mobile development concepts
Old vs New Architecture: A Paradigm Shift
The Old Bridge Architecture
The legacy architecture used a JSON message queue over an asynchronous bridge:
JavaScript Thread → Bridge (JSON serialization) → Native Thread
This had several limitations:
- Asynchronous only: All communication was async, even when sync was needed
- Single point of serialization: JSON serialization created performance overhead
- No shared memory: Data copying between threads was expensive
- Limited concurrency: JavaScript and native couldn’t run concurrently
The New Architecture
The new system introduces three core components that work together:
JavaScript (JSI) → Fabric (Renderer) → Native UI
↘ TurboModules (Native Logic)
Key improvements:
- Synchronous communication: JSI enables direct native calls
- Shared memory: Data can be shared without copying
- Concurrent rendering: Fabric supports concurrent features
- Lazy loading: Modules load only when needed
Fabric: The New Renderer
Fabric is React Native’s new rendering system that replaces the old UIManager. It introduces several groundbreaking features:
Key Features of Fabric
- Synchronous Layout: Immediate layout calculations without bridge delays
- Concurrent Rendering: Supports React 18’s concurrent features
- Better TypeScript Support: Native type definitions
- Shared C++ Core: Cross-platform consistency
Fabric Component Example
Here’s how a custom Fabric component looks:
import { requireNativeComponent, StyleSheet } from 'react-native';
interface CustomViewProps {
color: string;
borderRadius: number;
children: React.ReactNode;
}
const CustomView = requireNativeComponent<CustomViewProps>('CustomView');
export function Card({ color, borderRadius, children }: CustomViewProps) {
return (
<CustomView
style={[styles.container, { backgroundColor: color, borderRadius }]}
>
{children}
</CustomView>
);
}
const styles = StyleSheet.create({
container: {
padding: 16,
margin: 8,
},
});
TurboModules: Native Modules Reimagined
TurboModules replace the old NativeModules system with a more efficient, type-safe approach.
Advantages Over Old System
- Lazy Loading: Modules load on-demand, reducing startup time
- Type Safety: Full TypeScript support with Codegen
- Synchronous Access: Direct native method calls via JSI
- Better Memory Management: Efficient object lifecycle handling
Creating a TurboModule
// NativeCalculator.ts
import { TurboModuleRegistry, TurboModule } from 'react-native';
export interface Spec extends TurboModule {
add(a: number, b: number): Promise<number>;
multiply(a: number, b: number): number;
}
export default TurboModuleRegistry.get<Spec>('NativeCalculator');
Native Implementation (iOS)
// NativeCalculator.mm
@implementation NativeCalculator
RCT_EXPORT_MODULE()
- (NSNumber *)multiply:(NSNumber *)a b:(NSNumber *)b {
return @([a doubleValue] * [b doubleValue]);
}
- (void)add:(double)a b:(double)b resolve:(RCTPromiseResolveBlock)resolve {
resolve(@(a + b));
}
- (std::shared_ptr<TurboModule>)getTurboModule:
(const std::shared_ptr<facebook::react::TurboModule::InitParams &)params {
return std::make_shared<facebook::react::NativeCalculatorJSI>(params);
}
@end
JavaScript Interface (JSI): The Bridge Replacement
JSI is the low-level C++ interface that enables synchronous communication between JavaScript and native code.
How JSI Works
Instead of serializing JSON messages, JSI:
- Creates a shared C++ runtime
- Allows direct function calls from JS to native
- Enables shared memory access
- Supports synchronous operations
JSI Module Example
// NativeModule.cpp
#include <jsi/jsi.h>
#include <ReactCommon/TurboModuleUtils.h>
using namespace facebook::react;
void installJSIModules(jsi::Runtime &runtime) {
auto addFn = jsi::Function::createFromHostFunction(
runtime,
jsi::PropNameID::forAscii(runtime, "add"),
2,
[](jsi::Runtime &runtime,
const jsi::Value &thisValue,
const jsi::Value *args,
size_t count) -> jsi::Value {
double a = args[0].getNumber();
double b = args[1].getNumber();
return jsi::Value(a + b);
});
runtime.global().setProperty(runtime, "nativeAdd", std::move(addFn));
}
Codegen: Type-Safe Native Integration
Codegen automatically generates type-safe interfaces between JavaScript and native code, eliminating manual type definitions.
Codegen Configuration
// package.json
{
"name": "my-react-native-app",
"react-native": {
"codegenConfig": {
"name": "MyAppSpecs",
"type": "modules",
"jsSrcsDir": "src/specs",
"android": {
"javaPackageName": "com.myapp"
}
}
}
}
Codegen Specification
// src/specs/NativeStorage.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>;
removeItem(key: string): Promise<void>;
clear(): Promise<void>;
}
export default TurboModuleRegistry.getEnforcing<Spec>('NativeStorage');
Migration Steps
Step 1: Enable New Architecture
# For iOS
RCT_NEW_ARCH_ENABLED=1 pod install
# For Android (in gradle.properties)
newArchEnabled=true
Step 2: Update Dependencies
npm install react-native@latest
cd ios && pod install
cd android && ./gradlew clean
Step 3: Migrate Native Modules
Convert existing NativeModules to TurboModules:
// Before (Old Architecture)
import { NativeModules } from 'react-native';
const { Calculator } = NativeModules;
// After (New Architecture)
import NativeCalculator from './NativeCalculator';
const Calculator = NativeCalculator;
Step 4: Update Fabric Components
// Before
const CustomView = requireNativeComponent('CustomView');
// After (with Codegen)
import type { CustomViewProps } from './NativeCustomView';
import codegenNativeComponent from 'react-native/Libraries/Utilities/codegenNativeComponent';
const CustomView = codegenNativeComponent<CustomViewProps>('CustomView');
Performance Improvements
Startup Time
- Lazy Loading: TurboModules reduce app startup time by 30-50%
- Reduced Bridge Traffic: Direct JSI calls eliminate serialization overhead
Memory Usage
- Shared Memory: JSI enables zero-copy data sharing
- Better Garbage Collection: Improved object lifecycle management
Rendering Performance
- Synchronous Layout: Fabric enables immediate layout calculations
- Concurrent Rendering: Supports React 18’s concurrent features
- Reduced Jank: Eliminates bridge-induced frame drops
Real-World Benchmarks
- Startup Time: 40% faster in production apps
- Memory Usage: 20% reduction in peak memory
- Frame Rate: Consistent 60fps in complex UIs
- Bundle Size: 15% smaller due to optimized code generation
Common Pitfalls and Solutions
1. Type Mismatches
Problem: Codegen type errors Solution: Ensure TypeScript types match native implementations exactly
2. Module Loading Order
Problem: Modules not available at startup Solution: Use lazy loading patterns and handle async initialization
3. iOS Build Issues
Problem: Pod install failures
Solution: Clean pods and rebuild: cd ios && pod deinstall && pod install
Best Practices
- Start with Expo: Use Expo SDK 49+ for easier migration
- Incremental Migration: Migrate one module at a time
- Test Thoroughly: Both architectures may coexist during migration
- Monitor Performance: Use Flipper and React DevTools to track improvements
Conclusion & Next Steps
The React Native new architecture represents a fundamental shift toward modern mobile development. With Fabric, TurboModules, and JSI, you get:
- Better Performance: Faster startup, smoother animations
- Improved Developer Experience: Type safety, better debugging
- Future-Proof: Support for React 18+ features
- Cross-Platform Consistency: Shared C++ core ensures parity
Next Steps
- Evaluate Your App: Check compatibility with new architecture
- Start Small: Migrate one feature or module first
- Update Dependencies: Ensure all libraries support new architecture
- Monitor Metrics: Track performance improvements
- Contribute: Help improve the ecosystem
The migration might seem daunting, but the performance benefits and developer experience improvements make it worthwhile. Start your migration journey today and experience the future of React Native development.
Have questions about migrating your React Native app? Drop them in the comments below or reach out on Twitter. For more mobile development insights, subscribe to our newsletter.