Skip to content
useffect.sh
Book 30 min with a senior
Architecture

Turbo Modules

Native modules in the New Architecture: a TypeScript spec, code generated by Codegen, and lazy loading through JSI.

Definition

Turbo Modules are the native module system of React Native’s New Architecture. A Turbo Module is made of a typed spec (TypeScript or Flow) describing the methods exposed to JavaScript, the native code implementing them (Kotlin or Java on Android, Objective-C++ or Swift on iOS, or shared C++), and the interfaces Codegen generates from that spec. On the JavaScript side you obtain the module with TurboModuleRegistry.get or getEnforcing. They replace the legacy Native Modules, which were all instantiated at startup and whose every call crossed the bridge as serialized JSON. With JSI, a Turbo Module is loaded on first use and its methods can be invoked synchronously. Writing custom native access without Expo Modules or Nitro, for instance to read a hardware sensor or call a vendor’s payment SDK, means writing a Turbo Module.

In a real app

In a project, a Turbo Module shows up as a codegenConfig key in its package.json (with type: "modules" and a jsSrcsDir) and a spec file whose name starts with Native, for example specs/NativeLocalStorage.ts. On iOS the class is a .mm file adopting the generated protocol; on Android it extends the generated abstract class and is registered in a BaseReactPackage. Codegen runs on every build (a Gradle task on Android, a script phase during pod install on iOS), so a spec that does not compile breaks the native build, not the app at runtime.

The most common pitfall is getEnforcing in an optional library. If the native module is not linked (broken autolinking, a misconfigured monorepo), the app crashes on first import with an unhelpful message. get returns null and leaves room for a fallback. Types are the other one: a method returning Promise<Object> in the spec becomes an NSDictionary or a WritableMap on the native side; rich types do not cross as-is.

For a new module today the choice is between a plain Turbo Module (worth it if you have C++ to share), the Expo Modules API (Swift/Kotlin DSL, less boilerplate), and Nitro Modules (native Swift/Kotlin over JSI, fastest for chatty calls). All three sit on JSI; the React Native docs recommend Turbo Modules if you plan to write C++.

Our services on this

Sources

All 35 glossary terms

One of these is blocking your app?

30 minutes with a senior to look at the problem in your code. Free.