React Native is a powerful framework for building cross-platform mobile applications using JavaScript and React. However, sometimes, we need to interact with platform-specific features that aren’t available in JavaScript. This is where native modules come in. In this blog, we will explore how to work with native modules and native code in both Android and iOS for React Native applications.
What Are Native Modules?
Native modules allow you to write platform-specific code in Java/Kotlin (Android) or Objective-C/Swift (iOS) and expose it to JavaScript. This is useful for accessing device features like Bluetooth, biometrics, or background services that aren’t available in React Native out of the box.
When to Use Native Modules?
- When you need access to platform-specific APIs (e.g., sensors, file system, background tasks).
- When a third-party React Native library does not meet your requirements.
- When performance is critical, and JavaScript alone isn’t sufficient.
Setting Up a Native Module in Android (Java/Kotlin)
Step 1: Create a New Native Module
- Navigate to the android directory in your React Native project.
- Inside
android/app/src/main/java/com/yourappname/, create a new package for your module (e.g., NativeExample).
Step 2: Create a Java/Kotlin File
For Java:
Create a new file NativeExampleModule.java inside the new package:
package com.yourappname.NativeExample;
import androidx.annotation.NonNull;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
public class NativeExampleModule extends ReactContextBaseJavaModule {
public NativeExampleModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@NonNull
@Override
public String getName() {
return "NativeExample";
}
@ReactMethod
public void getDeviceName(Promise promise) {
try {
String deviceName = android.os.Build.MODEL;
promise.resolve(deviceName);
} catch (Exception e) {
promise.reject("ERROR", e);
}
}
}
Step 3: Register the Module
In
android/app/src/main/java/com/yourappname/NativeExample/NativeExamplePackage.java:
package com.yourappname.NativeExample;
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 NativeExamplePackage implements ReactPackage {
@Override
public List createNativeModules(ReactApplicationContext reactContext) {
List modules = new ArrayList<>();
modules.add(new NativeExampleModule(reactContext));
return modules;
}
@Override
public List createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
Step 4: Link the Module to React Native
Modify MainApplication.java to include the package:
import com.yourappname.NativeExample.NativeExamplePackage;
@Override
protected List getPackages() {
return Arrays.asList(
new MainReactPackage(),
new NativeExamplePackage()
);
}
Step 5: Use the Native Module in JavaScript
import { NativeModules } from 'react-native';
const { NativeExample } = NativeModules;
NativeExample.getDeviceName()
.then((name) => console.log('Device Name:', name))
.catch((error) => console.error(error));
Setting Up a Native Module in iOS (Swift/Objective-C)
Step 1: Create a Native Module
Navigate to ios/ in your project and create a new Swift file, NativeExample.swift.
Step 2: Implement the Native Module in Swift
import Foundation
import React
@objc(NativeExample)
class NativeExample: NSObject {
@objc static func requiresMainQueueSetup() -> Bool {
return false
}
@objc func getDeviceName(_ resolve: @escaping RCTPromiseResolveBlock, rejecter reject: @escaping RCTPromiseRejectBlock) {
resolve(UIDevice.current.name)
}
}
Step 3: Expose the Module to React Native
Modify
ios/NativeExampleBridge.m:
#import <React/RCTBridgeModule.h>
@interface RCT_EXTERN_MODULE(NativeExample, NSObject)
RCT_EXTERN_METHOD(getDeviceName:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
@end
Step 4: Use the Native Module in JavaScript
Same as Android:
import { NativeModules } from 'react-native';
const { NativeExample } = NativeModules;
NativeExample.getDeviceName()
.then((name) => console.log('Device Name:', name))
.catch((error) => console.error(error));
Conclusion
Native modules provide a way to extend React Native’s capabilities by integrating platform-specific code. Whether you’re working with Android or iOS, you can build and expose native functionality to JavaScript, allowing for a more seamless development experience. While third-party libraries often solve most needs, knowing how to write native modules gives you more flexibility and control over your React Native applications.