Architecture of React Native: Old and New
A high-level overview of the old and new architectures
Background
React Native is a framework for building mobile apps that work on both Android and iOS, using a shared codebase written in JavaScript or TypeScript. It’s popular because it lets developers create apps faster and more efficiently by reusing code across platforms. However, one recurring topic of discussion has always been its architecture.
Old Architecture: The Bridge Era
React Native’s older architecture relied on a system called the Bridge to communicate between two worlds: JavaScript (where your app’s logic lives) and Native (the actual Android/iOS platform logic). While this made cross-platform development possible, it introduced challenges due to its asynchronous nature.
Key Components
On the JavaScript side, notable components include:
Metro Bundler
Packs your JavaScript code and assets into a single file (like zipping up your luggage for a trip) called the JS bundle
JS Engine
The powerhouse that runs your app’s code and manages UI updates
JavaScript Thread
The execution thread that the JavaScript Engine runs in
Bridge
The messenger that carries information between JavaScript and the Native side. Messages were sent in a serialized format (like translating a letter before mailing it)
On the native side, notable components include:
Native/UI Thread
Renders components, handles animations, and processes user interactions
Yoga engine
Calculates layouts (e.g. size, position) based on Flexbox principles, then sends this data to the UI thread for rendering
Shadow Thread
An execution environment that the Yoga engine runs in
Pitfalls of Old Architecture
Asynchronous, slow communication: Data had to be serialized (translated) when sent between threads, causing delays
Single-threaded JavaScript: JavaScript handles everything (logic, rendering, networking), so one slow task can bottleneck the whole app
Serialization/deserialization overload: Apps with frequent back-and-forth communication (e.g., animations) struggled to keep up
New Architecture
To tackle these limitations, a new architecture was introduced. The most significant change? The Bridge is gone. Instead, React Native uses new systems that focus on direct, synchronous communication and smarter resource management.
Key Components
JavaScript Interface (JSI)
Think of JSI as a direct phone line between JavaScript and Native code—no translation or extra steps required.It speeds up communication, reduces delays, and allows more efficient execution of tasks
Fabric
A synchronous rendering system in which the JS thread and UI thread stay in sync, reducing lag in user interactions.This results in smoother animations and quicker UI updates
It prioritizes essential tasks, like touch gestures and animations, to provide more responsive user interactions
Turbo Modules
With Turbo Modules, native code modules are now “lazy-loaded,” meaning they are only loaded when requiredThis reduces startup times and saves memory
Shared code can be written in C++ for both Android and iOS, reducing duplication
CodeGen
A tool that auto-generates type-safe code for communication between JavaScript and Native, catching potential errors before the app runs.
This minimizes runtime issues and improves developer productivity by providing safe, predictable code
Advantages
Smoother interactions: Direct communication improves speed, especially for animations and gestures
Reduced startup time: Components load on demand, so apps start faster
Improved efficiency: Less overhead from serialization, plus support for modern engines like Hermes and V8
React Native’s Next Phase
React Native’s new architecture marks a significant leap forward, addressing the inefficiencies of its predecessor. Developers can now build apps that perform better, load faster, and respond more smoothly to user interaction. Features like JSI, Fabric, and Turbo Modules make it easier to create high-quality apps. Starting with version 0.76, the new architecture is now the default, leading the way for a better React Native experience.