Key Files to Understand React Native Architecture: A Developer's Guide to the Core Source
To understand React Native's architecture, examine packages/react-native/index.js for the public API façade, ReactNativeHost.java for the legacy bridge implementation, FabricUIManager.js for the new renderer pipeline, and ReactPackageTurboModuleManagerDelegate.java for TurboModules integration.
React Native's architecture has evolved from a bridge-based message queue to a modern JSI-driven system with Fabric and TurboModules. Whether you're debugging native module issues or contributing to the framework, navigating the facebook/react-native repository requires knowing which source files control the runtime, rendering, and interop layers. This guide maps the essential files that define how JavaScript communicates with native code in both legacy and new architecture modes.
The Entry Point: Mapping Public APIs to Native Implementations
All public components and APIs are lazily required from packages/react-native/index.js, making it the runtime façade for the whole framework. Studying its module.exports object reveals how React Native maps a JavaScript import (e.g., import {View} from 'react-native') to a native implementation.
The file uses lazy getters to load components on demand. For example, the View export demonstrates this pattern:
get View() {
return require('./Libraries/Components/View/View').default;
},
This indirection allows the framework to initialize heavy native dependencies only when accessed, reducing startup overhead in the JavaScript thread.
The Legacy Bridge: BatchedBridge and ReactNativeHost
Understanding the original JavaScript-to-native bridge is essential for debugging older codebases or migrating to the new architecture.
BatchedBridge.js
Located at packages/react-native/Libraries/BatchedBridge/BatchedBridge.js, this file implements the low-level message queue that serializes calls between JavaScript and native code. It marshals method invocations into batched JSON messages sent asynchronously across the bridge.
ReactNativeHost.java
On Android, packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactNativeHost.java builds and holds the ReactInstanceManager. This class wires the JS executor, the JavaScript-to-native message queue, and the set of native modules. While marked as deprecated in favor of the bridgeless architecture, it remains the definitive reference for how the legacy bridge initializes and manages the JavaScript runtime.
When you call NativeModules.ToastExample.show(), the invocation flows through BatchedBridge to ReactInstanceManager and finally to the native module implementation.
The New Architecture: Fabric Renderer and JSI
The modern React Native architecture replaces the asynchronous bridge with JavaScript Interface (JSI) synchronous calls and a C++ core renderer called Fabric.
FabricUIManager.js
packages/react-native/Libraries/ReactNative/FabricUIManager.js serves as the JavaScript proxy for the C++ Fabric UI manager (nativeFabricUIManager). It creates a proxy via createProxyWithCachedProperties that forwards calls such as createNode, measure, and dispatchCommand to the native side. When Fabric is enabled, all React component trees route through this file instead of the legacy UIManager.
Renderer Implementations
React Native ships two parallel renderer implementations:
ReactNativeRenderer-dev.jsandReactNativeRenderer-prod.js– The legacy renderer that communicates with the original UIManager through the bridge.ReactFabric-dev.jsandReactFabric-prod.js– The Fabric renderer that bypasses the bridge and talks directly tonativeFabricUIManagervia JSI.
The framework swaps these implementations based on the enableFabricRenderer feature flag.
ReactHost and Bridgeless Mode
When the enableBridgelessArchitecture flag is active, ReactNativeHost is replaced by ReactHost (generated at build time in newer versions). This class creates a ReactInstance that runs entirely on JSI without a message-queue bridge, eliminating the serialization overhead of the legacy system.
TurboModules: Direct Native Module Access
TurboModules allow JavaScript to hold references to native module objects and call methods synchronously without bridge marshaling.
ReactPackageTurboModuleManagerDelegate.java
packages/react-native/ReactAndroid/src/main/java/com/facebook/react/ReactPackageTurboModuleManagerDelegate.java registers native modules for the TurboModule system. It builds the module map and exposes getModule to the JSI runtime, allowing direct method invocation from JavaScript.
TurboModuleRegistry.js
On the JavaScript side, packages/react-native/Libraries/ReactNative/TurboModuleRegistry.js stores instantiated TurboModules. The getEnforcing method retrieves a native module by name, throwing if the implementation is missing.
import {TurboModuleRegistry} from 'react-native';
const ExampleTurbo = TurboModuleRegistry.getEnforcing('ExampleTurbo');
ExampleTurbo.doHeavyWork(42).then(result => {
console.log('Result from native:', result);
});
In this example, getEnforcing resolves to the native implementation built by ReactPackageTurboModuleManagerDelegate.java, bypassing BatchedBridge entirely.
Feature Flags: Controlling Architecture Modes
All switches that enable or disable parts of the new architecture are defined in packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js. This file contains boolean flags such as enableFabricRenderer, enableBridgelessArchitecture, and enableTurboModules that determine which code paths are active at runtime.
Reading this file clarifies which experimental features are available and how to toggle between legacy and modern architectures during development.
C++ Core and View Managers
For the complete picture of Fabric's rendering pipeline, examine packages/react-native/ReactCommon/react/renderer/components/view/ReactViewManager.cpp. This file demonstrates how Fabric nodes are backed by native C++ view managers that create and manipulate platform-native UI elements.
Additionally, packages/react-native/ReactCommon/React-runtime/ReactCommon/React-jsi/ReactJSIHost.cpp implements the JSI host for the bridgeless runtime, showing how the C++ layer exposes host objects to the JavaScript virtual machine.
Summary
packages/react-native/index.jsexposes the public API using lazy getters to defer native module initialization.BatchedBridge.jsandReactNativeHost.javaimplement the legacy asynchronous bridge between JavaScript and native code.FabricUIManager.jsandReactFabric-*.jsprovide the JavaScript interface to the modern Fabric renderer written in C++.ReactPackageTurboModuleManagerDelegate.javaandTurboModuleRegistry.jsenable direct JSI-based native module access without bridge overhead.ReactNativeFeatureFlags.jscentralizes configuration for enabling Fabric, TurboModules, and bridgeless architecture modes.
Frequently Asked Questions
What is the difference between ReactNativeHost and ReactHost?
ReactNativeHost is the legacy Android class that creates a ReactInstanceManager using the asynchronous bridge architecture. ReactHost is its modern replacement used when enableBridgelessArchitecture is true; it creates a ReactInstance that runs on JSI without a message queue, enabling synchronous native module calls and Fabric rendering.
How does Fabric differ from the legacy UIManager?
Fabric is React Native's new cross-platform rendering layer written in C++ that replaces the legacy UIManager. It uses the JavaScript Interface (JSI) to communicate synchronously between JavaScript and native code, eliminating the JSON serialization overhead of the bridge. Fabric is accessed via FabricUIManager.js on the JavaScript side, while the legacy UIManager used asynchronous batched messages through BatchedBridge.js.
What is JSI and how does it relate to TurboModules?
JSI (JavaScript Interface) is a lightweight C++ API that allows React Native to hold references to native objects and call methods synchronously. TurboModules use JSI to expose native modules directly to JavaScript without marshaling through the bridge, resulting in lower latency and type-safe method calls. The connection is managed by ReactPackageTurboModuleManagerDelegate.java on Android and equivalent C++ bindings on iOS.
Where can I find the flags to enable the new architecture?
All feature flags controlling the new architecture are defined in packages/react-native/src/private/featureflags/ReactNativeFeatureFlags.js. Look for enableFabricRenderer to switch to the Fabric renderer, enableTurboModules for JSI-based native modules, and enableBridgelessArchitecture to replace the legacy bridge with ReactHost. These flags are typically set at build time through Gradle or CocoaPods configurations but are referenced at runtime in this central registry.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →