React Native Turbo Modules New Architecture Latest πŸš€



This content originally appeared on DEV Community and was authored by Ajmal Hasan

React Native’s new architecture introduces Turbo Modules, which significantly improve native module communication with JavaScript. This guide will walk you through creating a Swift-based Turbo Module for iOS, ensuring smooth interaction with React Native.

What is a Turbo Module?

A Turbo Module is an advanced native module that offers:

βœ… Faster execution: Direct invocation via JSC/Hermes.
βœ… Automatic TypeScript/Flow integration: Generates native code automatically.
βœ… Efficient memory management: Modules are loaded only when needed.

Prerequisites: Basic React Native knowledge is required. No prior Swift or Objective-C experience is necessary.

Official Documentation

Before diving in, you can explore the official Turbo Modules documentation, which provides comprehensive coverage of Android, Objective-C, JavaScript/TypeScript, and specifications. In this guide, we’ll focus specifically on the iOS Swift implementation to streamline your learning process:

πŸ”— React Native Turbo Modules Introduction

For more insights into the old/new native bridging architecture, explore these articles:

πŸ”— Android Native Bridging in React Native – Part 1
πŸ”— iOS Native Bridging in React Native – Part 2
πŸ”— Build-native-and-turbo-modules

Project Structure

We will create a NativeLocalStorage Turbo Module using Swift.

NativeLocalStorage/
β”œβ”€β”€ RCTNativeLocalStorage.h
β”œβ”€β”€ RCTNativeLocalStorage.mm
β”œβ”€β”€ RCTNativeLocalStorageSwift.swift
β”œβ”€β”€ RN_NewArch-Bridging-Header.h

How to Create These Files in Xcode?

1) Create a New Group (Optional but Recommended)

To keep your project organized, you can create a new group in Xcode:

  • Right-click on the project navigator (left panel in Xcode).
  • Select New Group.
  • Name it NativeLocalStorage (or any preferred name).
  • Move all related files into this group.

2) Create a New File

  • Right-click on the NativeLocalStorage folder (group) in Xcode.
  • Select New File from Template.

3) Bridging Header (RN_NewArch-Bridging-Header.h)

  • When you create a new Swift file in an Objective-C project, Xcode will automatically prompt you to create a bridging header(Only One is Needed).
  • If it is not created automatically, follow these steps:

    1. Select Header File (.h) from the template list.
    2. Name it <ProjectName>-Bridging-Header.h.
    3. Navigate to Build Settings β†’ Swift Compiler – General.
    4. Set Objective-C Bridging Header to:
     $(SRCROOT)/<ProjectName>/<ProjectName>-Bridging-Header.h
    

4) Objective-C Interface (RCTNativeLocalStorage.h)

  • Select Objective-C File (.h) from the template list.
  • Name it RCTNativeLocalStorage.h.

5) Swift Implementation (RCTNativeLocalStorageSwift.swift)

  • Select Swift File (.swift) from the template list.
  • Name it RCTNativeLocalStorageSwift.swift.

6) Objective-C Implementation (RCTNativeLocalStorage.mm)

  • Select Objective-C File (.mm) from the template list.
  • Name it RCTNativeLocalStorage.mm.

1⃣ Bridging Header (RN_NewArch-Bridging-Header.h)

πŸ“Œ Code Explanation:

// RN_NewArch-Bridging-Header.h
#import "RCTAppDelegate.h"
  • This bridging header allows Swift code to interact with Objective-C components in React Native.
  • The #import "RCTAppDelegate.h" ensures compatibility with the React Native app delegate.

2⃣ Objective-C Interface (RCTNativeLocalStorage.h)

πŸ“Œ Code Explanation:

#import <Foundation/Foundation.h>
#import <NativeLocalStorageSpec/NativeLocalStorageSpec.h>

@interface RCTNativeLocalStorage : NSObject <NativeLocalStorageSpec>
@end
  • @interface RCTNativeLocalStorage: Declares the native module class.
  • <NativeLocalStorageSpec>: Ensures the class conforms to the required React Native module interface.
  • @end: Marks the end of the class declaration.

3⃣ Swift Implementation (RCTNativeLocalStorageSwift.swift)

πŸ“Œ Code Explanation:

import Foundation

@objcMembers
class RCTNativeLocalStorageImpl: NSObject {
    private let userDefaults: UserDefaults

    override init() {
        userDefaults = UserDefaults(suiteName: "local-storage") ?? UserDefaults.standard
        super.init()
    }

    func getItem(_ key: String) -> String? {
        return userDefaults.string(forKey: key)
    }

    func setItem(_ value: String, forKey key: String) {
        userDefaults.set(value, forKey: key)
    }

    func removeItem(_ key: String) {
        userDefaults.removeObject(forKey: key)
    }

    func clear() {
        for (key, _) in userDefaults.dictionaryRepresentation() {
            userDefaults.removeObject(forKey: key)
        }
    }
}
  • @objcMembers: Ensures all methods are accessible in Objective-C.
  • UserDefaults: Provides persistent storage for key-value pairs.
  • CRUD Operations:
    • getItem: Fetches a stored value.
    • setItem: Stores a value.
    • removeItem: Deletes a specific item.
    • clear: Removes all stored items.

4⃣ Objective-C Implementation (RCTNativeLocalStorage.mm)

πŸ“Œ Code Explanation:

#import "RCTNativeLocalStorage.h"
#import "RN_NewArch-Swift.h"

@implementation RCTNativeLocalStorage

RCT_EXPORT_MODULE("NativeLocalStorage");

RCTNativeLocalStorageImpl *nativeLocalStorage = [[RCTNativeLocalStorageImpl alloc] init];

- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const facebook::react::ObjCTurboModule::InitParams &)params {
    return std::make_shared<facebook::react::NativeLocalStorageSpecJSI>(params);
}

- (NSString *_Nullable)getItem:(nonnull NSString *)key {
    return [nativeLocalStorage getItem:key];
}

- (void)setItem:(nonnull NSString *)value key:(nonnull NSString *)key {
    [nativeLocalStorage setItem:value forKey:key];
}
  • RCT_EXPORT_MODULE("NativeLocalStorage"): Registers the module with React Native.
  • RCTNativeLocalStorageImpl: Calls the Swift implementation.
  • TurboModule Integration:

    • Uses std::shared_ptr to efficiently manage memory.
  • Bridges Swift functions to Objective-C, allowing React Native to interact with them.

🎯 Summary

βœ… Turbo Modules enhance React Native’s performance by enabling direct communication.\
βœ… We built a Swift-based Turbo Module for local storage.\
βœ… Objective-C wrappers ensured React Native compatibility.\
βœ… This setup allows Swift-based Turbo Modules to be used in React Native projects seamlessly.

πŸš€ Now you can build custom Turbo Modules in Swift! πŸš€


This content originally appeared on DEV Community and was authored by Ajmal Hasan