React Native Architecture: Old vs New

A side-by-side overview of the legacy React Native architecture and the New Architecture (Fabric + TurboModules + JSI + Hermes + Codegen), with a side-by-side comparison table, a release timeline, and SVG diagrams.

Architecture comparison

Overview

The legacy React Native architecture relied on an asynchronous JSON bridge to communicate between the JavaScript thread and the native UI thread. While simple and broadly compatible, the bridge became a well-known performance and correctness bottleneck as apps grew.

Threads

  • JavaScript thread

    • Executes React component logic, hooks, and state updates
    • Runs the React reconciler to compute the virtual element tree
    • Sends diffs to native via the bridge on each render
  • Native / UI thread

    • Receives view operations from the bridge and applies them to the native view hierarchy
    • Handles user input, gestures, and platform-level rendering
    • Dispatches responses (events, callbacks) back through the bridge
  • Shadow thread

    • Computes Yoga layout for the shadow tree off the main threads
    • Produces layout metadata the UI thread applies to native views

How the Bridge Worked

How the Bridge Worked. Every call between JavaScript and native was serialized as JSON, queued, and processed asynchronously on the other side. JSON serialization, queueing, and deserialization dominated cross-thread latency and prevented synchronous reads of native values from JS.

Problems

  • Asynchronous, JSON-serialized bridge

    All JS↔native traffic was serialized to JSON and processed on a queue, adding latency and preventing synchronous access to native values.

  • Duplicated work in three threads

    JS, Shadow, and Native threads each maintained parallel state of the tree, increasing memory pressure and the chance of inconsistencies.

  • Cost of repeated serialization

    Frequent updates paid the full JSON (de)serialization cost on every render, hurting scroll and animation performance.

  • No synchronous native calls

    The bridge was strictly async, so measuring layout, reading persistent values, or invoking imperative methods required extra round-trips.

  • Slower startup time

    Module initialization and bridge warm-up delayed time-to-interactive, especially on Android.

Rendering Flow

  1. React Code
  2. JSC
  3. Bridge (JSON Serialization)
  4. Native Modules
  5. UIManager
  6. Yoga
  7. Native Views

Diagram

Old Architecture: JS thread to native via JSON bridgeDiagram of the legacy React Native pipeline. React code runs in the JavaScriptCore engine and crosses the asynchronous JSON bridge into native modules and the UIManager, which compute Yoga layout before mounting native views.JS threadShadow threadNative / UI threadReact CodeJavaScriptCoreJSCBridgeJSON serialization (async)YogaLayoutNative ModulesUIManagerNative Viewsasync callasync response

Key terms in this diagram

React Code
Your React components, hooks, and state. Runs JavaScript that drives the UI.
JavaScriptCore (JSC)
Apple's JavaScript engine that executed React Native code on both iOS and Android in the legacy architecture.
Bridge
The asynchronous boundary between the JS thread and the native threads. Every call was serialized to JSON, queued, and decoded on the other side.
Native Modules
Platform-specific code (camera, location, storage, sensors) that the bridge exposed to JavaScript.
UIManager
The native module that owned the view hierarchy: it created, updated, and destroyed native views in response to bridge messages.
Yoga
Facebook's cross-platform layout engine. Ran on a separate shadow thread and computed flexbox-style positions and sizes for every node in the view tree.
Native Views
The actual platform UI objects (UIView on iOS, android.view.View on Android) that the OS rendered to the screen.

Comparison

Side-by-side comparison of the legacy and new React Native architectures.
AspectOld ArchitectureNew Architecture
JavaScript EngineJavaScriptCore (JSC) on iOS and Android, with optional Hermes opt-in.Hermes by default, with optional V8; AOT compilation and smaller footprint.
Communication LayerAsynchronous, JSON-serializing bridge between JS and native threads.JSI: direct, synchronous C++ bindings between JS and the native runtime.
Module SystemNative Modules: all modules initialized eagerly at app start.TurboModules: lazily loaded on demand, described by static specs.
Rendering SystemLegacy renderer with paper UIManager and async bridge updates.Fabric renderer with concurrent React, shadow tree, and prioritized updates.
SerializationEvery cross-thread call JSON-encodes data, queuing and decoding on the other side.No JSON serialization; JS holds direct C++ object references via JSI.
Synchronous CallsNot supported by the bridge; all cross-thread work is async.Supported via JSI; sync layout reads and imperative calls are first-class.
Startup TimeSlower: all modules and the bridge warm up before first paint.Faster: lazy TurboModules and Hermes AOT reduce time-to-interactive.
Memory UsageThree parallel trees (JS, Shadow, Native) plus queued bridge messages.Shared C++ shadow tree and lazy module loading lower baseline memory.
Module LoadingEager: Native Modules are created and registered at startup.Lazy: TurboModules initialize on first call, guarded by Codegen specs.
React Concurrent SupportLimited; the async bridge breaks assumptions of concurrent rendering.Full: Fabric integrates with React 18 concurrent features and Suspense.
PerformanceBridge bottlenecks under heavy updates; scroll and animation suffer on mid-range devices.Lower latency per update; smoother interactions thanks to JSI and Fabric prioritization.
Type SafetyDynamic contract: mistakes surface at runtime as bridge errors.Static contract: Codegen produces typed bindings validated at build time.

Release Timeline

  1. 0.68Experimental opt-in

    First release where the New Architecture could be enabled behind a flag for testing.

  2. 0.76Default

    New Architecture is enabled by default for new projects while still allowing opt-out.

  3. 0.82Only architecture

    Old Architecture is removed; the New Architecture is the only supported runtime.