React Native New Architecture 2025: Fabric & TurboModules

by

React Native’s New Architecture is finally mainstream in 2025. If you’ve shipped apps on the classic bridge, Fabric and TurboModules promise lower latency, smoother animations, and far less JNI/Obj‑C boilerplate. This guide explains how the pieces fit—JSI, Codegen, Hermes, TurboModules, and the Fabric renderer—plus a safe migration plan, sample conversions, and performance guardrails for production Android and iOS apps. By the end, you’ll know when to flip the switches, what to refactor, and how to measure real wins.

React Native New Architecture 2025: Fabric and TurboModules overview diagram
From bridged JSON to direct native access: Fabric, TurboModules, and Hermes under one roof.

React Native New Architecture: what it is and why it matters

The New Architecture replaces the old asynchronous JSON bridge with a unified model built on JSI (JavaScript Interface). Two big upgrades:

  • TurboModules: next‑gen NativeModules with direct, typed, synchronous/async calls via JSI and Codegen.
  • Fabric: a new renderer that makes layout and updates concurrent, reducing main‑thread jank.

You get faster startup, lower call overhead, and cleaner native interop—especially noticeable on mid‑range Android hardware.

Flow: JS (Hermes) ↔ JSI ↔ TurboModules & Fabric renderer
Data path: Hermes executes JS → JSI bridges values → TurboModules & Fabric touch platform UIs and services.

Fabric & TurboModules explained (primary value)

TurboModules make JS↔native calls cheap and type‑safe. You define an interface in TypeScript/Flow, and Codegen emits native stubs (Kotlin/Java, Obj‑C/Swift/C++) and JS wrappers.

Fabric replaces the legacy UIManager, enabling:

  • Concurrent rendering and prioritization for smoother gestures and animations.
  • Fewer layout passes and less main‑thread blocking.
  • Better memory patterns for large lists/grids.

Under the hood: JSI, Codegen, Hermes (secondary keyword)

  • JSI: a lightweight C++ API that lets JS and native exchange values and functions without JSON serialization.
  • Codegen: parses your module/surface specs and generates native bindings and typed JS factories.
  • Hermes: the default JS engine optimized for RN. Faster start, lower memory, and tight JSI coupling.

Migration checklist you can trust

  1. Upgrade RN: Move to a 2025‑supported version with New Architecture stable (check the RN release notes).
  2. Enable Hermes: It’s default on modern RN; verify in Android/iOS configs.
  3. Turn on New Architecture flags:
    // android/gradle.properties
    newArchEnabled=true
    
    // ios/Podfile
    use_react_native!( :new_architecture_enabled => true )
  4. Audit NativeModules: List current modules; mark ones to convert to TurboModules.
  5. Audit custom Views: Identify components to move to Fabric (paper/legacy to ShadowNode‑based renderer).
  6. Add Codegen: Define module/view specs in TS/Flow and run Codegen in your build.
  7. Measure: Add perf markers (TTI, startup, interaction latency) before/after.
  8. Roll out gradually: Use feature flags; ship to a beta ring first.

Example: converting a NativeModule → TurboModule

Define your interface (TypeScript):

// MyDeviceInfo.ts
export interface Spec {
  getModel(): Promise<string>;
  isEmulator(): Promise<boolean>;
}
export default Spec;

Register with Codegen and implement native stubs (Kotlin/Swift) that match the signatures. Import in JS:

import {TurboModuleRegistry} from 'react-native';
import type Spec from './MyDeviceInfo';

const DeviceInfo = TurboModuleRegistry.getEnforcing<Spec>('DeviceInfo');
const model = await DeviceInfo.getModel();

Result: fewer copies, typed calls, and no manual bridge glue.

Example: migrating a custom view to Fabric

  1. Create a component spec (props, commands) for Codegen.
  2. Implement the native view class and ShadowNode.
  3. Wire up events/commands via generated bindings.
  4. Use it from JS like any other component; Fabric handles layout/updates.

Performance & DX in 2025 (expert insights)

  • Startup: New Architecture + Hermes trims cold start, especially after removing large legacy bridges.
  • Input latency: Fabric prioritizes user interactions; list scroll and gestures feel steadier on Android.
  • Type‑safety: Codegen eliminates a class of brittle JSON argument bugs.
  • Interop: JSI enables advanced patterns (e.g., passing function refs to native) without serializing.
Indicative benchmarks: cold start, JS↔native call cost, list scroll stability
Focus on your app’s baseline: measure before you flip the flags; validate wins per screen.

Old Architecture vs New: what actually changes

  • Bridge: JSON message queue → JSI direct calls.
  • UI: UIManager (paper) → Fabric renderer.
  • Modules: NativeModule + manual glue → TurboModule + Codegen.
  • Engine: JSC (legacy) → Hermes (default).
Comparison diagram: Legacy Bridge + UIManager vs JSI + TurboModules + Fabric
Cleaner architecture, fewer copies, fewer wakeups. Less glue, more shipping.

Implementation guide: safe rollout in one afternoon

  1. Create a branch: bump RN, enable Hermes/New Architecture.
  2. Fix build errors: run Codegen; resolve missing specs/headers.
  3. Convert one module: pick a small NativeModule → TurboModule to validate the toolchain.
  4. Turn on Fabric for one surface: a contained screen (e.g., settings) is a good pilot.
  5. Profile: React Profiler, Perfetto (Android), Instruments (iOS). Track TTI and frame time.
  6. Feature flag: gate by environment or remote config; roll to 5–10% users.

Common pitfalls (and fixes)

  • Codegen drift: When you change a spec, re‑run Codegen and clean builds. Keep specs co‑located with modules.
  • Threading assumptions: TurboModule calls can be synchronous; ensure native side is thread‑safe.
  • Large lists: Fabric helps, but you still need proper virtualization (FlashList/RecyclerListView) and stable keys.
  • Third‑party libs: Pin versions that support New Architecture; audit NativeModules bundled by dependencies.

Practical examples to borrow

Device sensors via TurboModule

// Spec
export interface SensorsSpec { subscribe(type: 'accel'|'gyro'): void; }
// JS
const Sensors = TurboModuleRegistry.getEnforcing<SensorsSpec>('Sensors');
Sensors.subscribe('accel');

Custom chart view on Fabric

<ChartView data={series} theme="dark" onPointPress={...} />

Move heavy layout and path generation native‑side; Fabric keeps updates snappy.

Recommended tools & deals

  • Deploy lightweight backends for your RN app: Railway — fast APIs, queues, and cron without DevOps.
  • UI kits, icons, and Lottie animations: Envato — ship polished visuals and motion quickly.
  • Domains for preview builds: Namecheap — clean URLs for OTA update portals and docs.

Disclosure: Some links are affiliate links. If you click and purchase, we may earn a commission at no extra cost to you. We only recommend tools we’d use ourselves.

Go deeper: related internal guides

Official docs and trusted sources

Final recommendations

  • Enable the New Architecture on a pilot screen, measure, then expand.
  • Convert high‑traffic NativeModules first; keep legacy shims only where necessary.
  • Pair Fabric with list virtualization and memoized item renderers.
  • Automate Codegen and lint specs in CI so typing never drifts.

Frequently asked questions

Do I need Hermes to use the New Architecture?

Yes—Hermes is the default and tightly integrated with JSI. It’s strongly recommended for performance and compatibility.

Can I enable TurboModules without Fabric?

Yes. You can adopt them independently, though running both delivers the full benefit.

What breaks when switching?

Most JS code is fine. NativeModules with custom bridge glue need conversion or shims. Audit third‑party packages for support.

How do I know Codegen worked?

Your build will generate native stubs and JS types. Missing symbols or mismatched signatures indicate spec drift.

Will this fix list scroll jank by itself?

It helps, but you still need FlashList/RecyclerListView, stable keys, and lightweight item renders.

Is iOS or Android trickier?

Android surfaces more JNI/Gradle details; iOS usually goes smoother if Pods are clean. Test on both early.

Can TurboModules call synchronously?

Yes, where safe. Prefer async for I/O; use sync only for truly fast, non‑blocking reads.

How do I roll back?

Gate with a feature flag. Keep a branch with old flags off; revert if a crash spikes in telemetry.

What about Web and Windows?

React Native Web doesn’t use Fabric native; RN Windows/Mac have their own implementations—check project support.

What’s the best way to measure wins?

Track TTI, interaction latency, dropped frames, and memory on key screens before and after. Validate on mid‑tier Android.

FAQ highlights: Hermes, sync calls, rollbacks, and measurement
Adopt deliberately: enable, convert, measure, and expand.

all_in_one_marketing_tool