Skip to main content
Native modules allow you to write platform-specific code that can be invoked from JavaScript. This enables you to access native APIs and functionality that aren’t available through React Native’s standard components.

What are Native Modules?

Native modules are platform-specific classes that implement native functionality and expose it to JavaScript through React Native’s bridge. They allow you to:
  • Access platform APIs not covered by React Native
  • Reuse existing native libraries
  • Optimize performance-critical code
  • Integrate with native SDKs and services

Architecture

Native modules work through React Native’s bridge, which facilitates communication between JavaScript and native code:
JavaScript Layer

   Bridge

Native Layer (iOS/Android)

Key Components

Module Interface: Defines the contract between JavaScript and native code Method Annotation: Marks methods that should be exposed to JavaScript Type Conversion: Automatically converts between JavaScript and native types Threading: Native methods execute on a dedicated thread (not the UI thread by default)

Core Concepts

Module Registration

Native modules must be registered with React Native to be accessible from JavaScript:
  • Android: Modules extend ReactContextBaseJavaModule and are registered via ReactPackage
  • iOS: Modules implement RCTBridgeModule protocol and use RCT_EXPORT_MODULE macro

Method Export

Methods exposed to JavaScript must be explicitly marked:
  • Android: Use @ReactMethod annotation
  • iOS: Use RCT_EXPORT_METHOD macro

Type Support

Native modules support automatic type conversion for:
  • Primitives: boolean, int, float, double, string
  • Collections: Arrays and Maps/Dictionaries
  • Special types: Callbacks, Promises

Callbacks and Promises

Native modules can communicate results back to JavaScript using: Callbacks: Traditional callback pattern for asynchronous operations Promises: Modern async/await compatible promise pattern Events: For continuous data streams or notifications

When to Use Native Modules

Consider creating a native module when you need to:
  • Access platform-specific APIs (camera, sensors, etc.)
  • Integrate third-party native SDKs
  • Implement performance-critical operations
  • Reuse existing native code
  • Access features not available in React Native

Module Lifecycle

Initialization

Modules are typically initialized lazily when first accessed from JavaScript. You can control initialization behavior:
  • Android: Modules receive ReactApplicationContext in constructor
  • iOS: Implement requiresMainQueueSetup to control initialization timing

Cleanup

Modules should clean up resources when the React Native instance is destroyed:
  • Android: Override invalidate() method
  • iOS: Implement invalidate method

Threading Model

Android

By default, all @ReactMethod calls execute on a dedicated native modules thread, not the UI thread. If you need to update UI, dispatch to the main thread:
UiThreadUtil.runOnUiThread(() -> {
    // UI updates here
});

iOS

By default, methods execute on a dedicated queue. To run on the main queue, you can dispatch explicitly:
dispatch_async(dispatch_get_main_queue(), ^{
    // UI updates here
});

Next Steps

Now that you understand the basics, learn how to create native modules for each platform:

Best Practices

  • Keep modules focused on a single responsibility
  • Use promises for asynchronous operations when possible
  • Handle errors gracefully and report them to JavaScript
  • Document your module’s API thoroughly
  • Test on both platforms if building cross-platform modules
  • Avoid blocking the UI thread with long-running operations

Build docs developers (and LLMs) love