# react-native-nitro-modules

> Fast, type-safe native modules for React Native with statically compiled JSI bindings.

Latest version **0.37.2** (published 2026-11-03) · MIT license · 0 weekly downloads

## Install

```sh
npm install react-native-nitro-modules
pnpm add react-native-nitro-modules
yarn add react-native-nitro-modules
bun add react-native-nitro-modules
```

## Health

**Score 75/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; has provenance; recently updated; high maintenance score; high quality score.

Warnings: low downloads; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.37.2 |
| Published | 2026-11-03 |
| First published | 2024-06-15 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 1 |
| Unpacked size | 476 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Provenance | attested (GitHub Actions) |
| GitHub stars | 1967 |
| Author | Marc Rousavy |
| Maintainers | mrousavy |
| Keywords | react-native, nitro, ios, android, visionOS, tvOS, macOS, cpp, framework, react, swift, native, modules, fast, jsi, turbo, scaffold, template, views |

## Links

- npm: https://www.npmjs.com/package/react-native-nitro-modules
- Repository: https://github.com/margelo/nitro
- Homepage: https://nitro.margelo.com
- Issues: https://github.com/margelo/nitro/issues
- npm.io page: https://npm.io/package/react-native-nitro-modules

## Dependencies (1)

- [nitro-core](https://npm.io/package/nitro-core.md) 0.37.2

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 0.37.2 (latest) — 2026-11-03
- 0.37.3-nightly.132.ge199d0eb6bc4 (nightly) — 2026-11-09
- 1.0.0-alpha.nightly.124.g8a95de8fa7e3 (alpha-nightly) — 2026-11-09
- 0.37.2-nightly.32.gcd7b91624dde (nightly-7f18a1a6bd0d) — 2026-10-20
- 0.37.0-beta.1 (beta) — 2026-08-20
- 0.37.3-nightly.129.g7a8a51bd8d7a — 2026-11-09
- 0.37.3-nightly.123.gaf4aa5051ae5 — 2026-11-09
- 0.37.3-nightly.122.gb973d8d69ab7 — 2026-11-09
- 1.0.0-alpha.nightly.120.g33ef045b96c0 — 2026-11-02
- 1.0.0-alpha.nightly.115.gcdaf72e60229 — 2026-11-02
- 0.37.2-nightly.106.g4f552b03cc0f — 2026-11-02
- 1.0.0-alpha.nightly.105.g69d365fc9b18 — 2026-10-28
- 0.37.2-nightly.101.ge91b20f798c8 — 2026-10-27
- 1.0.0-alpha.nightly.102.g7b2ac8cfaaf9 — 2026-10-27
- 1.0.0-alpha.nightly.100.g107f6fc66597 — 2026-10-23
- … 133 more at https://npm.io/package/react-native-nitro-modules/versions

## README

<a href="https://nitro.margelo.com">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/margelo/nitro/main/docs/static/img/banner-react-native-nitro-modules-dark.png" />
    <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/margelo/nitro/main/docs/static/img/banner-react-native-nitro-modules-light.png" />
    <img alt="React Native Nitro Modules" src="https://raw.githubusercontent.com/margelo/nitro/main/docs/static/img/banner-react-native-nitro-modules-light.png" />
  </picture>
</a>

<br />

**react-native-nitro-modules** is the core React Native Nitro package for building fast, type-safe native modules with statically compiled JSI bindings.

It uses JSI to generate C++ templates that can bridge virtually any JS type to a C++ type with minimal overhead.

## Installation

### Inside an app

Install [react-native-nitro-modules](https://npmjs.org/react-native-nitro-modules) as a `dependency` in your react-native app:
```sh
npm i react-native-nitro-modules
cd ios && pod install
```

The package re-exports the shared `nitro-core` API and installs it into the React Native runtime.

### Inside a nitro module library

If you are building a nitro module yourself, add [react-native-nitro-modules](https://npmjs.org/react-native-nitro-modules) as a `peerDependency` into your library's `package.json`:

```json
{
  ...
  "peerDependencies": {
    ...
    "react-native-nitro-modules": "*"
  },
}
```

Then install `react-native-nitro-modules` as a normal `dependency` in your library's `example/` app as seen above.

## Usage

**react-native-nitro-modules** can either be used with-, or without nitrogen, or mixed (some objects are automatically generated, some manually).

### With Nitrogen

When using Nitrogen, all the bindings are automatically generated. You only need to implement C++, Swift or Kotlin interfaces inside your codebase.

### Without Nitrogen

All C++ bindings are bridged to JS using "Hybrid Objects".

A Hybrid Object can have both methods and properties (get and set).
Create a C++ Hybrid Object by inheriting from `HybridObject`:

```cpp
#include <NitroModules/HybridObject.hpp>

using namespace margelo::nitro;

class MyHybridObject: public HybridObject {
public:
  explicit MyHybridObject(): HybridObject(TAG) {}

public:
  // Property (get)
  double getNumber() { return 13; }
  // Property (set)
  void setNumber(double value) { }
  // Method
  double add(double left, double right) { return left + right; }

public:
  void loadHybridMethods() override {
    // Call base method to make sure we properly inherit `toString()` and `equals()`
    HybridObject::loadHybridMethods();
    // Register all methods that need to be exposed to JS
    registerHybrids(this, [](Prototype& prototype) {
      prototype.registerHybridGetter("number", &MyHybridObject::getNumber);
      prototype.registerHybridSetter("number", &MyHybridObject::setNumber);
      prototype.registerHybridMethod("add", &MyHybridObject::add);
    });
  }

private:
  static constexpr auto TAG = "MyHybrid";
};
```

The `MyHybridObject` can then be registered in the [`HybridObjectRegistry`](https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/cpp/registry/HybridObjectRegistry.hpp) at app startup:

```cpp
#include <NitroModules/HybridObjectRegistry.hpp>

// Call this at app startup to register the HybridObjects
void load() {
  HybridObjectRegistry::registerHybridObjectConstructor(
    "MyHybrid",
    []() -> std::shared_ptr<HybridObject> {
      return std::make_shared<MyHybridObject>();
    }
  );
}
```

Inside your `MyHybridObject`, you can use standard C++ types which will automatically be converted to JS using Nitro's [`JSIConverter<T>`](https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/cpp/jsi/JSIConverter.hpp) interface.

The following C++ / JS types are supported out of the box:

<table>
  <tr>
    <th>JS Type</th>
    <th>C++ Type</th>
    <th>Swift Type</th>
    <th>Kotlin Type</th>
  </tr>

  <tr>
    <td><code>number</code></td>
    <td><code>double</code> / <code>int</code> / <code>float</code></td>
    <td><code>Double</code></td>
    <td><code>Double</code></td>
  </tr>
  <tr>
    <td><code>boolean</code></td>
    <td><code>bool</code></td>
    <td><code>Bool</code></td>
    <td><code>Boolean</code></td>
  </tr>
  <tr>
    <td><code>string</code></td>
    <td><code>std::string</code></td>
    <td><code>String</code></td>
    <td><code>String</code></td>
  </tr>
  <tr>
    <td><code>Int64</code> (<code>bigint</code>)</td>
    <td><code>int64_t</code></td>
    <td><code>Int64</code></td>
    <td><code>Long</code></td>
  </tr>
  <tr>
    <td><code>UInt64</code> (<code>bigint</code>)</td>
    <td><code>uint64_t</code></td>
    <td><code>UInt64</code></td>
    <td><code>ULong</code></td>
  </tr>
  <tr>
    <td><code>T[]</code></td>
    <td><code>std::vector&lt;T&gt;</code></td>
    <td><code>[T]</code></td>
    <td><code>Array&lt;T&gt;</code> / <code>PrimitiveArray</code></td>
  </tr>
  <tr>
    <td><code>[A, B, C, ...]</code></td>
    <td><code>std::tuple&lt;A, B, C, ...&gt;</code></td>
    <td><code>(A, B, C)</code> 🟡  (<a href="https://github.com/margelo/nitro/issues/38">#38</a>)</td>
    <td>❌</td>
  </tr>
  <tr>
    <td><code>A | B | C | ...</code></td>
    <td><code>std::variant&lt;A, B, C, ...&gt;</code></td>
    <td><code>Variant_A_B_C</code></td>
    <td><code>Variant_A_B_C</code></td>
  </tr>
  <tr>
    <td><code>Record&lt;string, T&gt;</code></td>
    <td><code>std::unordered_map&lt;std::string, T&gt;</code></td>
    <td><code>Dictionary&lt;String, T&gt;</code></td>
    <td><code>Map&lt;std::string, T&gt;</code></td>
  </tr>
  <tr>
    <td><code>T?</code></td>
    <td><code>std::optional&lt;T&gt;</code></td>
    <td><code>T?</code></td>
    <td><code>T?</code></td>
  </tr>
  <tr>
    <td><code>null</code></td>
    <td><code>NullType</code></td>
    <td><code>NullType</code></td>
    <td><code>NullType</code></td>
  </tr>
  <tr>
    <td><code>(T...) =&gt; void</code></td>
    <td><code>std::function&lt;void (T...)&gt;</code></td>
    <td><code>@escaping (T...) -&gt; Void</code></td>
    <td><code>(T...) -&gt; Unit</code></td>
  </tr>
  <tr>
    <td><code>(T...) =&gt; R</code></td>
    <td><code>std::function&lt;std::shared_ptr&lt;<a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/cpp/core/Promise.hpp">Promise&lt;R&gt;</a>&gt; (T...)&gt;</code></td>
    <td><code>(T...) -&gt; <a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/apple/core/Promise.swift">Promise&lt;T&gt;</a></code></td>
    <td><code>(T...) -&gt; <a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/android/src/main/java/com/margelo/nitro/core/Promise.kt">Promise&lt;T&gt;</a></code></td>
  </tr>
  <tr>
    <td><code>Sync&lt;(T...) =&gt; R&gt;</code></td>
    <td><code>std::function&lt;R (T...)&gt;</code></td>
    <td><code>@escaping (T...) -&gt; R</code></td>
    <td><code>(T...) -&gt; R</code></td>
  </tr>
  <tr>
    <td><code>Error</code></td>
    <td><code>std::exception_ptr</code></td>
    <td><code>Error</code></td>
    <td><code>Throwable</code></td>
  </tr>
  <tr>
    <td><code>Promise&lt;T&gt;</code></td>
    <td><code>std::shared_ptr&lt;<a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/cpp/core/Promise.hpp">Promise&lt;T&gt;</a>&gt;</code></td>
    <td><code><a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/apple/core/Promise.swift">Promise&lt;T&gt;</a></code></td>
    <td><code><a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/android/src/main/java/com/margelo/nitro/core/Promise.kt">Promise&lt;T&gt;</a></code></td>
  </tr>
  <tr>
    <td><code><a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/js/src/AnyMap.ts">AnyMap</a></code></td>
    <td><code>std::shared_ptr&lt;<a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/cpp/core/AnyMap.hpp">AnyMap</a>&gt;</code></td>
    <td><code><a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/apple/core/AnyMap.swift">AnyMap</a></code></td>
    <td><code><a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/android/src/main/java/com/margelo/nitro/core/AnyMap.kt">AnyMap</a></code></td>
  </tr>
  <tr>
    <td><code>ArrayBuffer</code></td>
    <td><code>std::shared_ptr&lt;<a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/cpp/core/ArrayBuffer.hpp">ArrayBuffer</a>&gt;</code></td>
    <td><code><a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/apple/core/ArrayBuffer.swift">ArrayBuffer</a></code></td>
    <td><code><a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/android/src/main/java/com/margelo/nitro/core/ArrayBuffer.kt">ArrayBuffer</a></code></td>
  </tr>
  <tr>
    <td><code>Date</code></td>
    <td><code>std::chrono::system_clock::time_point</code></td>
    <td><code>Date</code></td>
    <td><code>java.time.Instant</code></td>
  </tr>
  <tr>
    <td>..any <code><a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/js/src/HybridObject.ts">HybridObject</a></code></td>
    <td><code>std::shared_ptr&lt;<a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/cpp/core/HybridObject.hpp">HybridObject</a>&gt;</code></td>
    <td><code><a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/apple/core/HybridObject.swift">HybridObject</a></code></td>
    <td><code><a href="https://github.com/margelo/nitro/blob/main/packages/nitro-core/native/android/src/main/java/com/margelo/nitro/core/HybridObject.kt">HybridObject</a></code></td>
  </tr>
  <tr>
    <td>..any <code>interface</code></td>
    <td><code>struct T</code></td>
    <td><code>struct T</code></td>
    <td><code>data class T</code></td>
  </tr>
  <tr>
    <td>..any <code>enum</code></td>
    <td><code>enum T</code></td>
    <td><code>enum T</code></td>
    <td><code>enum T</code></td>
  </tr>
  <tr>
    <td>..any <code>union</code></td>
    <td><code>enum T</code></td>
    <td><code>enum T</code></td>
    <td><code>enum T</code></td>
  </tr>
</table>


Since the `JSIConverter<T>` is just a template, you can extend it with any other custom types by overloading the interface.

For example, to add support for an enum, overload `JSIConverter<MyEnum>`:

```cpp
#include <NitroModules/JSIConverter.hpp>

enum class MyEnum {
  FIRST = 0,
  SECOND = 1
};

namespace margelo::nitro {
  template <>
  struct JSIConverter<MyEnum> {
    static inline MyEnum fromJSI(jsi::Runtime& runtime, const jsi::Value& arg) {
      int intValue = JSIConverter<int>::fromJSI(runtime, arg);
      return static_cast<MyEnum>(intValue);
    }
    static inline jsi::Value toJSI(jsi::Runtime& runtime, MyEnum arg) {
      int intValue = static_cast<int>(arg);
      return JSIConverter<int>::toJSI(runtime, intValue);
    }
  };
}
```

Once the `JSIConverter<T>` for `MyEnum` is defined, you can use the type `MyEnum` in C++ methods, getters and setters of `HybridObject`s.

And on the JS side, you can simply treat the returned `number` (int) as a `MyEnum`:

```js
enum MyEnum {
  FIRST = 0,
  SECOND = 1
}
const value = myHybridObject.getEnumValue() // <-- typed as `MyEnum` instead of `number`
```

Make sure to always include the header that defines the `JSIConverter<MyEnum>` overload inside the `MyHybridObject` file, as this is where the `JSIConverter<T>` overloads are accessed from.

[**Nitrogen**](https://github.com/margelo/nitro/tree/main/packages/nitrogen) can automatically generate such `JSIConverter<T>` extensions for enums, TypeScript unions, and even structs/objects - so it is generally recommended to use nitrogen.

---
_Source: https://npm.io/package/react-native-nitro-modules · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
