t1k:rn:performance:native-modules
| Field | Value |
|---|---|
| Module | performance |
| Version | 1.6.3 |
| Effort | medium |
| Tools | — |
Keywords: bridge, fabric, JSI, native modules, react native, turbo modules
How to invoke
Section titled “How to invoke”/t1k:rn:performance:native-modulesRN Performance Native Modules
Section titled “RN Performance Native Modules”New Architecture Overview
Section titled “New Architecture Overview”Old: JS → Bridge (serialized JSON) → NativeNew: JS → JSI (direct C++ binding) → Native (synchronous)New Architecture = Turbo Modules (TurboModule API) + Fabric (new renderer). Enabled by default in RN 0.74+.
Turbo Module Pattern
Section titled “Turbo Module Pattern”// specs/NativeMyModule.ts — CodeGen specimport type { TurboModule } from 'react-native';import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule { multiply(a: number, b: number): Promise<number>; getDeviceName(): string; // synchronous via JSI}
export default TurboModuleRegistry.getEnforcing<Spec>('MyModule');// android — MyModuleModule.ktclass MyModuleModule(reactContext: ReactApplicationContext) : NativeMyModuleSpec(reactContext) { override fun multiply(a: Double, b: Double, promise: Promise) { promise.resolve(a * b) } override fun getName() = NAME companion object { const val NAME = "MyModule" }}Expo Modules API (Preferred — wraps Turbo Modules)
Section titled “Expo Modules API (Preferred — wraps Turbo Modules)”import { requireNativeModule } from 'expo-modules-core';const MyModule = requireNativeModule('MyModule');export default MyModule;Expo Modules API auto-generates CodeGen specs — no manual spec file needed.
JSI Direct Binding (Synchronous)
Section titled “JSI Direct Binding (Synchronous)”// Only use JSI for performance-critical synchronous operations// MMKV, Reanimated, and Gesture Handler use JSI internally// For most cases, async Turbo Modules are sufficientNitro Modules (Cutting Edge — RN 0.75+)
Section titled “Nitro Modules (Cutting Edge — RN 0.75+)”// Even faster than Turbo Modules — uses C++ templates// Use for compute-intensive work: image processing, crypto, MLKey Rules
Section titled “Key Rules”- Prefer Expo Modules API over raw Turbo Module spec for new modules
- Async by default — only use synchronous JSI for truly sync-critical paths (e.g., storage reads)
- CodeGen spec types must match exactly —
numberin TS =Doublein Kotlin/Swift - Test native modules with
eas build --profile development— not Expo Go
Gotchas
Section titled “Gotchas”- Old Architecture NativeModules still work in New Architecture via compatibility layer — migration is not urgent
- JSI modules crash if accessed before JS runtime is ready — guard with
global.__turboModuleProxy requireNativeModulethrows if module not linked — wrap in try/catch for optional modules- Android minSdk must be 24+ for New Architecture