React Native Architecture: From Bridge to Fabric

In this post, we’ll explore how React Native works under the hood, from the traditional Bridge architecture to the New Architecture with Fabric.

A Quick Explanation on How React Native Works

In a React Native project, we often work with multiple JavaScript files: components, hooks, services, and more. In a typical React web application, these files are bundled into a single bundle.js to build the app. React Native follows a similar idea and it uses Metro, a bundler designed specifically for mobile environments. Metro takes all the JavaScript files, resolves dependencies, and produces a package that can run on mobile devices.

However, React Native applications don’t run only with JavaScript. Since the code needs to run natively on both iOS and Android, it cannot rely solely on JavaScript, considering that each platform has its own native languages, such as Swift and Kotlin, respectively.

React Native Architecture

To handle the execution of JavaScript in the app, React Native uses an engine called Hermes. The business logic runs in the JavaScript Thread through Hermes, while the native side (Main Thread) is responsible for tasks such as rendering elements on the screen and handling user interactions.

At this point, you might be wondering: how does JavaScript actually connect to native code? That’s where the Bridge architecture comes into play.

The Bridge Architecture

As the name suggests, the Bridge is responsible for connecting both worlds. This design worked well for many years, but it introduced significant limitations in terms of performance and scalability, which is why it was eventually replaced. We'll explore these limitations in more detail later in this post.

How Does It Work?

It's actually simpler than it looks. The communication is asynchronous and relies on JSON objects being passed back and forth. For example, when a user taps a button, a touch event is sent to the Bridge, which forwards it to the JavaScript Thread to execute the associated function.

Component Renderization

When you render a component, the JSON instruction is sent from JavaScript through the Bridge, telling the native side to render a native view. This mechanism is also used to request native resources such as geolocation, the camera or photo gallery.

There is also an additional thread, the Shadow Thread, responsible for calculating the layout and positioning of UI elements. It uses Yoga, a layout engine that enables cross-platform layouts with Flexbox, ensuring consistent styling on both Android and iOS.

Limitations

  • Serialization Overhead: Every method call or UI update had to be serialized into JSON and deserialized on the other side
  • Latency: Large or frequent data transfers (images, camera frames, DB queries) caused noticeable lags
  • Async Layout: Accessing layout synchronously was impossible, leading to flickering or "layout jumps"
React Native Bridge Architecture

Fabric: The New Architecture

The New Architecture, also known as Fabric, is a complete rewrite of how React Native renders components, communicates between JavaScript and native code, and schedules work across threads. At its core, Fabric is a C++ renderer shared across platforms, connected to JavaScript through the JavaScript Interface (JSI). It keeps the same threads (JS, Shadow, Native) but replaces the Bridge with the JSI. Since version 0.76, this architecture is enabled by default.

Component Renderization

When you render a component under Fabric, JavaScript can hold direct references to C++ objects. The Shadow Thread operates directly on the immutable C++ Shadow Tree. Each UI update creates a new version of this tree, which ensures that multiple “in-progress” renders can exist at the same time without interfering with each other.

Once the layout is computed, Fabric commits the final Shadow Tree to the Native UI Thread, which applies the changes to platform-native views. This design eliminates the overhead of JSON serialization and asynchronous communication.

React Native Fabric Architecture

Main Benefits of The New Architecture

  • Synchronous Layout: Layout can be read synchronously or asynchronously, preventing flickering from async queries. With that, Updates can be processed on different threads with different priorities: React can interrupt a low-priority render (like a background update) to handle urgent user input immediately. Hooks like useLayoutEffect now work correctly on mobile, allowing precise element positioning in the same frame.
  • Concurrent Rendering: Enables Concurrent Rendering (React 18 features like Suspense and Transitions) without blocking the UI because of the Immutable Shadow Tree in C++. Each update creates a new version of the tree instead of mutating the old one. Multiple “in-progress” trees can exist at once, allowing React to prepare updates in the background.
  • Web Alignment: Closer to how React works in the browser, easing cross-platform development

TurboModules and Codegen

The old Native Modules system initialized all modules at app startup, causing slow startup times and offering no type-safety: bugs could slip through if JS and native code disagreed. TurboModules improve this system by allowing your JavaScript code to interact with native platform APIs more efficiently:

  • Lazy Loading: Modules are loaded only when first used, improving startup time.

  • Type Safety: When combined with Codegen, TurboModules provide a strongly typed interface between JS and native code, reducing runtime errors.

Codegen works alongside TurboModules to generate the boilerplate automatically: instead of writing all bridge and platform-specific code manually, developers define a typed specification in TypeScript or Flow, and Codegen produces type-safe C++ and platform-native bindings. This ensures consistency and catches type mismatches early.

Ecosystem Readiness

Most core components and popular libraries already support the New Architecture, but teams should still check whether their dependencies are compatible before migrating. Good evidence of this maturity is that companies like Shopify have already migrated their main app to the New Architecture – See their blog post for details.

Final Thoughts

By understanding both the Bridge and the New Architecture, developers not only recognize why React Native evolved, but also gain the knowledge to build more efficient and scalable apps, as well as the perspective to identify bottlenecks in older projects that may still rely on the Bridge.

We explored the key differences between the two architectures, including how components are rendered, how data flows between JavaScript and native threads, and how TurboModules and Codegen improve native interoperability.

For a deeper understanding of specific architecture changes and migration paths, check the official React Native documentation linked below.

References

We want to work with you. Check out our Services page!