What is N-API and How to use it in nodejs
N-API (Node.js API) is an API for building native addons in Node.js. Native addons are compiled code that is written in languages like C or C++ and can be loaded into Node.js applications to provide additional functionality, typically for performance-critical operations or to access system-level resources that are not available in JavaScript. e.g. Sharp library uses N-API to process images.
Key Features of N-API
- ABI Stability: N-API provides a stable Application Binary Interface (ABI) that ensures addons built with one version of Node.js will run with future versions without recompilation.
- Ease of Use: It abstracts the complexities of interfacing with V8 (the JavaScript engine that powers Node.js), making it easier to write native code that interacts with JavaScript.
- Cross-Version Compatibility: Addons developed with N-API work across different versions of Node.js, reducing the need to maintain multiple versions of the same addon.
- Better Integration with Node.js: N-API provides a set of functions for handling data types, managing the lifecycle of objects, and working with the event loop, timers, and other core Node.js features.
How N-API Works
N-API functions are included in the node_api.h
header file. To use N-API, you need to include this header in your C or C++ source code. The basic workflow involves:
- Initializing the Module: Define the initialization function for your module. This function is called when the module is loaded into the Node.js runtime.
- Defining Functions and Objects: Define the functions and objects that will be exposed to the JavaScript environment.
- Building the Addon: Compile the C or C++ code into a binary that can be loaded by Node.js.
Example
Here's a simple example of a Node.js addon using N-API:
1. Install Dependencies
First, install the necessary dependencies:
npm install node-addon-api
2. Create the C++ Addon
Create a file called addon.cc
:
#include <napi.h>
// Function to add two numbers
Napi::Value Add(const Napi::CallbackInfo& info) {
Napi::Env env = info.Env();
// Check if arguments are numbers
if (!info[0].IsNumber() || !info[1].IsNumber()) {
Napi::TypeError::New(env, "Number expected").ThrowAsJavaScriptException();
return env.Null();
}
// Get the arguments as numbers
double arg0 = info[0].As<Napi::Number>().DoubleValue();
double arg1 = info[1].As<Napi::Number>().DoubleValue();
// Return the sum
Napi::Number returnValue = Napi::Number::New(env, arg0 + arg1);
return returnValue;
}
// Initialize the module
Napi::Object Init(Napi::Env env, Napi::Object exports) {
exports.Set(Napi::String::New(env, "add"), Napi::Function::New(env, Add));
return exports;
}
// Register the module
NODE_API_MODULE(addon, Init)
3. Create the binding.gyp
File
This file tells the build tool how to build your addon:
{
"targets": [
{
"target_name": "addon",
"sources": ["addon.cc"],
"include_dirs": ["<!@(node -p \"require('node-addon-api').include\")"],
"dependencies": ["<!(node -p \"require('node-addon-api').gyp\")"],
"cflags!": ["-fno-exceptions"],
"cflags_cc!": ["-fno-exceptions"],
"defines": ["NAPI_DISABLE_CPP_EXCEPTIONS"]
}
]
}
4. Build the Addon
Run the following command to build the addon:
npm install
This will generate a build/Release/addon.node
file.
5. Use the Addon in Node.js
Create a test.js
file to use the addon:
const addon = require('./build/Release/addon');
console.log('1 + 2 =', addon.add(1, 2));
Run the test.js
file:
node test.js
You should see the output:
1 + 2 = 3