Bridge in React Native — what it is, working principle, and interaction

Author: IT Sectr Published: 2026-06-03 Reading time: 9 min

Bridge is an architectural component of React Native that provides asynchronous communication between the JavaScript thread and the native environment of iOS and Android. It transmits serialized JSON messages through a queue, allowing native APIs to be called from JS code. According to Meta, 2024, Bridge remains the foundation of existing applications, although it lags in performance compared to the new architecture on JSI.

Key Takeaways

  • Bridge is an asynchronous communication channel between JavaScript and native code in React Native.
  • Serialization — all data is converted to JSON before transmission, creating overhead.
  • Asynchronicity — messages are transmitted through a queue, so JS does not block the native thread.
  • Limitations — Bridge is not suitable for frequent small calls due to serialization costs.
  • Replacement — in the new React Native architecture, Bridge is replaced by JSI and Turbo Module.

What is Bridge in React Native?

Bridge is a key architectural element of React Native that provides two-way asynchronous communication between the JavaScript thread, where the application business logic runs, and the native iOS and Android threads. Since the release of React Native in 2015, Bridge has remained the only way for JS code to interact with platform APIs — camera, geolocation, file system, notifications, and other native capabilities.

The Bridge architecture is based on the message queue principle. When JavaScript code calls a native method, the request is serialized into a JSON string, placed in a queue, and asynchronously sent to the native side. The native code processes the request, performs the corresponding operation, and sends the result back through the same queue to the JS thread. According to Meta’s report at React Conf 2021, up to 10,000 messages per second pass through Bridge in an average application.

The main threads involved in Bridge operation: JavaScript Thread (JS code execution), Native Thread (native operations execution), and Shadow Thread (layout calculation using Yoga). Each thread works independently, ensuring UI responsiveness — native animations are not blocked by JS computations.

How Bridge Architecture Works

Bridge uses three key mechanisms for communication: MessageQueue, JSON serialization, and message batching. MessageQueue is an internal React Native component that manages the call queue between JS and the native side. Each native method call is placed in a queue, serialized, and sent in batches for performance optimization.

MessageQueue and Serialization

MessageQueue operates on a batching principle: native method calls accumulate and are sent as a single group (batch) every 5–15 milliseconds. This reduces serialization overhead, as multiple calls are packed into one JSON package. On the native side, messages are deserialized and distributed to the corresponding modules.

Module Registration

Native modules are registered automatically through macros or annotations. iOS uses the RCT_EXPORT_MODULE macro, Android uses the @ReactMethod annotation. React Native scans registered modules at application startup and builds a configuration JSON map of all available methods. This map is passed to the JS environment, and JavaScript learns which methods can be called.

Data Flow

Data follows this path: JavaScript calls NativeModules.CalendarModule.createCalendarEvent(). The method is serialized into a JSON message with the module identifier, method name, and arguments. The message enters the MessageQueue. On the native thread, the message is deserialized and passed to the corresponding module. The execution result is serialized back and sent to the JS thread as a Promise or callback.

js
            // Native module call from JavaScript via Bridge
import { NativeModules } from 'react-native';

const CalendarModule = NativeModules.CalendarModule;

CalendarModule.createCalendarEvent('Test Event', 'Office')
  .then(eventId => {
    console.log('Created event with id:', eventId);
  })
  .catch(error => {
    console.error('Failed:', error);
  });

On the native iOS side, the module looks like an Objective-C class with the RCT_EXPORT_MODULE macro. The method is exported using the RCT_EXPORT_METHOD macro, and React Native automatically registers it in Bridge. Arguments are passed by position and must correspond to supported JSON types: NSString, NSNumber, NSArray, NSDictionary, BOOL.

objective-c
            // iOS Native Module registration in Bridge
@interface CalendarModule () RCT_EXPORT_MODULE()
@end

@implementation CalendarModule

RCT_EXPORT_METHOD(createCalendarEvent:(NSString *)name
                  location:(NSString *)location
                  resolver:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
  NSNumber *eventId = createEvent(name, location);
  resolve(eventId);
}

@end

Bridge Limitations and Issues

Bridge has a number of fundamental performance limitations. The main one is mandatory asynchronicity and serialization. Each native method call converts data into a JSON string, which adds latency and consumes memory. For operations with large amounts of data, such as image processing or video work, this becomes a bottleneck.

Serialization Costs

JSON serialization and deserialization consume CPU time and memory. Each message must be converted to a string on the JS side, transmitted through the bridge, and parsed on the native side. According to Callstack tests (2022), serializing an array of 10,000 numbers through Bridge takes about 30–50 milliseconds, which is unacceptable for high-frequency calls.

Message Size Limitation

Bridge is not optimized for transferring large binary data. Photos, audio files, and video streams require alternative approaches — for example, writing a file to disk and passing the path as a string. This creates additional overhead for file system read and write operations.

  • Asynchronicity — Bridge does not support synchronous calls, complicating scenarios that require instant responses.
  • Memory — each message is stored in the queue until processed, which can lead to increased memory consumption.
  • Debugging — message tracing in Bridge is difficult because the call chain is broken between threads.

Recognition of these limitations led the Meta team to develop a new React Native architecture, where Bridge is replaced by JSI (JavaScript Interface) and Turbo Module. JSI allows calling native methods directly, without serialization, eliminating the main drawback of Bridge.

Bridge vs Turbo Module: Comparison

The comparison of Bridge and Turbo Module shows fundamental differences in architectural approaches. Bridge uses an asynchronous message queue with JSON serialization, while Turbo Module works through JSI — a direct interface between JavaScript and C++ that allows synchronous calling of native methods without data conversion.

CharacteristicBridgeTurbo Module
Call TypeAsynchronousSynchronous and asynchronous
SerializationJSON on every callJSI objects without copying
PerformanceAverageHigh
TypingDynamicStatic (Codegen)
LoadingAll modules at startupLazy (on demand)

The choice between Bridge and Turbo Module depends on the React Native version. For projects on React Native 0.72 and older, Bridge remains the main mechanism. Starting with React Native 0.73, Metro and the new architecture are supported in parallel, allowing gradual migration. A full transition to Turbo Module requires updating to React Native 0.76+ and enabling the new architecture in the configuration.

Setting Up a Native Module via Bridge Example

Let’s walk through the complete cycle of creating and using a Native Module through Bridge using a calendar module as an example. The module will create an event and return its identifier. This example covers setup for both platforms — iOS and Android.

Android Module

On Android, a Native Module is created as a Java class extending ReactContextBaseJavaModule. The @ReactMethod annotation exports the method to Bridge. For Promise, the Promise interface from com.facebook.react.bridge is used.

java
public class CalendarModule extends ReactContextBaseJavaModule {

    @Override
    public String getName() {
        return "CalendarModule";
    }

    @ReactMethod
    public void createCalendarEvent(
            String name,
            String location,
            Promise promise) {
        try {
            Integer eventId = createCalendarEventNative(name, location);
            promise.resolve(eventId);
        } catch (Exception e) {
            promise.reject("EVENT_ERROR", e.getMessage());
        }
    }
}

Registration and Usage

The module is registered through @ReactModule or manually in the application package. React Native automatically detects and adds it to Bridge. After registration, the module is accessible from JavaScript via NativeModules.

java
public class CalendarPackage implements ReactPackage {

    @Override
    public List<NativeModule> createNativeModules(
            ReactApplicationContext reactContext) {
        return Arrays.asList(
            new CalendarModule(reactContext)
        );
    }

    @Override
    public List<ViewManager> createViewManagers(
            ReactApplicationContext reactContext) {
        return Collections.emptyList();
    }
}

It is important to note that Bridge requires an application restart when adding new modules, as the configuration map is built once during initialization. This distinguishes it from Turbo Module, which loads lazily and supports hot-reload of modules without restart.

Frequently Asked Questions

How is Bridge different from direct data transfer?

Bridge always uses an asynchronous queue and JSON serialization, while direct transfer via JSI works synchronously and without data copying. Bridge creates serialization latency but ensures thread isolation.

Can methods be called synchronously through Bridge?

No, Bridge only supports asynchronous calls. Synchronous interaction requires the new architecture with JSI and Turbo Module. This is one of the key limitations that has been resolved in React Native 0.76+.

What data types does Bridge support?

Bridge supports types serializable to JSON: strings, numbers, boolean values, arrays, dictionaries (objects). Binary data such as images must be transferred via the file system or base64 encoding.

How to measure Bridge performance?

For measurement, use React DevTools and the React Native profiler. The Performance tab shows the number of messages in the Bridge queue and latencies. The react-native-bridge-spy package is also available for traffic monitoring.

When should you switch from Bridge to Turbo Module?

It is recommended to switch for performance-demanding projects or when creating new applications on React Native 0.76+. For existing projects, migration can be gradual — both architectures work in parallel.

Summary

  • Bridge is an asynchronous communication mechanism between JavaScript and native React Native code, based on JSON serialization.
  • MessageQueue manages the message queue, grouping calls into batches to reduce overhead.
  • Serialization creates a 30–50 ms delay when transferring large data arrays through Bridge.
  • Limitations of the architecture include the absence of synchronous calls and high memory consumption with frequent messages.
  • New architecture of React Native replaces Bridge with JSI and Turbo Module, providing direct access without serialization.
  • Compatibility — Bridge continues to work in React Native up to 0.72+, and in versions 0.73+ parallel operation of both architectures is available.
  • Choice — for new projects, the new architecture is preferable; existing projects migrate gradually.

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also