{"id":11408,"library":"node-addon-api","title":"Node-Addon-API C++ Wrapper for Node.js Native Addons","description":"Node-Addon-API (N-API) is a C++ wrapper library that significantly simplifies the development of Node.js native add-ons. It provides a higher-level, more idiomatic C++ interface over the raw C-based Node-API, leveraging modern C++ features like RAII (Resource Acquisition Is Initialization) and exceptions for safer and more robust native module development. This abstraction layer helps manage memory and resources automatically, reducing common errors associated with manual memory management in C. The current stable version is 8.7.0, with minor feature and bugfix releases occurring every few months. Its primary differentiator is making Node.js native module development accessible to C++ developers by providing familiar C++ paradigms, while maintaining ABI stability across Node.js major versions, ensuring compiled add-ons continue to work without recompilation against newer Node.js releases. It is the recommended path for new native addon development.","status":"active","version":"8.7.0","language":"javascript","source_language":"en","source_url":"git://github.com/nodejs/node-addon-api","tags":["javascript","n-api","napi","addon","native","bindings","c","c++","nan"],"install":[{"cmd":"npm install node-addon-api","lang":"bash","label":"npm"},{"cmd":"yarn add node-addon-api","lang":"bash","label":"yarn"},{"cmd":"pnpm add node-addon-api","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Essential build toolchain for compiling native Node.js addons. While not an npm dependency of node-addon-api itself, it is a critical conceptual dependency for any project using node-addon-api to build native modules.","package":"node-gyp","optional":false},{"reason":"Requires a C++ compiler (e.g., g++ for Linux/macOS, MSVC for Windows) compatible with the Node.js version's V8 engine and Node-API requirements.","package":"C++ compiler","optional":false}],"imports":[{"note":"The 'node-addon-api' package itself is a C++ header library and does not provide JavaScript exports. This entry describes how a native addon compiled *using* node-addon-api is imported into a JavaScript application. The path `./build/Release/myaddon.node` is typical after a successful `node-gyp build`.","wrong":"import { myAddon } from 'node-addon-api';","symbol":"myAddon","correct":"const myAddon = require('./build/Release/myaddon.node');"},{"note":"ESM import for a compiled native addon. Node.js can directly import `.node` files, but ensure your project's `package.json` type is 'module' or use dynamic `import()` if mixing CJS and ESM.","wrong":"const myAddon = require('node-addon-api');","symbol":"myAddon","correct":"import myAddon from './build/Release/myaddon.node';"},{"note":"When operating in an ES Module environment (e.g., `\"type\": \"module\"` in `package.json`), you might need to use `createRequire` to load a CommonJS-style native addon dynamically.","symbol":"loadNativeAddon","correct":"import { createRequire } from 'module'; const require = createRequire(import.meta.url); const myAddon = require('./build/Release/myaddon.node');"}],"quickstart":{"code":"/* C++ source file: hello.cc */\n#include <napi.h>\n\n// Simple synchronous method that returns a string\nNapi::String Method(const Napi::CallbackInfo& info) {\n  Napi::Env env = info.Env();\n  return Napi::String::New(env, \"world\");\n}\n\n// Initialize the addon\nNapi::Object Init(Napi::Env env, Napi::Object exports) {\n  exports.Set(Napi::String::New(env, \"hello\"),\n              Napi::Function::New(env, Method));\n  return exports;\n}\n\n// Register the addon module\nNODE_API_MODULE(hello, Init)\n\n/* binding.gyp (build configuration for node-gyp) */\n{\n  \"targets\": [\n    {\n      \"target_name\": \"hello\",\n      \"sources\": [ \"hello.cc\" ],\n      \"include_dirs\": [\n        \"<!@(node -p \\\"require('node-addon-api').include\\\")\"\n      ],\n      \"cflags!\": [ \"-fno-exceptions\" ],\n      \"cflags_cc!\": [ \"-fno-exceptions\" ],\n      \"defines\": [ \"NAPI_CPP_EXCEPTIONS\" ],\n      \"libraries\": []\n    }\n  ]\n}\n\n/* JavaScript usage: index.js */\n// To build the addon: run `node-gyp rebuild` in your terminal.\n// This will create a `build/Release/hello.node` file.\n\nconst addon = require('./build/Release/hello.node');\n\nconsole.log('addon.hello() =', addon.hello()); // Expected output: addon.hello() = world\n","lang":"typescript","description":"Demonstrates building a simple 'hello world' native addon in C++ using Node-Addon-API and loading/executing it from a Node.js JavaScript application. Includes the `binding.gyp` configuration."},"warnings":[{"fix":"Always refer to the official changelog and migration guides for `node-addon-api` when updating major versions. Recompile your native addon against the new `node-addon-api` version and target Node.js release.","message":"Node-API provides ABI stability for its underlying C interface, meaning compiled addons typically work across Node.js major versions without recompilation. However, `node-addon-api` is a C++ wrapper; its C++ API can evolve, and major version bumps (e.g., v7 to v8) may introduce C++ API changes requiring code updates and recompilation.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure your Node.js development and deployment environments meet the `engines.node` requirements. Use a Node.js version manager (e.g., `nvm`) to switch between versions.","message":"Addons built with `node-addon-api` require specific Node.js versions as indicated by the `engines.node` field in the package.json (currently `^18 || ^20 || >= 21`). Building or running on unsupported Node.js versions can lead to build failures or runtime crashes due to incompatible N-API versions or internal changes.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Add `\"defines\": [ \"NAPI_CPP_EXCEPTIONS\" ]` to your `binding.gyp`. For other build systems (CMake), ensure the equivalent compiler flag for C++ exceptions is enabled. Wrap all C++ code callable from JavaScript in `try-catch` blocks to translate C++ exceptions into JavaScript exceptions.","message":"Node-Addon-API heavily utilizes C++ exceptions for error handling. It is critical to define `NAPI_CPP_EXCEPTIONS` in your `binding.gyp` (or equivalent build system) and ensure your compiler is configured to handle C++ exceptions. Failing to do so can lead to unexpected crashes, segmentation faults, or silent failures when exceptions are thrown from native code.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Use `Napi::Persistent<T>` for any JavaScript values (e.g., functions, objects) that need to persist beyond the immediate N-API callback. Remember to `Reset()` or `SuppressDestruct()` these references when they are no longer needed to allow garbage collection.","message":"While RAII is leveraged for many resources, developers must explicitly manage persistent references to JavaScript objects (`Napi::Persistent<T>`) that need to outlive the scope of a single N-API call to prevent them from being garbage collected prematurely by the V8 engine. Forgetting to manage these can lead to use-after-free bugs or incorrect behavior.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Thoroughly review the Node-Addon-API documentation and examples for `Napi::ThreadSafeFunction`. Ensure all `Acquire()`/`Release()` calls are balanced, `BlockingCall()`/`NonBlockingCall()` are used correctly, and the `ThreadSafeFunction`'s lifecycle is managed carefully, especially in shutdown scenarios.","message":"Using `Napi::ThreadSafeFunction` (TSFN) for asynchronous operations across threads introduces significant complexity. Incorrect usage, particularly around managing `ref()` and `unref()` calls, lifetime management of the `ThreadSafeFunction` object, and proper data transfer between threads, is a common source of deadlocks, memory leaks, or application crashes.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure your `binding.gyp` includes `\"<!@(node -p \\\"require('node-addon-api').include\\\")\"` in the `include_dirs` array. For CMake, ensure you correctly `find_package(node_addon_api CONFIG REQUIRED)` and link against `node_addon_api::node_addon_api`.","cause":"The C++ compiler cannot locate the `node-addon-api` header files, meaning the include paths are incorrect or missing in your build configuration.","error":"fatal error: 'napi.h' file not found"},{"fix":"Check your `binding.gyp` for correct `libraries` and `link_settings` entries. Run `node-gyp rebuild` with increased verbosity (`--verbose`) to inspect linker output. On Linux, use `ldd build/Release/myaddon.node` to identify missing shared library dependencies.","cause":"The native addon `.node` file could not be loaded due to a missing dependency (e.g., a shared library your addon links against) or a linker error during compilation that resulted in an unusable `.node` file.","error":"Error: The specified module could not be found. (on Windows) or Error: libmyaddon.node: undefined symbol: some_napi_function (on Linux/macOS)"},{"fix":"Ensure `NAPI_CPP_EXCEPTIONS` is defined in your build configuration. Wrap potentially throwing C++ code in `try-catch` blocks within your `Napi::CallbackInfo` handlers to convert C++ exceptions into JavaScript exceptions using `Napi::Error::New(env, e.what()).ThrowAsJavaScriptException();`.","cause":"This often indicates an unhandled C++ exception propagating out of the native code, incorrect memory access (e.g., dangling pointers), or an ABI incompatibility. It can also happen if `NAPI_CPP_EXCEPTIONS` is not defined but C++ exceptions are being used.","error":"Node.js crashes with a segmentation fault or unhandled C++ exception when calling a native method."},{"fix":"Double-check the `Init` function in your C++ code. Ensure `exports.Set(Napi::String::New(env, \"myFunction\"), Napi::Function::New(env, MyFunctionMethod));` correctly exposes the function with the intended JavaScript name ('myFunction' in this example).","cause":"The native addon loaded successfully, but the JavaScript environment cannot find the expected function. This means the C++ `Init` function did not correctly expose the function on the `exports` object or exposed it with a different name.","error":"TypeError: addon.myFunction is not a function"}],"ecosystem":"npm"}