React Native

Building Cross-Platform React Native Bridges for iOS and Android

Learn how to build React Native bridges for iOS and Android to connect JavaScript with native Swift, Objective-C, and Java code. Follow this step-by-step guide to integrate platform-specific functionality into your React Native applications.

React NativeNative BridgeNative ModulesiOS DevelopmentAndroid DevelopmentSwiftObjective-CJavaCross Platform DevelopmentMobile App DevelopmentReact Native TutorialDEFX

Building Cross-Platform React Native Bridges for iOS and Android

Connecting React Native with Native Code: A Deep Dive into Bridges

React Native's strength lies in its ability to bridge the gap between JavaScript and native platforms (iOS and Android). This "bridge" facilitates communication, enabling developers to leverage existing native libraries within their React Native applications. This capability is crucial for building production-ready apps with enhanced performance and access to platform-specific features. This article provides a comprehensive guide to creating native bridges that work seamlessly across both iOS and Android, allowing you to harness the power of Swift/Objective-C and Java within your React Native projects.

Building Our Example: The LightApp

To illustrate the concept, we'll build a simple "LightApp" using the react-native CLI. This app will demonstrate how to control a virtual "Bulb" through a native bridge. The same React code will function on both platforms, showcasing the cross-platform nature of this approach.

react-native init LightApp
cd LightApp

The tutorial is divided into two sections: Section 1: Native Bridge in iOS; Section 2: Native Bridge in Android.

Section 1: Native Bridge in iOS

This section focuses on building a bridge between Swift/Objective-C and your React Native component. The process involves three key steps: creating the Bulb class and bridge header, addressing GCD queue warnings, and accessing variables and implementing callbacks.

Step 1: Creating the Bulb Class and Bridge Header

First, within Xcode, create a new Swift file named Bulb.swift. Also, create a bridging header file (if one doesn't already exist) named LightApp-Bridging-Header.h. This header file allows communication between Swift and Objective-C. Add the following line to the bridging header:

#import <React/RCTBridgeModule.h>

This import provides the necessary interface for bridging.

Next, update Bulb.swift with the following code:

import Foundation

@objc(Bulb)
class Bulb: NSObject {
  @objc static var isOn = false

  @objc func turnOn() {
    Bulb.isOn = true
    print("Bulb is now ON")
  }
}

We've created a Bulb class inheriting from NSObject, making it compatible with Objective-C. The @objc annotation exposes the class and the turnOn function to Objective-C and subsequently to React Native.

Now, update App.js to access the Bulb class:

import React, { Component } from 'react';
import { Text, View, NativeModules, TouchableOpacity, StyleSheet } from 'react-native';

export default class App extends Component {
  turnOn = () => {
    NativeModules.Bulb.turnOn();
  };

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>Welcome to Light App!!</Text>
        <TouchableOpacity onPress={this.turnOn}>
          <Text>Turn On</Text>
        </TouchableOpacity>
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
});

Running the app and checking the Xcode console will confirm that the Swift turnOn method is called from JavaScript.

Step 2: Addressing GCD Queue Warnings

You might encounter warnings related to running native code on the wrong thread. To ensure the native module runs on the main queue, add the following to Bulb.swift:

@objc static func requiresMainQueueSetup() -> Bool {
  return true
}

Step 3: Accessing Variables and Implementing Callbacks

To display the bulb's status in the app, add a getStatus function to Bulb.swift:

@objc func getStatus(_ callback: RCTResponseSenderBlock) {
  callback([NSNull(), Bulb.isOn])
}

This function takes a callback and returns the isOn value. Update App.js to utilize this:

constructor(props) {
  super(props);
  this.state = { isOn: false };
  this.updateStatus();
}

turnOn = () => {
  NativeModules.Bulb.turnOn();
  this.updateStatus();
};

updateStatus = () => {
  NativeModules.Bulb.getStatus((error, isOn) => {
    this.setState({ isOn });
  });
};

render() {
  return (
    <View style={styles.container}>
      <Text style={styles.welcome}>Welcome to Light App!!</Text>
      <TouchableOpacity onPress={this.turnOn}>
        <Text>Turn On</Text>
      </TouchableOpacity>
      <Text>Bulb is {this.state.isOn ? "ON" : "OFF"}</Text>
    </View>
  );
}

Section 2: Native Bridge in Android

Now, let's create the equivalent functionality for Android. Create a Java class named Bulb.java within the Android project and add the following code:

package com.lightapp; // Replace with your app's package name

import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

public class Bulb extends ReactContextBaseJavaModule {
  private static boolean isOn = false;

  public Bulb(ReactApplicationContext reactContext) {
    super(reactContext);
  }

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

  @ReactMethod
  public void turnOn() {
    isOn = true;
    System.out.println("Bulb is turned ON");
  }

  @ReactMethod
  public void getStatus(Callback successCallback) {
    successCallback.invoke(null, isOn);
  }
}

Next, create a Java class named BulbPackage.java and add the following code to register the module:

package com.lightapp; // Replace with your app's package name

import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class BulbPackage implements ReactPackage {

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

  @Override
  public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
    List<NativeModule> modules = new ArrayList<>();
    modules.add(new Bulb(reactContext));
    return modules;
  }
}

Finally, you need to register the BulbPackage in your MainApplication.java file. Import your BulbPackage class, and add it to the getPackages method:

// ... other imports

import com.lightapp.BulbPackage; // Import your BulbPackage

public class MainApplication extends Application implements ReactApplication {

  // ... existing code ...

  @Override
  protected List<ReactPackage> getPackages() {
    @SuppressWarnings("UnnecessaryLocalVariable")
    List<ReactPackage> packages = new PackagesList(this).getPackages();
    // Packages that cannot be autolinked yet can be added manually here, for example:
    // packages.add(new MyReactNativePackage());
    packages.add(new BulbPackage()); // Add this line
    return packages;
  }

  // ... existing code ...
}

The same JavaScript code used for iOS will work for Android as well, demonstrating the cross-platform compatibility of the bridge.

Conclusion

By following these steps, you can effectively create and utilize React Native bridges, unlocking the potential of native functionalities within your cross-platform applications. This allows you to build richer, more performant apps that leverage the best of both worlds. Remember to rebuild your app after making native code changes for them to take effect.

Defx, with its extensive experience in IT services, can help you navigate the complexities of React Native development and create robust, high-quality cross-platform applications.

Need this built?

DEFX ships react native work like this for teams worldwide.

Tell us what you're building and we'll reply within 1 business day — or grab a call slot directly.

Send a request
DEFX EditorialDEFX Team

DEFX builds AI products, ERP platforms, web and mobile apps, and Shopify, Zoho & QuickBooks integrations for teams in the US, CA, UK, UAE, AU, and IN.

Related reads

More DEFX articles on growth-focused product delivery.

Continue with the next most relevant reads on ERP delivery, AI product architecture, ecommerce systems, and mobile execution.

Explore all articles
Artificial Inteligence5 min read

Accelerate AI Development with DEFX's Guide to the Groq API

Learn what the Groq API is, how Groq LPUs deliver ultra-low latency AI inference, how to generate API keys through GroqCloud, integrate with Python and LangChain, and accelerate enterprise AI development with DEFX.

Groq APIGroqCloud
Read article
React Native3 min read

Top 7 Local Databases for High-Performance React Native App Development in 2025

Discover the top 7 local databases for React Native app development in 2025. Compare Realm, Firebase, WatermelonDB, SQLite-based solutions, DynamoDB, and more to build fast, scalable, and offline-first mobile applications.

React NativeMobile App Development
Read article
loT3 min read

Transform Your IoT with DEFX: Seamlessly Connect SIM800L GSM Module to Arduino for SMS, Server, and Remote Monitoring Magic!

Learn how to connect a SIM800L GSM module with Arduino to send and receive SMS, connect to a remote server over GPRS, and build reliable IoT monitoring applications with step-by-step instructions.

ArduinoSIM800L
Read article

Contact us

Tell us what you're building.

Share your idea, timeline, and goals — we'll reply within 1 business day with the fastest path to production.

Prefer to talk it through?
  • Reply within 1 business day
  • NDA-friendly
  • US · CA · UK · UAE · AU · IN
No spam, no drip campaigns — a human reads this.