When I first ventured into mobile app development, I quickly realized that certain functionalities could not be fully achieved using just JavaScript alone in frameworks like React Native. That’s when I discovered the power of native modules. If you’re looking to enhance your mobile application with platform-specific features, creating native modules is a fantastic approach. Here’s a step-by-step guide on how to get started.

What Are Native Modules?

Native modules allow you to write native code (Java/Kotlin for Android, Objective-C/Swift for iOS) and bridge it with your React Native code. This gives you access to device capabilities and performance optimizations that pure JavaScript can’t provide.

Step 1: Setting Up Your Development Environment

Before diving into native module creation, ensure you have everything set up:

  1. React Native CLI: You can install it via npm:
    npm install -g react-native-cli
    
  2. Android Studio / Xcode: Install either Android Studio for Android development or Xcode for iOS.

  3. Node.js: Make sure you have Node.js installed, as it’s essential for the development process.

Step 2: Creating a React Native Project

First, create a new React Native project if you haven’t already:

npx react-native init MyApp
cd MyApp

Step 3: Creating the Native Module

For the example, let’s say we want to create a simple module that gets the device’s battery level.

Android (Java)

  1. Navigate to the android/app/src/main/java/com/myapp directory.
  2. Create a new Java file named BatteryModule.java.
  3. Add the following code:
package com.myapp;

import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
import android.content.Context;
import android.os.BatteryManager;

public class BatteryModule extends ReactContextBaseJavaModule {
    private final ReactApplicationContext reactContext;

    public BatteryModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext = reactContext;
    }

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

    @ReactMethod
    public void getBatteryLevel(Promise promise) {
        BatteryManager batteryManager = (BatteryManager) reactContext.getSystemService(Context.BATTERY_SERVICE);
        int batteryLevel = batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY);
        promise.resolve(batteryLevel);
    }
}
  1. Edit MainApplication.java to include your new module.
@Override
  protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
        new MainReactPackage(),
        new BatteryModule() // Add this line
    );
  }

iOS (Swift)

  1. Navigate to ios/MyApp.
  2. Create a new file named BatteryModule.swift.
  3. Add the following code:
import Foundation
import UIKit

@objc(BatteryModule)
class BatteryModule: NSObject {
    @objc func getBatteryLevel(_ callback: @escaping RCTResponseSenderBlock) {
        let batteryLevel = UIDevice.current.batteryLevel
        callback([NSNull(), batteryLevel * 100])
    }
}
  1. Ensure your project can recognize Swift files.

Step 4: Using the Native Module in Your React Native App

Now that your native module is set up, it’s time to use it in your React Native code.

import { NativeModules } from 'react-native';

const { BatteryModule } = NativeModules;

const fetchBatteryLevel = async () => {
    try {
        const batteryLevel = await BatteryModule.getBatteryLevel();
        console.log(`Battery Level: ${batteryLevel}%`);
    } catch (error) {
        console.error(error);
    }
};

fetchBatteryLevel();

Conclusion

Creating native modules can seem daunting at first, but once you understand the flow, it opens up a world of possibilities. I encourage you to explore other native functionalities that you can integrate into your app. For more detailed guidance, you can check out the official documentation here.

Happy coding!

Find more of my blogs at https://nadbn.com/blog