N-API modules are registered in a manner similar to other modules except that instead of using the NODE_MODULE macro the following is used:

    1. NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)

    The next difference is the signature for the Init method. For a N-API module it is as follows:

    1. napi_value Init(napi_env env, napi_value exports);

    The return value from Init is treated as the exports object for the module. The Init method is passed an empty object via the exports parameter as a convenience. If Init returns NULL, the parameter passed as exports is exported by the module. N-API modules cannot modify the module object but can specify anything as the exports property of the module.

    To add the method hello as a function so that it can be called as a method provided by the addon:

    1. napi_value Init(napi_env env, napi_value exports) {
    2. napi_status status;
    3. napi_property_descriptor desc = {
    4. "hello",
    5. NULL,
    6. Method,
    7. NULL,
    8. NULL,
    9. NULL,
    10. napi_writable | napi_enumerable | napi_configurable,
    11. NULL
    12. };
    13. status = napi_define_properties(env, exports, 1, &desc);
    14. if (status != napi_ok) return NULL;
    15. return exports;
    16. }

    To set a function to be returned by the require() for the addon:

    1. napi_value Init(napi_env env, napi_value exports) {
    2. napi_value method;
    3. napi_status status;
    4. status = napi_create_function(env, "exports", NAPI_AUTO_LENGTH, Method, NULL, &method);
    5. if (status != napi_ok) return NULL;
    6. return method;
    7. }

    To define a class so that new instances can be created (often used with [Object wrap][]):

    1. // NOTE: partial example, not all referenced code is included
    2. napi_value Init(napi_env env, napi_value exports) {
    3. napi_status status;
    4. napi_property_descriptor properties[] = {
    5. { "value", NULL, NULL, GetValue, SetValue, NULL, napi_writable | napi_configurable, NULL },
    6. DECLARE_NAPI_METHOD("plusOne", PlusOne),
    7. DECLARE_NAPI_METHOD("multiply", Multiply),
    8. };
    9. napi_value cons;
    10. status =
    11. napi_define_class(env, "MyObject", New, NULL, 3, properties, &cons);
    12. if (status != napi_ok) return NULL;
    13. status = napi_create_reference(env, cons, 1, &constructor);
    14. if (status != napi_ok) return NULL;
    15. status = napi_set_named_property(env, exports, "MyObject", cons);
    16. if (status != napi_ok) return NULL;
    17. return exports;
    18. }

    If the module will be loaded multiple times during the lifetime of the Node.js process, use the NAPI_MODULE_INIT macro to initialize the module:

    1. NAPI_MODULE_INIT() {
    2. napi_value answer;
    3. napi_status result;
    4. status = napi_create_int64(env, 42, &answer);
    5. if (status != napi_ok) return NULL;
    6. status = napi_set_named_property(env, exports, "answer", answer);
    7. if (status != napi_ok) return NULL;
    8. return exports;
    9. }

    This macro includes NAPI_MODULE, and declares an Init function with a special name and with visibility beyond the addon. This will allow Node.js to initialize the module even if it is loaded multiple times.

    There are a few design considerations when declaring a module that may be loaded multiple times. The documentation of [context-aware addons][] provides more details.

    The variables env and exports will be available inside the function body following the macro invocation.

    For more details on setting properties on objects, see the section on [Working with JavaScript properties][].

    For more details on building addon modules in general, refer to the existing API.