"Why does React Native need a new architecture?" If you've asked this lately, this post is for you.
This guide is your friendly deep-dive into Hermes, JSI, TurboModules, Fabric, and Codegen, written for real-world developers who want to understand not just what changed, but why it matters in daily work.
π§ Why You Should Care
React Native has come a long way from its "bridge" days. If you're building apps in 2025 and still relying on legacy architecture, you're likely hitting walls in performance, reliability, or scalability.
This article breaks down React Native's new architecture in a simple, real-world way β so you don't just know what each piece is, but also why it matters and when to use it.
π Quick Overview: The Moving Parts
Before we dig deep, here's a quick 1-liner summary of each piece:
- Hermes: A fast, mobile-first JavaScript engine that compiles your JS to bytecode before running it.
- JSI (JavaScript Interface): A new way for JS to talk directly to native code without the old bridge.
- TurboModules: A new type of native module that loads on-demand and communicates via JSI.
- Fabric: A new UI renderer that brings React 18 features and speeds up UI updates.
- Codegen: A tool that auto-generates native code from TypeScript/Flow type definitions.
π Hermes: Faster JavaScript Execution
Think of Hermes as your engine's turbocharger.
Before Hermes, JavaScript had to be parsed and interpreted on the device. With Hermes, the JS code is compiled ahead of time to bytecode β leading to:
- Faster app startup
- Lower memory usage
- Smaller APK size (in some cases)
Performance Gains (measured in real projects):
- Time to First Render decreased by ~40%
- JS Memory usage dropped up to 50%
You enable Hermes in android/app/build.gradle or your iOS Podfile.
π JSI: The Modern Bridge (Thatβs Not a Bridge)
JSI replaces the old bridge-based communication between JavaScript and native code.
With JSI:
- Calls are direct, not serialized through a bridge
- You can call native code from JS without waiting
- It opens the door for new tools like TurboModules & Fabric
Old Way:
// JS calling native via bridge
NativeModules.CameraModule.takePicture();
Now with JSI (TurboModules):
import { takePicture } from 'react-native-camera/takePicture';
takePicture(); // faster, lazy-loaded, type-safe
π§± TurboModules: Smarter Native Modules
Previously, all native modules were loaded on app startup, even if unused. TurboModules change this:
- Theyβre loaded only when needed
- Communicate through JSI, so theyβre faster
- Written with strict type safety using Codegen
Example use case: If your app has a camera module but the user never opens the camera screen, TurboModules make sure itβs not loaded until needed.
Example Codegen Interface:
// MyCameraModule.ts
export interface Spec {
takePicture(): void;
}
declare const CameraModule: Spec;
export default CameraModule;
π¨ Fabric: The Future of UI Rendering
Fabric is React Nativeβs new rendering system.
Why it matters:
- Brings React 18βs concurrent rendering and Suspense to mobile
- UI updates are faster and more predictable
- Uses JSI to update native views synchronously
Example:
// QRCodeScanner.tsx
import { codegenNativeComponent } from 'react-native/Libraries/Utilities/codegenNativeComponent';
export interface Props {
onQRCodeScanned: (data: string) => void;
scanAreaColor?: string;
}
export default codegenNativeComponent<Props>('QRCodeScannerView');
π§ͺ Codegen: Less Boilerplate, More Safety
Writing native modules used to involve lots of glue code β and lots of bugs.
Codegen automates the boring parts:
- You define your native module interface in TypeScript or Flow
- Run
yarn codegen - It generates the native bindings (Java/Kotlin/Obj-C/Swift) for you
This makes native modules:
- Type-safe
- Easier to maintain
- Faster to integrate
Without Codegen (Old Way):
- Manually create
.java,.h,.mfiles and glue them
With Codegen:
- One
.tsinterface = native bindings auto-generated
π§© How Everything Fits Together
Picture this:
- You write a component (e.g.,
QRCodeScanner) in native code - You define its props in TypeScript
- Codegen auto-generates native interfaces
- Hermes runs your JS efficiently
- JSI connects JS to native instantly
- TurboModule ensures itβs only loaded when needed
- Fabric renders it smoothly like any React component
π Visual Summary
π§ Hermes β Pre-compiles JS β Reduces load time
π§΅ JSI β Threads native & JS directly
βοΈ TurboModules β Lazy-loaded native logic
π¨ Fabric β Concurrent, faster UI rendering
π οΈ Codegen β Generates native code from types
π‘ Real-World Use Cases
- Building a blazing-fast media player? Use TurboModules to wrap native audio libraries.
- Creating a custom map renderer? Implement it in native and expose it via Fabric.
- Need custom QR code scanning? Define it once, run Codegen, and render via Fabric.
π Best Practices Moving Forward
- β Always enable Hermes in production.
- β Use TypeScript for defining native module interfaces.
- β Prefer TurboModules over legacy modules.
- β Use Fabric for custom native UI components.
- β Automate native bindings with Codegen.
π§ Final Thoughts
React Native's new architecture isn't just a buzzword β it's a real shift that unlocks speed, safety, and scalability.
If you're a senior developer or aspiring tech lead, understanding and adopting this architecture is no longer optional.
The best part? You donβt need to master C++ or Obj-C. You just need to know when and why to use these tools.
π£ If this helped you or you want part 2 (with real code samples for Fabric & TurboModules), drop a comment or follow me. Letβs build fast, native-like apps β the right way.
βοΈ Written by Waqar Amjad, a Senior React Native Developer passionate about building accessible and performant mobile experiences.
Top comments (0)