---
title: "How Node-API Works in React Native: A Deep Dive"
description: "A closer look at how Node-API works in React Native, covering addon loading, bundling, the host package, and new build tools like cmake-rn and ferric-cli."
url: https://www.callstack.com/blog/how-node-api-works-in-react-native-a-deep-dive
updated: 2026-10-24T08:39:30.607Z
---

# How Node-API Works in React Native: A Deep Dive

A closer look at how Node-API works in React Native, covering addon loading, bundling, the host package, and new build tools like cmake-rn and ferric-cli.

_By Kræn Hansen, Software Engineer @ MongoDB · Published 2025-08-05 · Category: Cross-Platform_

A few weeks back, we introduced our work on [bringing Node-API support to React Native](https://www.callstack.com/blog/announcing-node-api-support-for-react-native) and why we believe it will benefit our community. With this article, we want to dive deep into what Node-API actually is and how we're bringing it to React Native.

## How it all works together

As mentioned above, Node-API is an ABI-stable JS engine/runtime abstraction, built and maintained by the Node.js project governed by the OpenJS Foundation. In practice it’s a couple of [C header files](https://github.com/nodejs/node-api-headers/tree/main/include) declaring the types and functions expected by a Node-API addon, to be implemented by a Node-API host, such as Node.js

> We (and the Node.js docs) use the terms: Node-API module, Node-API addon and addon often interchangeably. In practice, they’re the same thing: A dynamic library expecting and calling into Node-API functions.

When a Node-API addon build is cached so that users don’t need to recompile it from source code, it’s colloquially referred to as a “pre-build”.

### Host package

At the core of everything is the [`react-native-node-api`](https://github.com/callstackincubator/react-native-node-api) package. We refer to it as “the host” because it sets up the environment needed for a Node-API addon to register itself in a React Native app before it’s required in JavaScript.

### Bundling addons

Before an addon can register itself, it must be included in the app bundle. This is different from Node.js, where the dynamic `.node` file just needs to be present on the filesystem.

In React Native, we bundle the addon by scanning the app and its dependencies for directories and files that match [a specific format](https://github.com/callstackincubator/react-native-node-api/blob/main/docs/PREBUILDS.md). We then copy them into the host package and rename them to avoid conflicts. This process is called **linking** or **auto-linking**, and it happens during every app build—via CocoaPods, Xcode build phases, and/or Gradle scripts—to ensure native code changes are applied.

![](https://www.callstack.com/assets/6891e9dd911134dfc18e7154_01native_build_linking_flow_platform_specific_node_api_addon_vbnet_v2.webp)

### Loading

In React Native, TurboModules are loaded using `TurboModuleRegistry.getEnforcing`. Node-API modules are loaded using the `requireNodeAddon` function provided by the host:

```javascript
requireNodeAddon("./my-addon")
```

To support existing Node-API modules, we provide a Babel plugin that transforms `.node` file imports into `requireNodeAddon `calls:

```javascript
const addon = require('./my-addon.node');
```

Just require the prebuilt file using a relative path and the addon will load and initialize at runtime.

![](https://www.callstack.com/assets/6891e960d7133f93e838b1ef_02_javascript_node_api_addon_runtime_flow.webp)

## Providing the Node-API Functions to Addons

Node-API addons expect the host to implement the Node-API functions. Some of these are **engine-specific** (e.g., object creation, property access), while others are **runtime-specific** (e.g., async task scheduling, addon registration).

> The engine-specific functions are provided by Hermes while the remaining runtime-specific functions are provided by the host. You can follow the status of Hermes-specific work by [visiting this PR](https://github.com/facebook/hermes/pull/1377).

In Node.js, the runtime provides the functions directly, and addons link against the Node.js binary. In React Native, we provide a lightweight dynamic library called `weak-node-api`. It exposes Node-API functions and allows both Hermes and the host package to register their respective function implementations.

## Build tools

To support existing Node-API addons and improve developer experience, we also published CLI tools:

- `cmake-rn` functions similarly to [cmake-js](https://www.npmjs.com/package/cmake-js) for Node.js. It acts as a wrapper around the CMake build system, injecting header and library paths for Node-API libraries. This facilitates building and producing the Node-API addon for Android and Apple platforms.
- `gyp-to-cmake` makes it simple to convert any package relying on [the GYP build system](https://gyp.gsrc.io/) (through `node-gyp`) to a CMake project, by transforming the `binding.gyp` file into a `CMakeLists.txt` file. Combined with `cmake-rn`, it allows you to build hundreds (thousands?) of existing GYP-based packages to use in React Native too.
- `ferric-cli` wraps the [napi.rs](http://napi.rs/) CLI to generate end-to-end type-safe Node-API bindings in the Node-API addon format from macro-annotated Rust code. Learn more about Ferric in [Kræn's talk at React Summit '25](https://gitnation.com/contents/rusty-native-modules-for-react-native).

## Get Involved

We’re building toward a future where native modules in React Native are easier to author, share, and maintain across frontend, backend and multiple different cross-platform frameworks, powered by Node-API. If that vision excites you, we’d love your help.

You can find the full codebase, docs, and examples on [GitHub](https://github.com/callstackincubator/react-native-node-api).

Here’s how you can join in:

- **Try it out** – Add a Node-API module to your app or build your own.
- **Contribute** – Check out good first issues, submit improvements, or test on real-world projects.
- **Spread the word** – Star the repo, share your experience, or help others discover what’s possible.

We’re here to support you and we’re excited to see what you build.
