# Unlocking Native Performance in Node.js with Node-API (N-API)

Node.js is fast, flexible, and great for building APIs, servers, and full-stack apps. But sometimes JavaScript isn’t enough.

* What if you need **blazing-fast performance**?
    
* Or you want to use an existing **C/C++ library** instead of rewriting it in JS?
    
* Or maybe you need access to **low-level system features** like file systems, drivers, or hardware?
    

That’s where **Node-API (N-API)** comes in.

## **1.What is Node-API (N-API)?**

**Node-API** is a **stable C API** for building **native addons** in Node.js.

Before Node-API, addons were tied directly to V8 (Node’s JavaScript engine). Every Node.js or V8 update risked breaking your addon.

With Node-API:

* Addons work across Node.js versions.
    
* It’s **engine-independent** (works with V8, ChakraCore, Hermes, etc.).
    
* It provides a **stable ABI** (Application Binary Interface).
    

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text">Node-API is the <strong>bridge</strong> between JavaScript and native code.</div>
</div>

## **2.Why Should You want N-API?**

* **Future-proof** - Your addon won’t break every time Node.js upgrades.
    
* **Performance** - Run CPU-heavy tasks in native code.
    
* **Reuse existing libraries** - Wrap C/C++ instead of reinventing in JS.
    
* **System access** - Do things pure JS can’t (hardware, OS integration).
    

Popular modules that use native code:

* **bcrypt** → password hashing
    
* **sharp** → image processing
    
* **sqlite3** → database driver
    

## **3.How Node-API Works?**

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1757778047784/3805fc4c-57b6-49bc-8c3f-a9f7c449abb9.png align="center")

JavaScript talks to Node-API, which safely communicates with your C/C++ addon.

## 4.Let’s build a tiny addon

Let’s make our hand’s dirty by building a tiny addon

### Step 1: Prerequisites

Make sure you have:

* Node.js
    
* Python (for build tools)
    
* C++ compiler (gcc/clang/MSVC)
    

```bash
npm install -g node-gyp
```

### Step 2: Addon Code (C++)

Create a new file named hello.cpp

```cpp
#include <napi.h>

// This is the native C++ function that will be exposed to JavaScript.
// It takes the standard N-API CallbackInfo object and returns a Napi::Value.
Napi::Value HelloWorld(const Napi::CallbackInfo& info) {
  // Napi::Env is the environment context for the current Node.js instance.
  // It's used to create JavaScript values (strings, numbers, objects, etc.).
  Napi::Env env = info.Env();

  // Create a new JavaScript string with the value "Hello World from C++!"
  // and return it. This value will be the result of calling the function
  // from your Node.js code.
  return Napi::String::New(env, "Hello World from C++!");
}

// The Init function is the entry point for the Node.js addon.
// It's responsible for setting up the exports that will be available
// in JavaScript when the addon is required.
Napi::Object Init(Napi::Env env, Napi::Object exports) {
  // Set a property on the 'exports' object.
  // The first argument is the name of the export (how you'll call it in JS).
  // The second argument is a Napi::Function that wraps our native C++ function.
  exports.Set(Napi::String::New(env, "hello"),
              Napi::Function::New(env, HelloWorld));

  // Return the modified exports object.
  return exports;
}

// This macro registers the addon with Node.js.
// The first argument is the addon's name (must match 'target_name' in binding.gyp).
// The second argument is the initialization function we just defined.
NODE_API_MODULE(hello_world_addon, Init)
```

This is the core C++ source code. It defines the HelloWorld function that returns a string and an Init function that exports HelloWorld under the name hello.

### Step 3: Build Config

Create binding.gyp

```json
{
"targets": [
  {
    "target_name": "hello_world_addon",
    "sources": [ "hello.cpp" ],
    "include_dirs": [
       "<!@(node -p "require('node-addon-api').include")"
     ],
     "defines": [ "NAPI_DISABLE_CPP_EXCEPTIONS" ]
   }
 ]
}
```

This is a build configuration file for node-gyp. It tells the compiler which C++ files to compile (sources), what to name the final binary (target\_name), and where to find the necessary header files (include\_dirs).

### Step 4: Build the Addon

```bash
node-gyp configure build
```

This generates `build/Release/addon.node`

### Step 5: Use It in Node.js

Create index.js

```javascript
const addon = require('./build/Release/hello_world_addon.node');

console.log(addon.hello()); // → "Hello from Node-API!"
```

Run it:

```javascript
node index.js
```

You can find the entire source code for the helloworld addon in the following Github

%[https://github.com/nidhinkumar06/N-API-Example] 

## 5.How N-API differs from Worklets or WebAssembly?

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1757783959208/3d07d722-31b3-4de3-a410-a3dbe88c9350.png align="center")

* **Node-API** → bridge to native C++ in Node.js.
    
* **Worklets** → lightweight JS workers in browser rendering.
    
* **WebAssembly** → portable, high-performance modules for both browser + Node.js.
    

## 6.Node-API and Hermes

**Hermes** — a JavaScript engine built by Meta for React Native. It’s optimized for:

* Fast startup
    
* Low memory usage
    
* Small binary size
    

Node.js usually runs on **V8**, but the community has experimented with **running Node.js on Hermes**.

Here’s why Node-API is important:

* Node-API is **engine-independent**.
    
* If Node.js runs on V8, ChakraCore, or Hermes, your addon still works.
    
* Without Node-API, you’d have to rewrite bindings for every engine.
    

### Example

Think of **Node-API** as a **universal power adapter**:

* V8 = US plug
    
* Hermes = EU plug
    
* ChakraCore = UK plug
    

Without Node-API, you’d need a different charger each time. With Node-API, your addon plugs in anywhere.

## 7.Resources & Links

### **Node-API**

* Documentation: [https://nodejs.org/api/n-api.html](https://nodejs.org/api/n-api.html)
    
* Examples: [https://github.com/nodejs/node-addon-examples](https://github.com/nodejs/node-addon-examples)
    

### **Node-API bindings**

* Engine bindings doc: [https://github.com/nodejs/abi-stable-node/blob/doc/node-api-engine-bindings.md](https://github.com/nodejs/abi-stable-node/blob/doc/node-api-engine-bindings.md)
    
* C++ API: [https://github.com/nodejs/node-addon-api](https://github.com/nodejs/node-addon-api)
    
* C# API: [https://github.com/microsoft/node-api-dotnet](https://github.com/microsoft/node-api-dotnet)
    
* JSI API: [https://github.com/microsoft/node-api-jsi](https://github.com/microsoft/node-api-jsi)
    

### **Node-API for Hermes**

* Hermes PR: [https://github.com/facebook/hermes/pull/1377](https://github.com/facebook/hermes/pull/1377)
    
* Hermes Windows fork: [https://github.com/microsoft/hermes-windows](https://github.com/microsoft/hermes-windows)
