📅 Day 20
💡 tip

Native Modules Showdown: TurboModules vs Expo Modules vs Nitro

Compare the three ways to build native modules in React Native - TurboModules, Expo Modules, and Nitro Modules - and learn when to use each approach

Native ModulesArchitecture

Welcome to Day 20 of the React Native Advent Calendar!

Today we’re comparing the three ways to build native modules in React Native. Whether you need to access device features, optimize performance, or integrate native libraries, you have three powerful options!


The Three Contenders

Building native functionality in React Native has evolved significantly. Today, you have three modern approaches:

  1. TurboModules - Meta’s official solution for the New Architecture
  2. Expo Modules - Expo’s developer-friendly approach with Swift & Kotlin
  3. Nitro Modules - Mark Rousavy’s high-performance C++ framework

Each has different strengths, trade-offs, and ideal use cases. Let’s break them down.


1. TurboModules: Meta’s Official Solution

TurboModules are Meta’s official way to build native modules for React Native’s New Architecture.

What They Are

TurboModules use Codegen to automatically generate native interfaces from TypeScript or Flow type definitions. You write a typed JavaScript spec, and Codegen creates the native glue code for both iOS and Android.

Key Benefits

  • Official React Native solution - First-class support from Meta
  • Type-safe - TypeScript/Flow specs enforce type safety
  • Automated code generation - Codegen eliminates boilerplate
  • New Architecture native - Built for the modern RN runtime
  • Cross-platform - Single spec for iOS and Android

Example: Simple TurboModule Spec

NativeCalendar.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';

export interface Spec extends TurboModule {
	createCalendarEvent(name: string, location: string): Promise<boolean>;
	getCurrentTime(): number;
}

export default TurboModuleRegistry.getEnforcing<Spec>('NativeCalendar');

When to Use TurboModules

Use TurboModules when:

  • You’re building for apps using the New Architecture
  • You want official Meta support
  • You need maximum compatibility with RN ecosystem
  • You’re comfortable with C++/Objective-C++

2. Expo Modules: Developer Experience First

Expo Modules prioritize developer experience with modern Swift and Kotlin APIs.

What They Are

Expo Modules let you write native code in Swift (iOS) and Kotlin (Android) with significantly less boilerplate than traditional approaches. They use JSI (same as TurboModules) for performance.

Key Benefits

  • Modern languages - Swift & Kotlin instead of Objective-C/Java
  • Minimal boilerplate - Expo’s API reduces code by ~90%
  • Great DX - Fast iteration, clear APIs, helpful errors
  • Performance - JSI-based, comparable to TurboModules
  • Works everywhere - Compatible with New Architecture AND legacy
  • Autolinking - Automatic native dependency linking

Example: Simple Expo Module

ExpoCalendarModule.swift
import ExpoModulesCore

public class CalendarModule: Module {
  public func definition() -> ModuleDefinition {
    Name("Calendar")

    // Async function
    AsyncFunction("createEvent") { (name: String, location: String) -> Bool in
      // Create calendar event
      return true
    }

    // Synchronous function
    Function("getCurrentTime") { () -> Double in
      return Date().timeIntervalSince1970
    }
  }
}

That’s it! No bridge code, no manual type conversions, no Codegen configuration.

When to Use Expo Modules

Use Expo Modules when:

  • You want the best developer experience
  • You prefer Swift/Kotlin over C++/Objective-C
  • You need backward compatibility with legacy apps
  • You want minimal boilerplate

3. Nitro Modules: High-Performance C++

Nitro Modules by Mark Rousavy (creator of react-native-vision-camera) focus on maximum performance through C++.

What They Are

Nitro generates type-safe bindings from TypeScript interfaces, creating a zero-overhead bridge between JavaScript and native C++ code. It’s designed for performance-critical modules.

Key Benefits

  • Maximum performance - Highly optimized JSI with caching
  • Type-safe across languages - TypeScript → C++ → Swift/Kotlin
  • C++ power - Direct C++ integration for complex algorithms
  • Minimal overhead - Lightweight memory footprint
  • Flexible types - Supports primitives, objects, arrays, variants
  • HybridObjects - JavaScript-like objects with native backing

Example: Nitro Module Interface

HybridCalendar.nitro.ts
interface HybridCalendar extends HybridObject {
	createEvent(name: string, location: string): Promise<boolean>;
	getCurrentTime(): number;
	// Nitro supports complex types seamlessly
	getAllEvents(): CalendarEvent[];
}

interface CalendarEvent {
	id: string;
	name: string;
	startDate: Date;
	attendees: string[];
}

Nitrogen (Nitro’s codegen) generates:

  • Type-safe C++ bindings
  • Swift/Kotlin implementations
  • Zero-copy data transfer where possible

When to Use Nitro Modules

Use Nitro Modules when:

  • Performance is absolutely critical
  • You’re building compute-intensive features (image processing, ML, etc.)
  • You need C++ integration for third-party libraries
  • You want zero JavaScript-to-native overhead
  • You’re comfortable with C++

The Verdict: Which Should You Use?

For Most Developers: Expo Modules 🏆

Expo Modules offer the best balance of:

  • Developer experience
  • Performance
  • Compatibility
  • Community support

For Performance-Critical Apps: Nitro Modules

Choose Nitro when:

  • You’re building vision/ML features
  • You need C++ integration
  • Performance is non-negotiable

For RN Core Contributors: TurboModules 🏛️

TurboModules make sense when:

  • Contributing to React Native core
  • Building official Meta libraries
  • Maximum ecosystem compatibility required

Wrapping Up

The native module landscape in React Native has matured significantly. You have three excellent options, each with clear strengths.

Quick recap:

  1. TurboModules - Meta’s official solution, great for core RN work
  2. Expo Modules - Best DX, modern languages, works everywhere
  3. Nitro Modules - Maximum performance, C++ power, cutting-edge

Ready to build native modules?

Built a native module? Share your experience on Twitter!

Tomorrow we’ll explore Day 21’s topic - see you then! 🎄