How React Native Shares Native Code Between Platforms: The C++ Core Architecture
React Native shares native code between iOS and Android through a shared C++ core located in packages/react-native/ReactCommon that implements the JavaScript Interface (JSI), Fabric renderer, Yoga layout engine, and TurboModule system, which is then wrapped by thin platform-specific layers.
React Native's cross-platform capabilities stem from its architectural decision to move the framework's heavy lifting into a platform-agnostic C++ layer. By centralizing the JavaScript bridge, layout calculations, and native module system in the ReactCommon package, the facebook/react-native repository ensures that critical features ship simultaneously across all supported platforms while maintaining consistent behavior.
The Shared C++ Core in ReactCommon
The majority of React Native's native implementation lives in packages/react-native/ReactCommon. This directory contains pure C/C++ code that compiles once for every target platform and links into each app binary.
Key components implemented in the shared core include:
- JSI (JavaScript Interface) – A lightweight API that allows direct synchronous communication between JavaScript and C++ without serialization overhead.
- Fabric – The new renderer that diffs and commits UI updates using a C++ shadow tree.
- Yoga – The cross-platform layout engine written in C++ that calculates flexbox layouts identically on iOS and Android.
- TurboModules – The native module system that allows C++ implementations to be shared across platforms.
Platform-Specific Wrappers: Bridging C++ to iOS and Android
While the core logic resides in C++, React Native uses thin platform-specific wrappers to bridge the shared code to native UI toolkits. These wrappers handle platform-specific conventions like memory management, threading models, and UI component instantiation.
iOS Integration via Objective-C++
On iOS, React Native exposes the C++ core through Objective-C++ files (.mm extensions) that bridge the C++ headers in ReactCommon with the iOS RCTBridge.
Key integration points include:
ReactCommon/react/renderer/components/view/platform/ios/*– Platform-specific view component implementations.ReactCxxBridge/ReactCxxBridge.mm– The Objective-C++ bridge that initializes the C++ core and connects it to the iOS runtime.
Android Integration via JNI
On Android, React Native uses the Java Native Interface (JNI) to load the compiled C++ library and forward calls between Java/Kotlin and the C++ core.
The workflow involves:
System.loadLibrary("reactnativejni")loads the shared library containing the ReactCommon code.- Java classes in
ReactAndroid/src/main/java/com/facebook/react/bridge/ReactInstanceManager.javamanage the C++ instance lifecycle. - JNI bindings in
ReactCommon/react/nativemodule/core/platform/android/*marshal data between Java and C++.
How the Architecture Works at Runtime
Understanding the data flow reveals how React Native maintains platform consistency while leveraging native capabilities:
-
JavaScript Execution – JavaScript runs inside an engine (Hermes, V8, or JavaScriptCore) embedded within the app.
-
JSI Communication – When JavaScript calls a native API, JSI forwards the call synchronously to the C++ bridge in
ReactCommon. -
Platform Dispatch – The bridge invokes the platform-specific binding (Objective-C on iOS, Java/Kotlin on Android), which handles OS-specific UI frameworks (UIKit, Android Views).
-
Fabric Rendering – UI updates are batched and rendered by Fabric, which lives in the shared core and communicates with platform-specific view managers to update the screen.
Because heavy operations like layout calculation (Yoga), tree diffing, and async module loading execute in the shared C++ layer, both platforms share identical implementations, guaranteeing feature parity.
TurboModules: Sharing Native Modules Across Platforms
TurboModules extend the shared architecture by allowing developers to write native modules once and use them on both platforms. A module can be implemented in C++ (or in Java/Kotlin/Objective-C) and exported via a unified C++ interface.
The runtime loads the correct implementation for the current platform while keeping the JavaScript contract identical across iOS and Android.
C++ TurboModule Definition
// Shared C++ implementation (ReactCommon/react/nativemodule/core/ReactCommon/TurboModule.h)
class NativeSampleTurboModule : public facebook::react::TurboModule {
public:
NativeSampleTurboModule(const std::shared_ptr<CallInvoker> &jsInvoker)
: TurboModule("NativeSampleTurboModule", jsInvoker) {}
// Synchronous method exposed to JavaScript
int add(int a, int b) {
return a + b;
}
};
iOS Binding Implementation
// ios/NativeSampleTurboModule.mm
#import <ReactCommon/TurboModule.h>
#import "NativeSampleTurboModule.h"
@implementation RCTNativeSampleTurboModule {
std::shared_ptr<facebook::react::NativeSampleTurboModule> _cppModule;
}
RCT_EXPORT_MODULE();
- (instancetype)init {
if (self = [super init]) {
_cppModule = std::make_shared<facebook::react::NativeSampleTurboModule>(self.jsInvoker);
}
return self;
}
RCT_EXPORT_METHOD(add:(NSInteger)a
b:(NSInteger)b
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject) {
NSInteger result = _cppModule->add(a, b);
resolve(@(result));
}
@end
Android Binding Implementation
// android/src/main/java/com/example/NativeSampleTurboModule.java
package com.example;
import com.facebook.react.turbomodule.core.interfaces.TurboModule;
import com.facebook.react.bridge.ReactApplicationContext;
public class NativeSampleTurboModule implements TurboModule {
static {
System.loadLibrary("reactnativejni"); // loads the shared C++ library
}
private final long nativeModulePtr;
public NativeSampleTurboModule(ReactApplicationContext reactContext) {
nativeModulePtr = nativeCreate(); // native side constructs C++ NativeSampleTurboModule
}
private native long nativeCreate();
public int add(int a, int b) {
return nativeAdd(nativeModulePtr, a, b);
}
private native int nativeAdd(long ptr, int a, int b);
}
JavaScript Usage
import { NativeModules } from 'react-native';
const { NativeSampleTurboModule } = NativeModules;
async function demo() {
const sum = await NativeSampleTurboModule.add(3, 4);
console.log('3 + 4 =', sum); // => 7 on both platforms
}
demo();
Key Source Files and Implementation Details
The following files illustrate the layered architecture that enables React Native to share native code between platforms:
packages/react-native/ReactCommon/README.md– Overview of the shared C++ code and architecture.packages/react-native/ReactCommon/yoga/yoga/Node.h– Yoga layout engine implementation.packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModule.h– Base class for cross-platform native modules.packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.cpp– Android JNI entry point for TurboModules.packages/react-native/React/CxxBridge/ReactCxxBridge.mm– iOS Objective-C++ bridge implementation.packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/NativeSampleTurboModule.cpp– Sample shared C++ module implementation.packages/react-native/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/TurboModule.kt– Android TurboModule interface.packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModule.mm– iOS sample TurboModule binding.packages/react-native/Libraries/TurboModule/TurboModuleRegistry.js– JavaScript entry point for TurboModules.
Summary
- React Native shares native code between platforms through a shared C++ core in
packages/react-native/ReactCommonthat implements the bridge, JSI, Fabric, Yoga, and TurboModules. - Platform-specific wrappers provide thin bindings: Objective-C++ for iOS and JNI for Android, allowing the shared C++ code to interact with native UI toolkits.
- TurboModules enable developers to write native modules once in C++ (or platform languages) and expose them through a unified interface, maintaining identical JavaScript contracts across iOS and Android.
- The architecture guarantees feature parity and reduces code duplication by performing heavy operations (layout, tree diffing, async operations) in the shared C++ layer.
Frequently Asked Questions
What programming languages does React Native use to share code between platforms?
React Native primarily uses C++ to share code between platforms, implementing the core framework logic in packages/react-native/ReactCommon. This shared codebase is then exposed to iOS through Objective-C++ wrappers and to Android through Java/Kotlin classes that communicate via the Java Native Interface (JNI).
How does React Native handle platform-specific UI differences if the core is shared C++?
While the business logic, layout calculations (via the Yoga engine), and rendering logic (via Fabric) live in the shared C++ core, platform-specific view managers handle the actual UI component instantiation. The C++ shadow tree calculates layouts identically across platforms, but platform-specific bindings in ReactCommon/react/renderer/components/view/platform/ios/* and corresponding Android directories map these calculations to native UIKit or Android View components.
What is the difference between the legacy bridge and the new JSI architecture for code sharing?
The legacy bridge required all native calls to be asynchronous and serialized through JSON, forcing platform-specific implementations to handle marshalling separately. The JSI (JavaScript Interface) architecture exposes C++ host objects directly to the JavaScript engine, allowing synchronous, type-safe calls to the shared C++ core. This eliminates serialization overhead and ensures that both platforms use identical C++ implementations for core functionality, with only thin platform bindings differing.
Can third-party libraries share native code between platforms using the same approach?
Yes, third-party libraries can leverage TurboModules to share native code between platforms. Developers can implement core logic in C++ within their library, then provide thin platform-specific bindings for iOS (Objective-C++) and Android (JNI) that interface with the shared C++ implementation. This approach ensures that complex calculations, cryptographic operations, or custom rendering logic behave identically on both platforms while maintaining a single JavaScript API contract.
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 →