Skip to main content

How to build a Nitro Module

A Nitro Module is essentially just a react-native library that depends on react-native-nitro-modules and exposes one or more Hybrid Objects. It can either just use react-native-nitro-modules directly from C++, or use Nitrogen to generate bindings from TypeScript to native - in this case you can even use Swift and Kotlin.

This is a quick guide to build a Nitro Module from start to finish:

1. Create a Nitro Module

First, you need to create a Nitro Module - either by bootstrapping a template using nitrogen, react-native-builder-bob or create-nitro-module - or by manually adding Nitro to your existing library/app.

npx nitro-codegen@latest init

2. Create Hybrid Object specs

To actually use Nitro, you need to create Hybrid Objects - either by using Nitro's code-generator CLI “Nitrogen”, or by just manually extending the HybridObject base class in C++.

2.1. Write the HybridObject specs

A spec is just a *.nitro.ts file that exports an interface, which extends HybridObject:

Math.nitro.ts
export interface Math extends HybridObject {
add(a: number, b: number): number
}

2.2. Run nitrogen

After writing specs, re-generate the generated code by running nitrogen:

npx nitro-codegen

This then will generate a native specs which you can implement - in C++, that'd be HybridMathSpec.hpp.

2.3. Implement the generated native specs

Create a new file (e.g. ios/HybridMath.swift), and implement the HybridMathSpec protocol:

HybridMath.swift
class HybridMath : HybridMathSpec {
public func add(a: Double, b: Double) throws -> Double {
return a + b
}
}

3. (Optional) Register Hybrid Objects

Each Hybrid Object you want to be able to construct from JS has to be registered in Nitro's HybridObjectRegistry. If you don't want to register this Hybrid Object, you can skip this part - you will still be able to create it from another Hybrid Object's function (e.g. using the Factory-pattern).

You can either use Nitrogen to automatically generate bindings for your Hybrid Object's constructor, or manually register them using the C++ API for HybridObjectRegistry:

In your nitro.json config, you can connect the name of the Hybrid Object ("Math") with the name of the native C++/Swift/Kotlin class that you used to implement the spec (HybridMath) using the autolinking section:

nitro.json
{
...
"autolinking": {
"Math": {
"swift": "HybridMath"
}
}
}

Now, just run Nitrogen again to generate the native bindings:

npx nitro-codegen

4. Use your Hybrid Objects in JS

Lastly, you can initialize and use the registered Hybrid Objects from JS. This is what this will ultimately look like:

interface Math extends HybridObject {
add(a: number, b: number): number
}

const math = NitroModules.createHybridObject<Math>("Math")
const result = math.add(5, 7) // --> 12

5. Run it

To test the library you just created, you now need to set up an example app for it.

Nitro's template does not include an example app by default, which makes it easier to be used in monorepos. To create an example app yourself - for example with Expo - run create-expo-app:

npx create-expo-app@latest

Then, install the library in the example app - e.g. via:

cd example
npm install ../