RN CLI App with local turbo module
📖 Official Guide: Native Modules
Prefer reading code? Skip this README and check out the code changes
A React Native project demonstrating the in-app integration of Turbo Modules with both iOS and Android platforms. This project shows how to create localStorage using Android SharedPreferences (Kotlin) and NSUserDefaults (Objective-C), and showcases a structure.
TurboModuleExample/
├── 📱 App.tsx # Main React Native app demonstrating localStorage usage
├── 📦 package.json # where codegen configuration lives
├── 📝 specs/ # TypeScript Turbo Module specifications directory
│ └── NativeLocalStorage.ts # 🔧 Turbo Module interface for localStorage operations (spec file)
├── 🍎 ios/
│ └── NativeLocalStorage/ # iOS Turbo Module implementation
│ ├── RCTNativeLocalStorage.h # Obj-C header file (Objective-C)
│ └── RCTNativeLocalStorage.mm # implementation of generated NativeLocalStorageSpec interface using NSUserDefaults (Objective-C++)
└── 🤖 android/
└── app/src/main/java/
├── com/turbomoduleexample/
│ └── MainApplication.kt # app entry point with package registration
└── com/nativelocalstorage/ # our Turbo Module namespace
├── NativeLocalStorageModule.kt # implementation of generated NativeLocalStorageSpec interface using SharedPreferences
└── NativeLocalStoragePackage.kt # provides an object to register our Module in the React Native runtime, by wrapping it as a Base Native Package
React Native development environment
- Create the spec file
Take note of our module name "NativeLocalStorage".
This'll get used (prefixed or suffixed) once we write our iOS / Android files.
// in specs/NativeLocalStorage.ts
import type { TurboModule } from 'react-native';
import { TurboModuleRegistry } from 'react-native';
export interface Spec extends TurboModule {
setItem(value: string, key: string): void;
getItem(key: string): string | null;
removeItem(key: string): void;
clear(): void;
}
export default TurboModuleRegistry.getEnforcing<Spec>(
'NativeLocalStorage',
);- Create codegen config
"android"&"ios"keys to tell React Native about the link between the JS specs of the Native Module and the concrete implementation of those specs in native code
// in package.json
"codegenConfig": {
// name of the interface generated by codegen
// 💡 we'll use this later once we start implementing android / ios code
// *Spec is the suffix
"name": "NativeLocalStorageSpec",
"type": "modules",
"jsSrcsDir": "specs",
"android": {
// 💡 our android namespace
// normally, a name close to our module name
"javaPackageName": "com.nativelocalstorage"
},
"ios": {
"modulesProvider": {
// 💡 "RCT*" is a prefix required
"NativeLocalStorage": "RCTNativeLocalStorage"
}
}
},- Run codegen
💡 Unlike Nitro Modules, you won't see generated files after running these commands
# Android
cd android && ./gradlew generateCodegenArtifactsFromSchema# iOS
cd ios && rm -rf Pods Podfile.lock && bundle install && bundle exec pod install && cd ..- Write Application Code using the Turbo Native Module (See
App.tsx)
You'll see that we imported our spec file (
NativeLocalStorage.ts) intoApp.tsx.💡 To organize this in a larger codebase, simply create
*Module.tsfiles in a new dir calledsrc/moduleswhere each spec file imports will live and be consumed.e.g. LocalStorageModule.ts file that exports LocalStorageModule object with functions like getItem etc.
- Write Native Platform Code
You'll be asked to create:
- android/app/src/main/java/com/nativelocalstorage/NativeLocalStorageModule.kt
- android/app/src/main/java/com/nativelocalstorage/NativeLocalStoragePackage.kt
💡 If you copied from the guide, you might get some lint warnings once you open the implementation code (NativeLocalStorageModule.kt) in Android Studio, but there's an autofix if you highlight the yellow line and press (
option + returnkeys)
See Android - Kotlin Guide
💡 If XCode prompts to create a
swift objective c bridging headerwhile creating Cocoa Touch Class (RCTNativeLocalStorage), skip it, otherwise build is going to fail. We're not going to use Swift in this example.Similar to android, if you get warnings when writing in the Obj-C++ file (RCTNativeLocalStorage.mm), there's a pop up if you click warnings and a fix button.
See iOS - Obj-C Guide
At this point, you need to re-install the pods to make sure that codegen runs again to generate the new files:
# iOS
yarn pods- Run the app
yarn android
# OR
yarn ios