require() function can load addons as ordinary Node.js modules. Addons provide an interface between JavaScript and C/C++ libraries.
Implementation Options
There are three options for implementing addons:- Node-API (recommended) - Provides ABI stability across Node.js versions
- nan (Native Abstractions for Node.js) - Compatibility layer for V8 API changes
- Direct V8, libuv, and Node.js APIs - For advanced use cases requiring low-level access
Unless you need direct access to functionality not exposed by Node-API, use Node-API. Refer to C/C++ addons with Node-API for more information.
Components
When not using Node-API, implementing addons requires knowledge of several components:V8
The C++ library Node.js uses to provide the JavaScript implementation. V8 provides mechanisms for:- Creating objects
- Calling functions
- Managing memory and garbage collection
v8.h and available online.
libuv
The C library implementing the Node.js event loop, worker threads, and asynchronous behaviors. It provides:- Cross-platform abstraction for common system tasks
- File system interactions
- Sockets and networking
- Timers and system events
- Threading abstraction for sophisticated async operations
Internal Node.js Libraries
Node.js exports C++ APIs that addons can use, including thenode::ObjectWrap class.
Other Libraries
Node.js statically links libraries including OpenSSL, V8, and zlib, whose symbols are purposefully re-exported for addon use.Hello World Example
This simple addon is equivalent to the following JavaScript:hello.cc):
Building Addons
Once the source code is written, it must be compiled into the binaryaddon.node file.
Create a binding.gyp file:
Using Addons
Once built, the addon can be loaded from Node.js:Context-Aware Addons
Addons may need to be loaded multiple times in multiple contexts. For example, Electron runs multiple instances of Node.js in a single process. Construct a context-aware addon usingNODE_MODULE_INITIALIZER:
NODE_MODULE_INIT():
Managing Global State
Context-aware addons require careful management of global static data:- Define a class to hold per-addon-instance data with a static
DeleteInstance()method - Heap-allocate an instance in the addon initializer
- Call
node::AddEnvironmentCleanupHook()to ensure cleanup - Store the instance in a
v8::External - Pass the
v8::Externalto all exposed methods
Worker Thread Support
To support Worker threads, addons must:- Be a Node-API addon, or
- Be declared as context-aware using
NODE_MODULE_INIT()
AddEnvironmentCleanupHook():
Linking to Node.js Libraries
Addons are required to link to V8 and may link to other Node.js dependencies:- Include headers with
#include <...>statements node-gypautomatically locates appropriate headers- When downloading full source, addons have access to all Node.js dependencies
- When downloading only headers, only exported symbols are available
Common Patterns
Function Arguments
Reading arguments passed from JavaScript:Callbacks
Passing JavaScript functions to C++ and executing them:Object Factory
Creating and returning objects from C++:Wrapping C++ Objects
Wrap C++ classes for use with JavaScriptnew operator by inheriting from node::ObjectWrap:
Node-API Alternative
Stability: 2 - Stable
- Independent from the underlying JavaScript runtime (V8)
- Maintained as part of Node.js
- ABI stable across Node.js versions
- Allows modules compiled for one version to run on later versions without recompilation