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

Nitro Modules

Margelo’s framework for writing native modules in Swift, Kotlin, or C++ exposed to JavaScript through JSI, with bindings generated from TypeScript.

Definition

Nitro Modules is a framework by Margelo for writing React Native native modules in Swift, Kotlin, or C++. A Nitro module contains Hybrid Objects: native objects whose methods and properties are exposed directly to JavaScript through JSI, relying on jsi::NativeState rather than a HostObject. The TypeScript interface is the source of truth: Nitrogen, the code generator, produces the native bindings from it, and Swift or Kotlin code that does not match the declared types does not compile. Nitro talks to Swift through Swift/C++ interop and to Kotlin through fbjni, with no Objective-C or Java in between, which explains the gap in its benchmarks against Turbo Modules (7.27 ms versus 115.86 ms for 100,000 addition calls, an extreme case by the docs’ own admission). It requires React Native 0.75 or later, Xcode 16.4 and Swift 5.9 or later, compileSdk 34, and NDK 27. You meet it in recent libraries such as react-native-mmkv, or when a custom module has to be called very often.

In a real app

A Nitro module is recognizable by its *.nitro.ts files (the specs), a nitro.json at the root, and the npx nitrogen command that generates the native code. The consuming project installs react-native-nitro-modules as a dependency, and every Nitro library depends on it too. On the JavaScript side, a Hybrid Object is instantiated with NitroModules.createHybridObject<Type>("Name"), and its lifetime is tied to the app’s garbage collector.

The choice depends on the call profile. For an API called a few times per screen, the Expo Modules API or a Turbo Module do the same job with more widespread tooling. Nitro wins when calls are synchronous and frequent (a key-value store read on every render, image processing, audio), or when native code has to hold stateful objects and hand them back to JavaScript without serialization. The price: a more demanding toolchain (Xcode and NDK versions), modern Swift and Kotlin as hard requirements, and a smaller contributor base than Expo’s.

In an audit I check that the minimum versions are respected in expo-build-properties or in the Podfile and build.gradle, that nitrogen actually runs in the build scripts (or that generated files are committed, which is acceptable), and that a Nitro library and a Turbo library are not fighting over the same native resource.

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.