Native Module in React Native — wat is het, hoe aan te maken en te integreren

Auteur: IT Sectr Gepubliceerd: 2026-06-03 Leestijd: 9 min

Native Module is een Java of Objective-C klasse die native API’s van het platform toegankelijk maakt vanuit JavaScript in React Native. Elke module wordt geregistreerd in de Bridge en exporteert methoden die vanuit JS-code als gewone functies kunnen worden aangeroepen. Volgens Meta, 2024 blijft Native Module de belangrijkste manier om platformcode te integreren in React Native-applicaties.

Belangrijkste punten

  • Native Module — de brug tussen JavaScript en native iOS- of Android-code.
  • Registratie — de module wordt gedeclareerd via iOS- (RCT_EXPORT_MODULE) of Android-annotaties (@ReactMethod).
  • Gegevenstypen — primitieven, strings, arrays, woordenboeken en Promise worden ondersteund.
  • Gebruik — vanuit JS is de module toegankelijk via NativeModules.ModuleNaam.
  • Nieuwe architectuur — in React Native 0.76+ kan Native Module als Turbo Module via JSI werken.

Wat is Native Module?

Native Module is een architecturale component van React Native waarmee code in de platformtaal (Objective-C/Swift voor iOS, Java/Kotlin voor Android) kan worden uitgevoerd en het resultaat aan JavaScript kan worden teruggegeven. Zonder Native Module is toegang tot native apparaatmogelijkheden — camera, GPS, accelerometer, bestandssysteem of Bluetooth — onmogelijk.

React Native wordt geleverd met een set ingebouwde Native Modules: CameraRoll, AsyncStorage, Geolocation, NetInfo en andere. Voor specifieke taken — integratie van externe SDK’s, werken met hardwaresensoren of achtergrondprocessen — maakt de ontwikkelaar echter eigen modules. Volgens de State of React Native 2024-enquête gebruikt 67% van de ontwikkelaars ten minste één aangepaste Native Module in hun projecten.

De architectuur van Native Module hangt af van de React Native-versie. In de klassieke architectuur (React Native 0.72 en ouder) wordt de module via Bridge verbonden en communiceert asynchroon met JS via JSON-serialisatie. In de nieuwe architectuur (React Native 0.76+) kan de module als Turbo Module werken, met behulp van JSI voor synchrone toegang zonder serialisatie.

Native Module aanmaken voor iOS

Het aanmaken van een Native Module voor iOS begint met het declareren van een Objective-C-klasse die het RCTBridgeModule-protocol implementeert. De macro RCT_EXPORT_MODULE registreert de module in de Bridge en RCT_EXPORT_METHOD exporteert een methode die toegankelijk is vanuit JavaScript.

objective-c
// ImageCompressor.m — Native Module voor iOS
@interface ImageCompressor () RCT_EXPORT_MODULE()
@end

@implementation ImageCompressor

RCT_EXPORT_METHOD(compressImage:(NSString *)imagePath
                  quality:(NSNumber *)quality
                  resolver:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject)
{
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];
    NSData *compressedData = [UIImageJPEGRepresentation(image, quality.floatValue)];
    NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"compressed.jpg"];
    [compressedData writeToFile:outputPath atomically:YES];
    resolve(outputPath);
}

@end

De methode compressImage ontvangt het pad naar de afbeelding en de compressiekwaliteit (0.0–1.0), verwerkt de gegevens aan de native kant en retourneert het pad naar het gecomprimeerde bestand. Het belangrijkste voordeel — compressie wordt uitgevoerd met native code, wat aanzienlijk sneller en geheugenefficiënter is dan een vergelijkbare bewerking in JavaScript.

Voor Swift-modules wordt de annotatie @objc voor de klasse en methoden gebruikt, zodat ze toegankelijk zijn voor de Objective-C runtime waar Bridge mee werkt. De klasse moet overerven van NSObject en RCTBridgeModule implementeren.

swift
// ImageCompressor.swift — Swift Native Module
@objc(ImageCompressor)
class ImageCompressor: NSObject {

    @objc
    func compressImage(
        _ imagePath: String,
        quality: Float,
        resolver: @escaping RCTPromiseResolveBlock,
        rejecter: @escaping RCTPromiseRejectBlock
    ) {
        guard let image = UIImage(contentsOfFile: imagePath) else {
            rejecter("FILE_ERROR", "Cannot load image", nil)
            return
        }
        guard let data = image.jpegData(compressionQuality: CGFloat(quality)) else {
            rejecter("COMPRESS_ERROR", "Compression failed", nil)
            return
        }
        let outputPath = NSTemporaryDirectory() + "compressed.jpg"
        try? data.write(to: URL(fileURLWithPath: outputPath))
        resolver(outputPath)
    }
}

Native Module aanmaken voor Android

Op Android wordt Native Module gemaakt als een Java-klasse die overerft van ReactContextBaseJavaModule. De annotatie @ReactMethod exporteert de methode naar de Bridge. Voor het retourneren van het resultaat wordt de Promise-interface uit com.facebook.react.bridge gebruikt.

java
// ImageCompressorModule.java — Android Native Module
public class ImageCompressorModule
    extends ReactContextBaseJavaModule {

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

    @ReactMethod
    public void compressImage(
            String imagePath,
            Float quality,
            Promise promise) {
        try {
            Bitmap bitmap = BitmapFactory.decodeFile(imagePath);
            File outputFile = new File(
                ReactNative.getApplicationContext()
                    .getCacheDir(), "compressed.jpg");
            FileOutputStream fos = new FileOutputStream(outputFile);
            bitmap.compress(
                Bitmap.CompressFormat.JPEG,
                (int)(quality * 100), fos);
            fos.close();
            promise.resolve(outputFile.getAbsolutePath());
        } catch (Exception e) {
            promise.reject("COMPRESS_ERROR", e.getMessage());
        }
    }
}

De methode getName() retourneert de naam van de module waaronder deze toegankelijk is vanuit JavaScript. In het gegeven voorbeeld wordt de module geregistreerd als ImageCompressor. De annotatie @ReactMethod geeft de Bridge aan dat de methode moet worden geëxporteerd. Belangrijk: methoden moeten void zijn en alleen typen accepteren die door Bridge worden ondersteund: String, Boolean, Integer, Double, ReadableArray, ReadableMap, Promise.

Na het maken van de klasse moet de module worden geregistreerd in het applicatiepakket. Hiervoor wordt een klasse gemaakt die ReactPackage implementeert en toegevoegd aan de lijst met modules in de methode createNativeModules.

java
// ImageCompressorPackage.java — moduleregistratie
public class ImageCompressorPackage implements ReactPackage {

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

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

Native Module registreren en gebruiken

Na het aanmaken van de modules voor beide platforms moeten ze worden geregistreerd in React Native. Voor Android wordt het pakket toegevoegd in MainApplication.java in de methode getPackages(). Voor iOS wordt de module automatisch geregistreerd via de macro RCT_EXPORT_MODULE, maar handmatige registratie in het bestand AppDelegate.mm is ook mogelijk.

java
// MainApplication.java — pakket toevoegen aan React Native
import com.yourapp.nativemodules.ImageCompressorPackage;

public class MainApplication extends Application
    implements ReactApplication {

    private final ReactNativeHost mReactNativeHost =
        new ReactNativeHost(this) {

        @Override
        protected List<ReactPackage> getPackages() {
            List<ReactPackage> packages =
                new PackageList(this).getPackages();
            packages.add(new ImageCompressorPackage());
            return packages;
        }
    };
}

Na registratie wordt de module toegankelijk in JavaScript via NativeModules. React Native vervangt automatisch de modulenaam die is opgegeven in getName() voor Android of in RCT_EXPORT_MODULE voor iOS.

js
// Native Module gebruiken vanuit JavaScript
import { NativeModules } from 'react-native';
import { Platform } from 'react-native';

const ImageCompressor = NativeModules.ImageCompressor;

async function compressPhoto(uri: string) {
  try {
    const result = await ImageCompressor.compressImage(
      uri.replace('file://', ''), 0.8
    );
    console.log('Gecomprimeerd:', result);
    return result;
  } catch (error) {
    console.error('Compressie mislukt:', error);
    throw error;
  }
}

Native Module vs Turbo Module: vergelijking

Een vergelijking van klassieke Native Module en Turbo Module helpt te begrijpen welke aanpak voor een nieuw project te kiezen. Beide mechanismen bieden toegang tot native code, maar verschillen fundamenteel in architectuur en prestaties.

KenmerkNative Module (Bridge)Turbo Module (JSI)
CommunicatieAsynchroon via JSONSynchroon via JSI
SerialisatieJSON bij elke aanroepZonder gegevenskopiering
TyperingHandmatig, zonder generatieAutomatisch via Codegen
LadenBij initialisatie van de appLazy load
CompatibiliteitAlle React Native-versiesReact Native 0.73+

Voor bestaande projecten op React Native 0.72 en ouder blijft klassieke Native Module de belangrijkste keuze. Voor nieuwe projecten wordt het gebruik van Turbo Module aanbevolen, vooral als hoge prestaties vereist zijn bij frequente aanroepen van native methoden. Met de geleidelijke update van React Native beweegt de gemeenschap richting een volledige overgang naar de nieuwe architectuur.

Veelgestelde vragen

Kan ik een callback doorgeven in plaats van Promise in Native Module?

Ja, Bridge ondersteunt callbacks. In plaats van Promise kunnen de callback-functies RCTResponseSenderBlock in iOS en Callback in Android worden gebruikt. Promise wordt echter beschouwd als de moderne standaard en wordt aanbevolen voor nieuwe modules.

Hoe debug ik Native Module in Xcode of Android Studio?

Native Module wordt gedebugd als gewone native code — plaats breekpunten in Xcode of Android Studio. Gebruik voor iOS het buildschema met React Native, voor Android — Debug-configuratie. Het toegangspunt — methoden die vanuit JS worden aangeroepen.

Welke gegevenstypen worden NIET ondersteund door Native Module?

Native Module ondersteunt via Bridge geen binaire gegevens (NSData/byte[]), aangepaste objecten en functies. Gebruik voor het verzenden van afbeeldingen het bestandspad of een base64-string. Turbo Module via JSI verwijdert een deel van deze beperkingen.

Moet ik Native Module herschrijven bij het updaten van React Native?

Meestal niet — Native Module API is stabiel en achterwaarts compatibel. Bij de overgang naar de nieuwe architectuur (Turbo Module) wordt de module aangepast via decorators, maar bestaande code blijft werken.

Hoe stuur ik een gebeurtenis van Native Module naar JavaScript?

Gebruik RCTEventEmitter in iOS of DeviceEventEmitter in Android. De module verzendt de gebeurtenis en de JS-kant abonneert zich via NativeEventEmitter uit react-native. Dit is handig voor streaminggegevens en sensorgebeurtenissen.

Samenvatting

  • Native Module — Java/Objective-C klasse die native API’s toegankelijk maakt vanuit JavaScript in React Native.
  • Registratie — iOS gebruikt RCT_EXPORT_MODULE, Android — ReactContextBaseJavaModule met @ReactMethod.
  • Aanroep — vanuit JS is de module toegankelijk via NativeModules.Module en ondersteunt Promise en callback.
  • Gegevenstypen — Bridge verzendt alleen JSON-compatibele typen: strings, getallen, arrays, woordenboeken.
  • Prestaties — klassieke Native Module presteert slechter dan Turbo Module vanwege asynchroniteit en serialisatie.
  • Migratie — bij overgang naar React Native 0.76+ kan de module als Turbo Module werken zonder logica te herschrijven.
  • Toepassing — Native Module is onmisbaar voor camera, Bluetooth, bestandssysteem en SDK-integratie.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook