Skip to main content
React Native’s modern architecture represents a complete reimagining of how JavaScript and native platforms communicate. This new architecture provides better performance, type safety, and alignment with modern JavaScript standards.

Core Architecture Components

React Native’s architecture consists of several interconnected systems that work together to render JavaScript-defined UIs on native platforms:

JavaScript Interface (JSI)

JSI is the foundational layer that enables direct communication between JavaScript and native code. Unlike the legacy bridge that used asynchronous JSON message passing, JSI provides:
  • Synchronous method invocation - Native methods can be called directly from JavaScript
  • Direct memory access - JavaScript can hold references to C++ objects
  • Type safety - Strong typing across the JavaScript/native boundary
  • Multiple JavaScript engines - Not tied to JavaScriptCore, supports Hermes and V8
JSI is defined in ReactCommon/jsi/jsi/jsi.h and provides the jsi::Runtime interface that JavaScript engines must implement.

Fabric Renderer

Fabric is the new rendering system that manages the UI layer. Key improvements include:
  • Synchronous layout - Layout can be computed synchronously on any thread
  • Type-safe view updates - Strongly typed props and state
  • Priority-based rendering - Support for concurrent React features
  • Improved shadow tree - Immutable shadow nodes with efficient diffing
The renderer is implemented in ReactCommon/react/renderer/ and includes subsystems for:
  • Component registry and descriptors
  • Shadow tree management
  • Mounting and diffing
  • Event handling

TurboModules

TurboModules replace legacy native modules with a lazy-loading, type-safe system:
  • Lazy initialization - Modules are only loaded when first accessed
  • Codegen integration - Type definitions automatically generate native interfaces
  • JSI-powered - Direct function calls without bridge serialization
  • Better performance - Eliminates JSON serialization overhead
TurboModules extend facebook::react::TurboModule defined in ReactCommon/react/nativemodule/core/.

Codegen

Codegen generates type-safe native interfaces from Flow or TypeScript specifications:
  • Single source of truth - Define APIs once in JavaScript
  • Compile-time validation - Type errors caught during build
  • Reduced boilerplate - Automatically generates native glue code
  • Cross-platform consistency - Same interface for iOS and Android
Codegen is implemented in packages/react-native-codegen/ and generates C++, Objective-C++, and Java/Kotlin code.

Threading Model

React Native uses a multi-threaded architecture for optimal performance:

JavaScript Thread

Executes your React components and business logic. This is where:
  • React renders and reconciles component trees
  • State updates are processed
  • Event handlers execute
  • Async operations are coordinated

UI Thread (Main Thread)

The native platform’s main thread handles:
  • Mounting views and applying mutations
  • Processing user input
  • Drawing and animation
  • Native module operations that require main thread

Background Threads

Various operations run on background threads:
  • Layout calculation - Yoga layout engine computes flexbox layouts
  • Image decoding - Image assets are decoded off the main thread
  • Network requests - HTTP operations run asynchronously
  • Native module work - TurboModules can specify thread requirements

RuntimeExecutor

The RuntimeExecutor provides safe access to the JavaScript runtime across threads. It’s defined as:
using RuntimeExecutor = std::function<void(
  std::function<void(jsi::Runtime &runtime)> &&callback
)>;
This ensures JavaScript runtime operations are serialized and thread-safe.

Data Flow

The architecture follows a unidirectional data flow:
  1. JavaScript Render - React components render based on props and state
  2. Shadow Tree Creation - Fabric creates immutable shadow nodes representing the UI
  3. Layout Calculation - Yoga computes layout on background thread
  4. Diffing - New shadow tree is diffed against the previous version
  5. Mutation List - Changes are collected into a mounting transaction
  6. UI Update - Mutations are applied to native views on the UI thread

Event Handling Flow

  1. Native Event - User interaction occurs on the UI thread
  2. Event Emission - Event is dispatched through the EventEmitter
  3. Event Beat - Events are batched and synchronized with the event loop
  4. JavaScript Callback - Event handler executes on JavaScript thread
  5. State Update - Handler may trigger React state changes
  6. Re-render - Process repeats with updated state

Runtime Architecture

The RuntimeScheduler implements the event loop aligned with web specifications:
  • Task Queue - Manages execution of JavaScript tasks with priorities
  • Microtask Queue - Executes promise callbacks and queueMicrotask calls
  • Rendering Updates - Flushes UI updates atomically at end of event loop tick
  • Long Task Monitoring - Integrates with PerformanceObserver for monitoring
This provides predictable UI update semantics where each event loop iteration represents an atomic UI update.

Memory Management

Shadow Nodes

Shadow nodes are immutable and use shared pointers for memory management:
  • Copy-on-write - Mutations create new nodes sharing unchanged subtrees
  • Reference counting - Automatic memory management via std::shared_ptr
  • Layout cache - Computed layouts are cached on shadow nodes

Runtime Shadow Node Reference Updates (RSNRU)

RSNRU optimizes memory and performance by updating references to shadow nodes in the React renderer:
  • Maintains references to the latest shadow node revisions
  • Improves layout cache hit rates
  • Keeps native state fresh across commits

JSI Object Lifecycle

JSI objects follow specific lifetime rules:
  • JavaScript values must be used on the correct thread
  • jsi::Value objects are move-only for safety
  • Host objects are reference-counted and can be shared

Build System

The new architecture requires coordinated builds across platforms:

C++ Core

  • CMake (Android) - Builds native C++ libraries
  • CocoaPods (iOS) - Integrates C++ code into iOS apps
  • Shared code - Same C++ implementation for both platforms

Codegen Integration

  • Build-time generation - Codegen runs during native build
  • Schema validation - Type definitions are validated
  • Platform-specific output - Generates appropriate native bindings

Migration from Legacy Architecture

The new architecture is the default in React Native 0.68+, but legacy bridge support remains for gradual migration.
Key differences from the legacy architecture:
AspectLegacy BridgeNew Architecture
CommunicationAsync JSON messagesSynchronous JSI calls
Type SafetyRuntime onlyCompile-time via Codegen
Module LoadingEager all modulesLazy TurboModules
RenderingAsync bridge callsSynchronous Fabric
ThreadingFixed bridge threadFlexible RuntimeExecutor
LayoutMain thread onlyAny thread with Fabric

Performance Characteristics

The new architecture delivers significant performance improvements:
  • Startup time - TurboModules reduce initialization overhead by 30-40%
  • Interaction latency - Synchronous JSI calls eliminate bridge delays
  • Memory usage - Lazy loading and efficient shadow tree reduce footprint
  • Frame rate - Priority-based scheduling prevents dropped frames
  • List performance - Efficient diffing and mounting improve ScrollView performance

Developer Experience

Type Safety

Codegen provides end-to-end type safety:
// Define once in TypeScript/Flow
export interface Spec extends TurboModule {
  readonly getConstants: () => {initialValue: number};
  getUser(id: string): Promise<User>;
}
Codegen generates native interfaces ensuring type consistency across the stack.

Debugging

The new architecture improves debugging:
  • Synchronous errors - Stack traces are more accurate
  • React DevTools - Full support for Fabric components
  • JSI debugging - Native debuggers can inspect JavaScript objects
  • Performance profiling - Better integration with native profilers

Web Alignment

The architecture increasingly aligns with web standards:
  • Event loop - Follows HTML specification event loop model
  • Promises and microtasks - Standard JavaScript async semantics
  • Web APIs - Support for MutationObserver, IntersectionObserver, etc.
  • Performance APIs - PerformanceObserver for monitoring
This alignment makes it easier to share code between React Native and web applications.

Next Steps

Fabric Renderer

Deep dive into the new rendering system

TurboModules

Learn about the native module system

JavaScript Interface

Understand JSI fundamentals

Codegen

Explore code generation

Build docs developers (and LLMs) love