• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Node-API
2
3<!--introduced_in=v8.0.0-->
4<!-- type=misc -->
5
6> Stability: 2 - Stable
7
8Node-API (formerly N-API) is an API for building native Addons. It is
9independent from the underlying JavaScript runtime (for example, V8) and is
10maintained as part of Node.js itself. This API will be Application Binary
11Interface (ABI) stable across versions of Node.js. It is intended to insulate
12addons from changes in the underlying JavaScript engine and allow modules
13compiled for one major version to run on later major versions of Node.js without
14recompilation. The [ABI Stability][] guide provides a more in-depth explanation.
15
16Addons are built/packaged with the same approach/tools outlined in the section
17titled [C++ Addons][]. The only difference is the set of APIs that are used by
18the native code. Instead of using the V8 or [Native Abstractions for Node.js][]
19APIs, the functions available in Node-API are used.
20
21APIs exposed by Node-API are generally used to create and manipulate
22JavaScript values. Concepts and operations generally map to ideas specified
23in the ECMA-262 Language Specification. The APIs have the following
24properties:
25
26* All Node-API calls return a status code of type `napi_status`. This
27  status indicates whether the API call succeeded or failed.
28* The API's return value is passed via an out parameter.
29* All JavaScript values are abstracted behind an opaque type named
30  `napi_value`.
31* In case of an error status code, additional information can be obtained
32  using `napi_get_last_error_info`. More information can be found in the error
33  handling section [Error handling][].
34
35Node-API is a C API that ensures ABI stability across Node.js versions
36and different compiler levels. A C++ API can be easier to use.
37To support using C++, the project maintains a
38C++ wrapper module called [`node-addon-api`][].
39This wrapper provides an inlineable C++ API. Binaries built
40with `node-addon-api` will depend on the symbols for the Node-API C-based
41functions exported by Node.js. `node-addon-api` is a more
42efficient way to write code that calls Node-API. Take, for example, the
43following `node-addon-api` code. The first section shows the
44`node-addon-api` code and the second section shows what actually gets
45used in the addon.
46
47```cpp
48Object obj = Object::New(env);
49obj["foo"] = String::New(env, "bar");
50```
51
52```cpp
53napi_status status;
54napi_value object, string;
55status = napi_create_object(env, &object);
56if (status != napi_ok) {
57  napi_throw_error(env, ...);
58  return;
59}
60
61status = napi_create_string_utf8(env, "bar", NAPI_AUTO_LENGTH, &string);
62if (status != napi_ok) {
63  napi_throw_error(env, ...);
64  return;
65}
66
67status = napi_set_named_property(env, object, "foo", string);
68if (status != napi_ok) {
69  napi_throw_error(env, ...);
70  return;
71}
72```
73
74The end result is that the addon only uses the exported C APIs. As a result,
75it still gets the benefits of the ABI stability provided by the C API.
76
77When using `node-addon-api` instead of the C APIs, start with the API [docs][]
78for `node-addon-api`.
79
80The [Node-API Resource](https://nodejs.github.io/node-addon-examples/) offers
81an excellent orientation and tips for developers just getting started with
82Node-API and `node-addon-api`.
83
84## Implications of ABI stability
85
86Although Node-API provides an ABI stability guarantee, other parts of Node.js do
87not, and any external libraries used from the addon may not. In particular,
88none of the following APIs provide an ABI stability guarantee across major
89versions:
90
91* the Node.js C++ APIs available via any of
92
93    ```cpp
94    #include <node.h>
95    #include <node_buffer.h>
96    #include <node_version.h>
97    #include <node_object_wrap.h>
98    ```
99
100* the libuv APIs which are also included with Node.js and available via
101
102    ```cpp
103    #include <uv.h>
104    ```
105
106* the V8 API available via
107
108    ```cpp
109    #include <v8.h>
110    ```
111
112Thus, for an addon to remain ABI-compatible across Node.js major versions, it
113must use Node-API exclusively by restricting itself to using
114
115```c
116#include <node_api.h>
117```
118
119and by checking, for all external libraries that it uses, that the external
120library makes ABI stability guarantees similar to Node-API.
121
122## Building
123
124Unlike modules written in JavaScript, developing and deploying Node.js
125native addons using Node-API requires an additional set of tools. Besides the
126basic tools required to develop for Node.js, the native addon developer
127requires a toolchain that can compile C and C++ code into a binary. In
128addition, depending upon how the native addon is deployed, the *user* of
129the native addon will also need to have a C/C++ toolchain installed.
130
131For Linux developers, the necessary C/C++ toolchain packages are readily
132available. [GCC][] is widely used in the Node.js community to build and
133test across a variety of platforms. For many developers, the [LLVM][]
134compiler infrastructure is also a good choice.
135
136For Mac developers, [Xcode][] offers all the required compiler tools.
137However, it is not necessary to install the entire Xcode IDE. The following
138command installs the necessary toolchain:
139
140```bash
141xcode-select --install
142```
143
144For Windows developers, [Visual Studio][] offers all the required compiler
145tools. However, it is not necessary to install the entire Visual Studio
146IDE. The following command installs the necessary toolchain:
147
148```bash
149npm install --global windows-build-tools
150```
151
152The sections below describe the additional tools available for developing
153and deploying Node.js native addons.
154
155### Build tools
156
157Both the tools listed here require that *users* of the native
158addon have a C/C++ toolchain installed in order to successfully install
159the native addon.
160
161#### node-gyp
162
163[node-gyp][] is a build system based on the [gyp-next][] fork of
164Google's [GYP][] tool and comes bundled with npm. GYP, and therefore node-gyp,
165requires that Python be installed.
166
167Historically, node-gyp has been the tool of choice for building native
168addons. It has widespread adoption and documentation. However, some
169developers have run into limitations in node-gyp.
170
171#### CMake.js
172
173[CMake.js][] is an alternative build system based on [CMake][].
174
175CMake.js is a good choice for projects that already use CMake or for
176developers affected by limitations in node-gyp.
177
178### Uploading precompiled binaries
179
180The three tools listed here permit native addon developers and maintainers
181to create and upload binaries to public or private servers. These tools are
182typically integrated with CI/CD build systems like [Travis CI][] and
183[AppVeyor][] to build and upload binaries for a variety of platforms and
184architectures. These binaries are then available for download by users who
185do not need to have a C/C++ toolchain installed.
186
187#### node-pre-gyp
188
189[node-pre-gyp][] is a tool based on node-gyp that adds the ability to
190upload binaries to a server of the developer's choice. node-pre-gyp has
191particularly good support for uploading binaries to Amazon S3.
192
193#### prebuild
194
195[prebuild][] is a tool that supports builds using either node-gyp or
196CMake.js. Unlike node-pre-gyp which supports a variety of servers, prebuild
197uploads binaries only to [GitHub releases][]. prebuild is a good choice for
198GitHub projects using CMake.js.
199
200#### prebuildify
201
202[prebuildify][] is a tool based on node-gyp. The advantage of prebuildify is
203that the built binaries are bundled with the native module when it's
204uploaded to npm. The binaries are downloaded from npm and are immediately
205available to the module user when the native module is installed.
206
207## Usage
208
209In order to use the Node-API functions, include the file [`node_api.h`][] which
210is located in the src directory in the node development tree:
211
212```c
213#include <node_api.h>
214```
215
216This will opt into the default `NAPI_VERSION` for the given release of Node.js.
217In order to ensure compatibility with specific versions of Node-API, the version
218can be specified explicitly when including the header:
219
220```c
221#define NAPI_VERSION 3
222#include <node_api.h>
223```
224
225This restricts the Node-API surface to just the functionality that was available
226in the specified (and earlier) versions.
227
228Some of the Node-API surface is experimental and requires explicit opt-in:
229
230```c
231#define NAPI_EXPERIMENTAL
232#include <node_api.h>
233```
234
235In this case the entire API surface, including any experimental APIs, will be
236available to the module code.
237
238## Node-API version matrix
239
240Node-API versions are additive and versioned independently from Node.js.
241Version 4 is an extension to version 3 in that it has all of the APIs
242from version 3 with some additions. This means that it is not necessary
243to recompile for new versions of Node.js which are
244listed as supporting a later version.
245
246<!-- For accessibility purposes, this table needs row headers. That means we
247     can't do it in markdown. Hence, the raw HTML. -->
248
249<table>
250  <tr>
251    <td></td>
252    <th scope="col">1</th>
253    <th scope="col">2</th>
254    <th scope="col">3</th>
255  </tr>
256  <tr>
257    <th scope="row">v6.x</th>
258    <td></td>
259    <td></td>
260    <td>v6.14.2*</td>
261  </tr>
262  <tr>
263    <th scope="row">v8.x</th>
264    <td>v8.6.0**</td>
265    <td>v8.10.0*</td>
266    <td>v8.11.2</td>
267  </tr>
268  <tr>
269    <th scope="row">v9.x</th>
270    <td>v9.0.0*</td>
271    <td>v9.3.0*</td>
272    <td>v9.11.0*</td>
273  </tr>
274  <tr>
275    <th scope="row">≥ v10.x</th>
276    <td>all releases</td>
277    <td>all releases</td>
278    <td>all releases</td>
279  </tr>
280</table>
281
282<table>
283  <tr>
284    <td></td>
285    <th scope="col">4</th>
286    <th scope="col">5</th>
287    <th scope="col">6</th>
288    <th scope="col">7</th>
289    <th scope="col">8</th>
290  </tr>
291  <tr>
292    <th scope="row">v10.x</th>
293    <td>v10.16.0</td>
294    <td>v10.17.0</td>
295    <td>v10.20.0</td>
296    <td>v10.23.0</td>
297    <td></td>
298  </tr>
299  <tr>
300    <th scope="row">v11.x</th>
301    <td>v11.8.0</td>
302    <td></td>
303    <td></td>
304    <td></td>
305    <td></td>
306  </tr>
307  <tr>
308    <th scope="row">v12.x</th>
309    <td>v12.0.0</td>
310    <td>v12.11.0</td>
311    <td>v12.17.0</td>
312    <td>v12.19.0</td>
313    <td>v12.22.0</td>
314  </tr>
315  <tr>
316    <th scope="row">v13.x</th>
317    <td>v13.0.0</td>
318    <td>v13.0.0</td>
319    <td></td>
320    <td></td>
321    <td></td>
322  </tr>
323  <tr>
324    <th scope="row">v14.x</th>
325    <td>v14.0.0</td>
326    <td>v14.0.0</td>
327    <td>v14.0.0</td>
328    <td>v14.12.0</td>
329    <td>v14.17.0</td>
330  </tr>
331  <tr>
332    <th scope="row">v15.x</th>
333    <td>v15.0.0</td>
334    <td>v15.0.0</td>
335    <td>v15.0.0</td>
336    <td>v15.0.0</td>
337    <td>v15.12.0</td>
338  </tr>
339  <tr>
340    <th scope="row">v16.x</th>
341    <td>v16.0.0</td>
342    <td>v16.0.0</td>
343    <td>v16.0.0</td>
344    <td>v16.0.0</td>
345    <td>v16.0.0</td>
346  </tr>
347</table>
348
349\* Node-API was experimental.
350
351\*\* Node.js 8.0.0 included Node-API as experimental. It was released as
352Node-API version 1 but continued to evolve until Node.js 8.6.0. The API is
353different in versions prior to Node.js 8.6.0. We recommend Node-API version 3 or
354later.
355
356Each API documented for Node-API will have a header named `added in:`, and APIs
357which are stable will have the additional header `Node-API version:`.
358APIs are directly usable when using a Node.js version which supports
359the Node-API version shown in `Node-API version:` or higher.
360When using a Node.js version that does not support the
361`Node-API version:` listed or if there is no `Node-API version:` listed,
362then the API will only be available if
363`#define NAPI_EXPERIMENTAL` precedes the inclusion of `node_api.h`
364or `js_native_api.h`. If an API appears not to be available on
365a version of Node.js which is later than the one shown in `added in:` then
366this is most likely the reason for the apparent absence.
367
368The Node-APIs associated strictly with accessing ECMAScript features from native
369code can be found separately in `js_native_api.h` and `js_native_api_types.h`.
370The APIs defined in these headers are included in `node_api.h` and
371`node_api_types.h`. The headers are structured in this way in order to allow
372implementations of Node-API outside of Node.js. For those implementations the
373Node.js specific APIs may not be applicable.
374
375The Node.js-specific parts of an addon can be separated from the code that
376exposes the actual functionality to the JavaScript environment so that the
377latter may be used with multiple implementations of Node-API. In the example
378below, `addon.c` and `addon.h` refer only to `js_native_api.h`. This ensures
379that `addon.c` can be reused to compile against either the Node.js
380implementation of Node-API or any implementation of Node-API outside of Node.js.
381
382`addon_node.c` is a separate file that contains the Node.js specific entry point
383to the addon and which instantiates the addon by calling into `addon.c` when the
384addon is loaded into a Node.js environment.
385
386```c
387// addon.h
388#ifndef _ADDON_H_
389#define _ADDON_H_
390#include <js_native_api.h>
391napi_value create_addon(napi_env env);
392#endif  // _ADDON_H_
393```
394
395```c
396// addon.c
397#include "addon.h"
398
399#define NAPI_CALL(env, call)                                      \
400  do {                                                            \
401    napi_status status = (call);                                  \
402    if (status != napi_ok) {                                      \
403      const napi_extended_error_info* error_info = NULL;          \
404      napi_get_last_error_info((env), &error_info);               \
405      bool is_pending;                                            \
406      napi_is_exception_pending((env), &is_pending);              \
407      if (!is_pending) {                                          \
408        const char* message = (error_info->error_message == NULL) \
409            ? "empty error message"                               \
410            : error_info->error_message;                          \
411        napi_throw_error((env), NULL, message);                   \
412        return NULL;                                              \
413      }                                                           \
414    }                                                             \
415  } while(0)
416
417static napi_value
418DoSomethingUseful(napi_env env, napi_callback_info info) {
419  // Do something useful.
420  return NULL;
421}
422
423napi_value create_addon(napi_env env) {
424  napi_value result;
425  NAPI_CALL(env, napi_create_object(env, &result));
426
427  napi_value exported_function;
428  NAPI_CALL(env, napi_create_function(env,
429                                      "doSomethingUseful",
430                                      NAPI_AUTO_LENGTH,
431                                      DoSomethingUseful,
432                                      NULL,
433                                      &exported_function));
434
435  NAPI_CALL(env, napi_set_named_property(env,
436                                         result,
437                                         "doSomethingUseful",
438                                         exported_function));
439
440  return result;
441}
442```
443
444```c
445// addon_node.c
446#include <node_api.h>
447#include "addon.h"
448
449NAPI_MODULE_INIT() {
450  // This function body is expected to return a `napi_value`.
451  // The variables `napi_env env` and `napi_value exports` may be used within
452  // the body, as they are provided by the definition of `NAPI_MODULE_INIT()`.
453  return create_addon(env);
454}
455```
456
457## Environment life cycle APIs
458
459[Section 8.7][] of the [ECMAScript Language Specification][] defines the concept
460of an "Agent" as a self-contained environment in which JavaScript code runs.
461Multiple such Agents may be started and terminated either concurrently or in
462sequence by the process.
463
464A Node.js environment corresponds to an ECMAScript Agent. In the main process,
465an environment is created at startup, and additional environments can be created
466on separate threads to serve as [worker threads][]. When Node.js is embedded in
467another application, the main thread of the application may also construct and
468destroy a Node.js environment multiple times during the life cycle of the
469application process such that each Node.js environment created by the
470application may, in turn, during its life cycle create and destroy additional
471environments as worker threads.
472
473From the perspective of a native addon this means that the bindings it provides
474may be called multiple times, from multiple contexts, and even concurrently from
475multiple threads.
476
477Native addons may need to allocate global state which they use during
478their entire life cycle such that the state must be unique to each instance of
479the addon.
480
481To this end, Node-API provides a way to allocate data such that its life cycle
482is tied to the life cycle of the Agent.
483
484### napi_set_instance_data
485<!-- YAML
486added:
487 - v12.8.0
488 - v10.20.0
489napiVersion: 6
490-->
491
492```c
493napi_status napi_set_instance_data(napi_env env,
494                                   void* data,
495                                   napi_finalize finalize_cb,
496                                   void* finalize_hint);
497```
498
499* `[in] env`: The environment that the Node-API call is invoked under.
500* `[in] data`: The data item to make available to bindings of this instance.
501* `[in] finalize_cb`: The function to call when the environment is being torn
502  down. The function receives `data` so that it might free it.
503  [`napi_finalize`][] provides more details.
504* `[in] finalize_hint`: Optional hint to pass to the finalize callback during
505  collection.
506
507Returns `napi_ok` if the API succeeded.
508
509This API associates `data` with the currently running Agent. `data` can later
510be retrieved using `napi_get_instance_data()`. Any existing data associated with
511the currently running Agent which was set by means of a previous call to
512`napi_set_instance_data()` will be overwritten. If a `finalize_cb` was provided
513by the previous call, it will not be called.
514
515### napi_get_instance_data
516<!-- YAML
517added:
518 - v12.8.0
519 - v10.20.0
520napiVersion: 6
521-->
522
523```c
524napi_status napi_get_instance_data(napi_env env,
525                                   void** data);
526```
527
528* `[in] env`: The environment that the Node-API call is invoked under.
529* `[out] data`: The data item that was previously associated with the currently
530  running Agent by a call to `napi_set_instance_data()`.
531
532Returns `napi_ok` if the API succeeded.
533
534This API retrieves data that was previously associated with the currently
535running Agent via `napi_set_instance_data()`. If no data is set, the call will
536succeed and `data` will be set to `NULL`.
537
538## Basic Node-API data types
539
540Node-API exposes the following fundamental datatypes as abstractions that are
541consumed by the various APIs. These APIs should be treated as opaque,
542introspectable only with other Node-API calls.
543
544### napi_status
545<!-- YAML
546added: v8.0.0
547napiVersion: 1
548-->
549Integral status code indicating the success or failure of a Node-API call.
550Currently, the following status codes are supported.
551
552```c
553typedef enum {
554  napi_ok,
555  napi_invalid_arg,
556  napi_object_expected,
557  napi_string_expected,
558  napi_name_expected,
559  napi_function_expected,
560  napi_number_expected,
561  napi_boolean_expected,
562  napi_array_expected,
563  napi_generic_failure,
564  napi_pending_exception,
565  napi_cancelled,
566  napi_escape_called_twice,
567  napi_handle_scope_mismatch,
568  napi_callback_scope_mismatch,
569  napi_queue_full,
570  napi_closing,
571  napi_bigint_expected,
572  napi_date_expected,
573  napi_arraybuffer_expected,
574  napi_detachable_arraybuffer_expected,
575  napi_would_deadlock,  /* unused */
576  napi_no_external_buffers_allowed
577} napi_status;
578```
579
580If additional information is required upon an API returning a failed status,
581it can be obtained by calling `napi_get_last_error_info`.
582
583### napi_extended_error_info
584<!-- YAML
585added: v8.0.0
586napiVersion: 1
587-->
588
589```c
590typedef struct {
591  const char* error_message;
592  void* engine_reserved;
593  uint32_t engine_error_code;
594  napi_status error_code;
595} napi_extended_error_info;
596```
597
598* `error_message`: UTF8-encoded string containing a VM-neutral description of
599  the error.
600* `engine_reserved`: Reserved for VM-specific error details. This is currently
601  not implemented for any VM.
602* `engine_error_code`: VM-specific error code. This is currently
603  not implemented for any VM.
604* `error_code`: The Node-API status code that originated with the last error.
605
606See the [Error handling][] section for additional information.
607
608### napi_env
609
610`napi_env` is used to represent a context that the underlying Node-API
611implementation can use to persist VM-specific state. This structure is passed
612to native functions when they're invoked, and it must be passed back when
613making Node-API calls. Specifically, the same `napi_env` that was passed in when
614the initial native function was called must be passed to any subsequent
615nested Node-API calls. Caching the `napi_env` for the purpose of general reuse,
616and passing the `napi_env` between instances of the same addon running on
617different [`Worker`][] threads is not allowed. The `napi_env` becomes invalid
618when an instance of a native addon is unloaded. Notification of this event is
619delivered through the callbacks given to [`napi_add_env_cleanup_hook`][] and
620[`napi_set_instance_data`][].
621
622### napi_value
623
624This is an opaque pointer that is used to represent a JavaScript value.
625
626### napi_threadsafe_function
627<!-- YAML
628added: v10.6.0
629napiVersion: 4
630-->
631
632This is an opaque pointer that represents a JavaScript function which can be
633called asynchronously from multiple threads via
634`napi_call_threadsafe_function()`.
635
636### napi_threadsafe_function_release_mode
637<!-- YAML
638added: v10.6.0
639napiVersion: 4
640-->
641
642A value to be given to `napi_release_threadsafe_function()` to indicate whether
643the thread-safe function is to be closed immediately (`napi_tsfn_abort`) or
644merely released (`napi_tsfn_release`) and thus available for subsequent use via
645`napi_acquire_threadsafe_function()` and `napi_call_threadsafe_function()`.
646
647```c
648typedef enum {
649  napi_tsfn_release,
650  napi_tsfn_abort
651} napi_threadsafe_function_release_mode;
652```
653
654### napi_threadsafe_function_call_mode
655<!-- YAML
656added: v10.6.0
657napiVersion: 4
658-->
659
660A value to be given to `napi_call_threadsafe_function()` to indicate whether
661the call should block whenever the queue associated with the thread-safe
662function is full.
663
664```c
665typedef enum {
666  napi_tsfn_nonblocking,
667  napi_tsfn_blocking
668} napi_threadsafe_function_call_mode;
669```
670
671### Node-API memory management types
672#### napi_handle_scope
673
674This is an abstraction used to control and modify the lifetime of objects
675created within a particular scope. In general, Node-API values are created
676within the context of a handle scope. When a native method is called from
677JavaScript, a default handle scope will exist. If the user does not explicitly
678create a new handle scope, Node-API values will be created in the default handle
679scope. For any invocations of code outside the execution of a native method
680(for instance, during a libuv callback invocation), the module is required to
681create a scope before invoking any functions that can result in the creation
682of JavaScript values.
683
684Handle scopes are created using [`napi_open_handle_scope`][] and are destroyed
685using [`napi_close_handle_scope`][]. Closing the scope can indicate to the GC
686that all `napi_value`s created during the lifetime of the handle scope are no
687longer referenced from the current stack frame.
688
689For more details, review the [Object lifetime management][].
690
691#### napi_escapable_handle_scope
692<!-- YAML
693added: v8.0.0
694napiVersion: 1
695-->
696Escapable handle scopes are a special type of handle scope to return values
697created within a particular handle scope to a parent scope.
698
699#### napi_ref
700<!-- YAML
701added: v8.0.0
702napiVersion: 1
703-->
704This is the abstraction to use to reference a `napi_value`. This allows for
705users to manage the lifetimes of JavaScript values, including defining their
706minimum lifetimes explicitly.
707
708For more details, review the [Object lifetime management][].
709
710#### napi_type_tag
711<!-- YAML
712added:
713  - v14.8.0
714  - v12.19.0
715napiVersion: 8
716-->
717
718A 128-bit value stored as two unsigned 64-bit integers. It serves as a UUID
719with which JavaScript objects can be "tagged" in order to ensure that they are
720of a certain type. This is a stronger check than [`napi_instanceof`][], because
721the latter can report a false positive if the object's prototype has been
722manipulated. Type-tagging is most useful in conjunction with [`napi_wrap`][]
723because it ensures that the pointer retrieved from a wrapped object can be
724safely cast to the native type corresponding to the type tag that had been
725previously applied to the JavaScript object.
726
727```c
728typedef struct {
729  uint64_t lower;
730  uint64_t upper;
731} napi_type_tag;
732```
733
734#### napi_async_cleanup_hook_handle
735<!-- YAML
736added: v14.10.0
737-->
738
739An opaque value returned by [`napi_add_async_cleanup_hook`][]. It must be passed
740to [`napi_remove_async_cleanup_hook`][] when the chain of asynchronous cleanup
741events completes.
742
743### Node-API callback types
744
745#### napi_callback_info
746<!-- YAML
747added: v8.0.0
748napiVersion: 1
749-->
750Opaque datatype that is passed to a callback function. It can be used for
751getting additional information about the context in which the callback was
752invoked.
753
754#### napi_callback
755<!-- YAML
756added: v8.0.0
757napiVersion: 1
758-->
759Function pointer type for user-provided native functions which are to be
760exposed to JavaScript via Node-API. Callback functions should satisfy the
761following signature:
762
763```c
764typedef napi_value (*napi_callback)(napi_env, napi_callback_info);
765```
766
767Unless for reasons discussed in [Object Lifetime Management][], creating a
768handle and/or callback scope inside a `napi_callback` is not necessary.
769
770#### napi_finalize
771<!-- YAML
772added: v8.0.0
773napiVersion: 1
774-->
775Function pointer type for add-on provided functions that allow the user to be
776notified when externally-owned data is ready to be cleaned up because the
777object with which it was associated with, has been garbage-collected. The user
778must provide a function satisfying the following signature which would get
779called upon the object's collection. Currently, `napi_finalize` can be used for
780finding out when objects that have external data are collected.
781
782```c
783typedef void (*napi_finalize)(napi_env env,
784                              void* finalize_data,
785                              void* finalize_hint);
786```
787
788Unless for reasons discussed in [Object Lifetime Management][], creating a
789handle and/or callback scope inside the function body is not necessary.
790
791#### napi_async_execute_callback
792<!-- YAML
793added: v8.0.0
794napiVersion: 1
795-->
796Function pointer used with functions that support asynchronous
797operations. Callback functions must satisfy the following signature:
798
799```c
800typedef void (*napi_async_execute_callback)(napi_env env, void* data);
801```
802
803Implementations of this function must avoid making Node-API calls that execute
804JavaScript or interact with JavaScript objects. Node-API calls should be in the
805`napi_async_complete_callback` instead. Do not use the `napi_env` parameter as
806it will likely result in execution of JavaScript.
807
808#### napi_async_complete_callback
809<!-- YAML
810added: v8.0.0
811napiVersion: 1
812-->
813Function pointer used with functions that support asynchronous
814operations. Callback functions must satisfy the following signature:
815
816```c
817typedef void (*napi_async_complete_callback)(napi_env env,
818                                             napi_status status,
819                                             void* data);
820```
821
822Unless for reasons discussed in [Object Lifetime Management][], creating a
823handle and/or callback scope inside the function body is not necessary.
824
825#### napi_threadsafe_function_call_js
826<!-- YAML
827added: v10.6.0
828napiVersion: 4
829-->
830
831Function pointer used with asynchronous thread-safe function calls. The callback
832will be called on the main thread. Its purpose is to use a data item arriving
833via the queue from one of the secondary threads to construct the parameters
834necessary for a call into JavaScript, usually via `napi_call_function`, and then
835make the call into JavaScript.
836
837The data arriving from the secondary thread via the queue is given in the `data`
838parameter and the JavaScript function to call is given in the `js_callback`
839parameter.
840
841Node-API sets up the environment prior to calling this callback, so it is
842sufficient to call the JavaScript function via `napi_call_function` rather than
843via `napi_make_callback`.
844
845Callback functions must satisfy the following signature:
846
847```c
848typedef void (*napi_threadsafe_function_call_js)(napi_env env,
849                                                 napi_value js_callback,
850                                                 void* context,
851                                                 void* data);
852```
853
854* `[in] env`: The environment to use for API calls, or `NULL` if the thread-safe
855  function is being torn down and `data` may need to be freed.
856* `[in] js_callback`: The JavaScript function to call, or `NULL` if the
857  thread-safe function is being torn down and `data` may need to be freed. It
858  may also be `NULL` if the thread-safe function was created without
859  `js_callback`.
860* `[in] context`: The optional data with which the thread-safe function was
861  created.
862* `[in] data`: Data created by the secondary thread. It is the responsibility of
863  the callback to convert this native data to JavaScript values (with Node-API
864  functions) that can be passed as parameters when `js_callback` is invoked.
865  This pointer is managed entirely by the threads and this callback. Thus this
866  callback should free the data.
867
868Unless for reasons discussed in [Object Lifetime Management][], creating a
869handle and/or callback scope inside the function body is not necessary.
870
871#### napi_async_cleanup_hook
872<!-- YAML
873added: v14.10.0
874-->
875
876Function pointer used with [`napi_add_async_cleanup_hook`][]. It will be called
877when the environment is being torn down.
878
879Callback functions must satisfy the following signature:
880
881```c
882typedef void (*napi_async_cleanup_hook)(napi_async_cleanup_hook_handle handle,
883                                        void* data);
884```
885
886* `[in] handle`: The handle that must be passed to
887  [`napi_remove_async_cleanup_hook`][] after completion of the asynchronous
888  cleanup.
889* `[in] data`: The data that was passed to [`napi_add_async_cleanup_hook`][].
890
891The body of the function should initiate the asynchronous cleanup actions at the
892end of which `handle` must be passed in a call to
893[`napi_remove_async_cleanup_hook`][].
894
895## Error handling
896
897Node-API uses both return values and JavaScript exceptions for error handling.
898The following sections explain the approach for each case.
899
900### Return values
901
902All of the Node-API functions share the same error handling pattern. The
903return type of all API functions is `napi_status`.
904
905The return value will be `napi_ok` if the request was successful and
906no uncaught JavaScript exception was thrown. If an error occurred AND
907an exception was thrown, the `napi_status` value for the error
908will be returned. If an exception was thrown, and no error occurred,
909`napi_pending_exception` will be returned.
910
911In cases where a return value other than `napi_ok` or
912`napi_pending_exception` is returned, [`napi_is_exception_pending`][]
913must be called to check if an exception is pending.
914See the section on exceptions for more details.
915
916The full set of possible `napi_status` values is defined
917in `napi_api_types.h`.
918
919The `napi_status` return value provides a VM-independent representation of
920the error which occurred. In some cases it is useful to be able to get
921more detailed information, including a string representing the error as well as
922VM (engine)-specific information.
923
924In order to retrieve this information [`napi_get_last_error_info`][]
925is provided which returns a `napi_extended_error_info` structure.
926The format of the `napi_extended_error_info` structure is as follows:
927
928<!-- YAML
929added: v8.0.0
930napiVersion: 1
931-->
932
933```c
934typedef struct napi_extended_error_info {
935  const char* error_message;
936  void* engine_reserved;
937  uint32_t engine_error_code;
938  napi_status error_code;
939};
940```
941
942* `error_message`: Textual representation of the error that occurred.
943* `engine_reserved`: Opaque handle reserved for engine use only.
944* `engine_error_code`: VM specific error code.
945* `error_code`: Node-API status code for the last error.
946
947[`napi_get_last_error_info`][] returns the information for the last
948Node-API call that was made.
949
950Do not rely on the content or format of any of the extended information as it
951is not subject to SemVer and may change at any time. It is intended only for
952logging purposes.
953
954#### napi_get_last_error_info
955<!-- YAML
956added: v8.0.0
957napiVersion: 1
958-->
959
960```c
961napi_status
962napi_get_last_error_info(napi_env env,
963                         const napi_extended_error_info** result);
964```
965
966* `[in] env`: The environment that the API is invoked under.
967* `[out] result`: The `napi_extended_error_info` structure with more
968  information about the error.
969
970Returns `napi_ok` if the API succeeded.
971
972This API retrieves a `napi_extended_error_info` structure with information
973about the last error that occurred.
974
975The content of the `napi_extended_error_info` returned is only valid up until
976a Node-API function is called on the same `env`.
977
978Do not rely on the content or format of any of the extended information as it
979is not subject to SemVer and may change at any time. It is intended only for
980logging purposes.
981
982This API can be called even if there is a pending JavaScript exception.
983
984### Exceptions
985
986Any Node-API function call may result in a pending JavaScript exception. This is
987the case for any of the API functions, even those that may not cause the
988execution of JavaScript.
989
990If the `napi_status` returned by a function is `napi_ok` then no
991exception is pending and no additional action is required. If the
992`napi_status` returned is anything other than `napi_ok` or
993`napi_pending_exception`, in order to try to recover and continue
994instead of simply returning immediately, [`napi_is_exception_pending`][]
995must be called in order to determine if an exception is pending or not.
996
997In many cases when a Node-API function is called and an exception is
998already pending, the function will return immediately with a
999`napi_status` of `napi_pending_exception`. However, this is not the case
1000for all functions. Node-API allows a subset of the functions to be
1001called to allow for some minimal cleanup before returning to JavaScript.
1002In that case, `napi_status` will reflect the status for the function. It
1003will not reflect previous pending exceptions. To avoid confusion, check
1004the error status after every function call.
1005
1006When an exception is pending one of two approaches can be employed.
1007
1008The first approach is to do any appropriate cleanup and then return so that
1009execution will return to JavaScript. As part of the transition back to
1010JavaScript, the exception will be thrown at the point in the JavaScript
1011code where the native method was invoked. The behavior of most Node-API calls
1012is unspecified while an exception is pending, and many will simply return
1013`napi_pending_exception`, so do as little as possible and then return to
1014JavaScript where the exception can be handled.
1015
1016The second approach is to try to handle the exception. There will be cases
1017where the native code can catch the exception, take the appropriate action,
1018and then continue. This is only recommended in specific cases
1019where it is known that the exception can be safely handled. In these
1020cases [`napi_get_and_clear_last_exception`][] can be used to get and
1021clear the exception. On success, result will contain the handle to
1022the last JavaScript `Object` thrown. If it is determined, after
1023retrieving the exception, the exception cannot be handled after all
1024it can be re-thrown it with [`napi_throw`][] where error is the
1025JavaScript value to be thrown.
1026
1027The following utility functions are also available in case native code
1028needs to throw an exception or determine if a `napi_value` is an instance
1029of a JavaScript `Error` object: [`napi_throw_error`][],
1030[`napi_throw_type_error`][], [`napi_throw_range_error`][] and
1031[`napi_is_error`][].
1032
1033The following utility functions are also available in case native
1034code needs to create an `Error` object: [`napi_create_error`][],
1035[`napi_create_type_error`][], and [`napi_create_range_error`][],
1036where result is the `napi_value` that refers to the newly created
1037JavaScript `Error` object.
1038
1039The Node.js project is adding error codes to all of the errors
1040generated internally. The goal is for applications to use these
1041error codes for all error checking. The associated error messages
1042will remain, but will only be meant to be used for logging and
1043display with the expectation that the message can change without
1044SemVer applying. In order to support this model with Node-API, both
1045in internal functionality and for module specific functionality
1046(as its good practice), the `throw_` and `create_` functions
1047take an optional code parameter which is the string for the code
1048to be added to the error object. If the optional parameter is `NULL`
1049then no code will be associated with the error. If a code is provided,
1050the name associated with the error is also updated to be:
1051
1052```text
1053originalName [code]
1054```
1055
1056where `originalName` is the original name associated with the error
1057and `code` is the code that was provided. For example, if the code
1058is `'ERR_ERROR_1'` and a `TypeError` is being created the name will be:
1059
1060```text
1061TypeError [ERR_ERROR_1]
1062```
1063
1064#### napi_throw
1065<!-- YAML
1066added: v8.0.0
1067napiVersion: 1
1068-->
1069
1070```c
1071NAPI_EXTERN napi_status napi_throw(napi_env env, napi_value error);
1072```
1073
1074* `[in] env`: The environment that the API is invoked under.
1075* `[in] error`: The JavaScript value to be thrown.
1076
1077Returns `napi_ok` if the API succeeded.
1078
1079This API throws the JavaScript value provided.
1080
1081#### napi_throw_error
1082<!-- YAML
1083added: v8.0.0
1084napiVersion: 1
1085-->
1086
1087```c
1088NAPI_EXTERN napi_status napi_throw_error(napi_env env,
1089                                         const char* code,
1090                                         const char* msg);
1091```
1092
1093* `[in] env`: The environment that the API is invoked under.
1094* `[in] code`: Optional error code to be set on the error.
1095* `[in] msg`: C string representing the text to be associated with the error.
1096
1097Returns `napi_ok` if the API succeeded.
1098
1099This API throws a JavaScript `Error` with the text provided.
1100
1101#### napi_throw_type_error
1102<!-- YAML
1103added: v8.0.0
1104napiVersion: 1
1105-->
1106
1107```c
1108NAPI_EXTERN napi_status napi_throw_type_error(napi_env env,
1109                                              const char* code,
1110                                              const char* msg);
1111```
1112
1113* `[in] env`: The environment that the API is invoked under.
1114* `[in] code`: Optional error code to be set on the error.
1115* `[in] msg`: C string representing the text to be associated with the error.
1116
1117Returns `napi_ok` if the API succeeded.
1118
1119This API throws a JavaScript `TypeError` with the text provided.
1120
1121#### napi_throw_range_error
1122<!-- YAML
1123added: v8.0.0
1124napiVersion: 1
1125-->
1126
1127```c
1128NAPI_EXTERN napi_status napi_throw_range_error(napi_env env,
1129                                               const char* code,
1130                                               const char* msg);
1131```
1132
1133* `[in] env`: The environment that the API is invoked under.
1134* `[in] code`: Optional error code to be set on the error.
1135* `[in] msg`: C string representing the text to be associated with the error.
1136
1137Returns `napi_ok` if the API succeeded.
1138
1139This API throws a JavaScript `RangeError` with the text provided.
1140
1141#### napi_is_error
1142<!-- YAML
1143added: v8.0.0
1144napiVersion: 1
1145-->
1146
1147```c
1148NAPI_EXTERN napi_status napi_is_error(napi_env env,
1149                                      napi_value value,
1150                                      bool* result);
1151```
1152
1153* `[in] env`: The environment that the API is invoked under.
1154* `[in] value`: The `napi_value` to be checked.
1155* `[out] result`: Boolean value that is set to true if `napi_value` represents
1156  an error, false otherwise.
1157
1158Returns `napi_ok` if the API succeeded.
1159
1160This API queries a `napi_value` to check if it represents an error object.
1161
1162#### napi_create_error
1163<!-- YAML
1164added: v8.0.0
1165napiVersion: 1
1166-->
1167
1168```c
1169NAPI_EXTERN napi_status napi_create_error(napi_env env,
1170                                          napi_value code,
1171                                          napi_value msg,
1172                                          napi_value* result);
1173```
1174
1175* `[in] env`: The environment that the API is invoked under.
1176* `[in] code`: Optional `napi_value` with the string for the error code to be
1177  associated with the error.
1178* `[in] msg`: `napi_value` that references a JavaScript `string` to be used as
1179  the message for the `Error`.
1180* `[out] result`: `napi_value` representing the error created.
1181
1182Returns `napi_ok` if the API succeeded.
1183
1184This API returns a JavaScript `Error` with the text provided.
1185
1186#### napi_create_type_error
1187<!-- YAML
1188added: v8.0.0
1189napiVersion: 1
1190-->
1191
1192```c
1193NAPI_EXTERN napi_status napi_create_type_error(napi_env env,
1194                                               napi_value code,
1195                                               napi_value msg,
1196                                               napi_value* result);
1197```
1198
1199* `[in] env`: The environment that the API is invoked under.
1200* `[in] code`: Optional `napi_value` with the string for the error code to be
1201  associated with the error.
1202* `[in] msg`: `napi_value` that references a JavaScript `string` to be used as
1203  the message for the `Error`.
1204* `[out] result`: `napi_value` representing the error created.
1205
1206Returns `napi_ok` if the API succeeded.
1207
1208This API returns a JavaScript `TypeError` with the text provided.
1209
1210#### napi_create_range_error
1211<!-- YAML
1212added: v8.0.0
1213napiVersion: 1
1214-->
1215
1216```c
1217NAPI_EXTERN napi_status napi_create_range_error(napi_env env,
1218                                                napi_value code,
1219                                                napi_value msg,
1220                                                napi_value* result);
1221```
1222
1223* `[in] env`: The environment that the API is invoked under.
1224* `[in] code`: Optional `napi_value` with the string for the error code to be
1225  associated with the error.
1226* `[in] msg`: `napi_value` that references a JavaScript `string` to be used as
1227  the message for the `Error`.
1228* `[out] result`: `napi_value` representing the error created.
1229
1230Returns `napi_ok` if the API succeeded.
1231
1232This API returns a JavaScript `RangeError` with the text provided.
1233
1234#### napi_get_and_clear_last_exception
1235<!-- YAML
1236added: v8.0.0
1237napiVersion: 1
1238-->
1239
1240```c
1241napi_status napi_get_and_clear_last_exception(napi_env env,
1242                                              napi_value* result);
1243```
1244
1245* `[in] env`: The environment that the API is invoked under.
1246* `[out] result`: The exception if one is pending, `NULL` otherwise.
1247
1248Returns `napi_ok` if the API succeeded.
1249
1250This API can be called even if there is a pending JavaScript exception.
1251
1252#### napi_is_exception_pending
1253<!-- YAML
1254added: v8.0.0
1255napiVersion: 1
1256-->
1257
1258```c
1259napi_status napi_is_exception_pending(napi_env env, bool* result);
1260```
1261
1262* `[in] env`: The environment that the API is invoked under.
1263* `[out] result`: Boolean value that is set to true if an exception is pending.
1264
1265Returns `napi_ok` if the API succeeded.
1266
1267This API can be called even if there is a pending JavaScript exception.
1268
1269#### napi_fatal_exception
1270<!-- YAML
1271added: v9.10.0
1272napiVersion: 3
1273-->
1274
1275```c
1276napi_status napi_fatal_exception(napi_env env, napi_value err);
1277```
1278
1279* `[in] env`: The environment that the API is invoked under.
1280* `[in] err`: The error that is passed to `'uncaughtException'`.
1281
1282Trigger an `'uncaughtException'` in JavaScript. Useful if an async
1283callback throws an exception with no way to recover.
1284
1285### Fatal errors
1286
1287In the event of an unrecoverable error in a native module, a fatal error can be
1288thrown to immediately terminate the process.
1289
1290#### napi_fatal_error
1291<!-- YAML
1292added: v8.2.0
1293napiVersion: 1
1294-->
1295
1296```c
1297NAPI_NO_RETURN void napi_fatal_error(const char* location,
1298                                     size_t location_len,
1299                                     const char* message,
1300                                     size_t message_len);
1301```
1302
1303* `[in] location`: Optional location at which the error occurred.
1304* `[in] location_len`: The length of the location in bytes, or
1305  `NAPI_AUTO_LENGTH` if it is null-terminated.
1306* `[in] message`: The message associated with the error.
1307* `[in] message_len`: The length of the message in bytes, or `NAPI_AUTO_LENGTH`
1308  if it is null-terminated.
1309
1310The function call does not return, the process will be terminated.
1311
1312This API can be called even if there is a pending JavaScript exception.
1313
1314## Object lifetime management
1315
1316As Node-API calls are made, handles to objects in the heap for the underlying
1317VM may be returned as `napi_values`. These handles must hold the
1318objects 'live' until they are no longer required by the native code,
1319otherwise the objects could be collected before the native code was
1320finished using them.
1321
1322As object handles are returned they are associated with a
1323'scope'. The lifespan for the default scope is tied to the lifespan
1324of the native method call. The result is that, by default, handles
1325remain valid and the objects associated with these handles will be
1326held live for the lifespan of the native method call.
1327
1328In many cases, however, it is necessary that the handles remain valid for
1329either a shorter or longer lifespan than that of the native method.
1330The sections which follow describe the Node-API functions that can be used
1331to change the handle lifespan from the default.
1332
1333### Making handle lifespan shorter than that of the native method
1334It is often necessary to make the lifespan of handles shorter than
1335the lifespan of a native method. For example, consider a native method
1336that has a loop which iterates through the elements in a large array:
1337
1338```c
1339for (int i = 0; i < 1000000; i++) {
1340  napi_value result;
1341  napi_status status = napi_get_element(env, object, i, &result);
1342  if (status != napi_ok) {
1343    break;
1344  }
1345  // do something with element
1346}
1347```
1348
1349This would result in a large number of handles being created, consuming
1350substantial resources. In addition, even though the native code could only
1351use the most recent handle, all of the associated objects would also be
1352kept alive since they all share the same scope.
1353
1354To handle this case, Node-API provides the ability to establish a new 'scope' to
1355which newly created handles will be associated. Once those handles
1356are no longer required, the scope can be 'closed' and any handles associated
1357with the scope are invalidated. The methods available to open/close scopes are
1358[`napi_open_handle_scope`][] and [`napi_close_handle_scope`][].
1359
1360Node-API only supports a single nested hierarchy of scopes. There is only one
1361active scope at any time, and all new handles will be associated with that
1362scope while it is active. Scopes must be closed in the reverse order from
1363which they are opened. In addition, all scopes created within a native method
1364must be closed before returning from that method.
1365
1366Taking the earlier example, adding calls to [`napi_open_handle_scope`][] and
1367[`napi_close_handle_scope`][] would ensure that at most a single handle
1368is valid throughout the execution of the loop:
1369
1370```c
1371for (int i = 0; i < 1000000; i++) {
1372  napi_handle_scope scope;
1373  napi_status status = napi_open_handle_scope(env, &scope);
1374  if (status != napi_ok) {
1375    break;
1376  }
1377  napi_value result;
1378  status = napi_get_element(env, object, i, &result);
1379  if (status != napi_ok) {
1380    break;
1381  }
1382  // do something with element
1383  status = napi_close_handle_scope(env, scope);
1384  if (status != napi_ok) {
1385    break;
1386  }
1387}
1388```
1389
1390When nesting scopes, there are cases where a handle from an
1391inner scope needs to live beyond the lifespan of that scope. Node-API supports
1392an 'escapable scope' in order to support this case. An escapable scope
1393allows one handle to be 'promoted' so that it 'escapes' the
1394current scope and the lifespan of the handle changes from the current
1395scope to that of the outer scope.
1396
1397The methods available to open/close escapable scopes are
1398[`napi_open_escapable_handle_scope`][] and
1399[`napi_close_escapable_handle_scope`][].
1400
1401The request to promote a handle is made through [`napi_escape_handle`][] which
1402can only be called once.
1403
1404#### napi_open_handle_scope
1405<!-- YAML
1406added: v8.0.0
1407napiVersion: 1
1408-->
1409
1410```c
1411NAPI_EXTERN napi_status napi_open_handle_scope(napi_env env,
1412                                               napi_handle_scope* result);
1413```
1414
1415* `[in] env`: The environment that the API is invoked under.
1416* `[out] result`: `napi_value` representing the new scope.
1417
1418Returns `napi_ok` if the API succeeded.
1419
1420This API opens a new scope.
1421
1422#### napi_close_handle_scope
1423<!-- YAML
1424added: v8.0.0
1425napiVersion: 1
1426-->
1427
1428```c
1429NAPI_EXTERN napi_status napi_close_handle_scope(napi_env env,
1430                                                napi_handle_scope scope);
1431```
1432
1433* `[in] env`: The environment that the API is invoked under.
1434* `[in] scope`: `napi_value` representing the scope to be closed.
1435
1436Returns `napi_ok` if the API succeeded.
1437
1438This API closes the scope passed in. Scopes must be closed in the
1439reverse order from which they were created.
1440
1441This API can be called even if there is a pending JavaScript exception.
1442
1443#### napi_open_escapable_handle_scope
1444<!-- YAML
1445added: v8.0.0
1446napiVersion: 1
1447-->
1448
1449```c
1450NAPI_EXTERN napi_status
1451    napi_open_escapable_handle_scope(napi_env env,
1452                                     napi_handle_scope* result);
1453```
1454
1455* `[in] env`: The environment that the API is invoked under.
1456* `[out] result`: `napi_value` representing the new scope.
1457
1458Returns `napi_ok` if the API succeeded.
1459
1460This API opens a new scope from which one object can be promoted
1461to the outer scope.
1462
1463#### napi_close_escapable_handle_scope
1464<!-- YAML
1465added: v8.0.0
1466napiVersion: 1
1467-->
1468
1469```c
1470NAPI_EXTERN napi_status
1471    napi_close_escapable_handle_scope(napi_env env,
1472                                      napi_handle_scope scope);
1473```
1474
1475* `[in] env`: The environment that the API is invoked under.
1476* `[in] scope`: `napi_value` representing the scope to be closed.
1477
1478Returns `napi_ok` if the API succeeded.
1479
1480This API closes the scope passed in. Scopes must be closed in the
1481reverse order from which they were created.
1482
1483This API can be called even if there is a pending JavaScript exception.
1484
1485#### napi_escape_handle
1486<!-- YAML
1487added: v8.0.0
1488napiVersion: 1
1489-->
1490
1491```c
1492napi_status napi_escape_handle(napi_env env,
1493                               napi_escapable_handle_scope scope,
1494                               napi_value escapee,
1495                               napi_value* result);
1496```
1497
1498* `[in] env`: The environment that the API is invoked under.
1499* `[in] scope`: `napi_value` representing the current scope.
1500* `[in] escapee`: `napi_value` representing the JavaScript `Object` to be
1501  escaped.
1502* `[out] result`: `napi_value` representing the handle to the escaped `Object`
1503  in the outer scope.
1504
1505Returns `napi_ok` if the API succeeded.
1506
1507This API promotes the handle to the JavaScript object so that it is valid
1508for the lifetime of the outer scope. It can only be called once per scope.
1509If it is called more than once an error will be returned.
1510
1511This API can be called even if there is a pending JavaScript exception.
1512
1513### References to objects with a lifespan longer than that of the native method
1514
1515In some cases an addon will need to be able to create and reference objects
1516with a lifespan longer than that of a single native method invocation. For
1517example, to create a constructor and later use that constructor
1518in a request to creates instances, it must be possible to reference
1519the constructor object across many different instance creation requests. This
1520would not be possible with a normal handle returned as a `napi_value` as
1521described in the earlier section. The lifespan of a normal handle is
1522managed by scopes and all scopes must be closed before the end of a native
1523method.
1524
1525Node-API provides methods to create persistent references to an object.
1526Each persistent reference has an associated count with a value of 0
1527or higher. The count determines if the reference will keep
1528the corresponding object live. References with a count of 0 do not
1529prevent the object from being collected and are often called 'weak'
1530references. Any count greater than 0 will prevent the object
1531from being collected.
1532
1533References can be created with an initial reference count. The count can
1534then be modified through [`napi_reference_ref`][] and
1535[`napi_reference_unref`][]. If an object is collected while the count
1536for a reference is 0, all subsequent calls to
1537get the object associated with the reference [`napi_get_reference_value`][]
1538will return `NULL` for the returned `napi_value`. An attempt to call
1539[`napi_reference_ref`][] for a reference whose object has been collected
1540results in an error.
1541
1542References must be deleted once they are no longer required by the addon. When
1543a reference is deleted, it will no longer prevent the corresponding object from
1544being collected. Failure to delete a persistent reference results in
1545a 'memory leak' with both the native memory for the persistent reference and
1546the corresponding object on the heap being retained forever.
1547
1548There can be multiple persistent references created which refer to the same
1549object, each of which will either keep the object live or not based on its
1550individual count.
1551
1552#### napi_create_reference
1553<!-- YAML
1554added: v8.0.0
1555napiVersion: 1
1556-->
1557
1558```c
1559NAPI_EXTERN napi_status napi_create_reference(napi_env env,
1560                                              napi_value value,
1561                                              uint32_t initial_refcount,
1562                                              napi_ref* result);
1563```
1564
1565* `[in] env`: The environment that the API is invoked under.
1566* `[in] value`: `napi_value` representing the `Object` to which we want a
1567  reference.
1568* `[in] initial_refcount`: Initial reference count for the new reference.
1569* `[out] result`: `napi_ref` pointing to the new reference.
1570
1571Returns `napi_ok` if the API succeeded.
1572
1573This API create a new reference with the specified reference count
1574to the `Object` passed in.
1575
1576#### napi_delete_reference
1577<!-- YAML
1578added: v8.0.0
1579napiVersion: 1
1580-->
1581
1582```c
1583NAPI_EXTERN napi_status napi_delete_reference(napi_env env, napi_ref ref);
1584```
1585
1586* `[in] env`: The environment that the API is invoked under.
1587* `[in] ref`: `napi_ref` to be deleted.
1588
1589Returns `napi_ok` if the API succeeded.
1590
1591This API deletes the reference passed in.
1592
1593This API can be called even if there is a pending JavaScript exception.
1594
1595#### napi_reference_ref
1596<!-- YAML
1597added: v8.0.0
1598napiVersion: 1
1599-->
1600
1601```c
1602NAPI_EXTERN napi_status napi_reference_ref(napi_env env,
1603                                           napi_ref ref,
1604                                           uint32_t* result);
1605```
1606
1607* `[in] env`: The environment that the API is invoked under.
1608* `[in] ref`: `napi_ref` for which the reference count will be incremented.
1609* `[out] result`: The new reference count.
1610
1611Returns `napi_ok` if the API succeeded.
1612
1613This API increments the reference count for the reference
1614passed in and returns the resulting reference count.
1615
1616#### napi_reference_unref
1617<!-- YAML
1618added: v8.0.0
1619napiVersion: 1
1620-->
1621
1622```c
1623NAPI_EXTERN napi_status napi_reference_unref(napi_env env,
1624                                             napi_ref ref,
1625                                             uint32_t* result);
1626```
1627
1628* `[in] env`: The environment that the API is invoked under.
1629* `[in] ref`: `napi_ref` for which the reference count will be decremented.
1630* `[out] result`: The new reference count.
1631
1632Returns `napi_ok` if the API succeeded.
1633
1634This API decrements the reference count for the reference
1635passed in and returns the resulting reference count.
1636
1637#### napi_get_reference_value
1638<!-- YAML
1639added: v8.0.0
1640napiVersion: 1
1641-->
1642
1643```c
1644NAPI_EXTERN napi_status napi_get_reference_value(napi_env env,
1645                                                 napi_ref ref,
1646                                                 napi_value* result);
1647```
1648
1649the `napi_value passed` in or out of these methods is a handle to the
1650object to which the reference is related.
1651
1652* `[in] env`: The environment that the API is invoked under.
1653* `[in] ref`: `napi_ref` for which we requesting the corresponding `Object`.
1654* `[out] result`: The `napi_value` for the `Object` referenced by the
1655  `napi_ref`.
1656
1657Returns `napi_ok` if the API succeeded.
1658
1659If still valid, this API returns the `napi_value` representing the
1660JavaScript `Object` associated with the `napi_ref`. Otherwise, result
1661will be `NULL`.
1662
1663### Cleanup on exit of the current Node.js instance
1664
1665While a Node.js process typically releases all its resources when exiting,
1666embedders of Node.js, or future Worker support, may require addons to register
1667clean-up hooks that will be run once the current Node.js instance exits.
1668
1669Node-API provides functions for registering and un-registering such callbacks.
1670When those callbacks are run, all resources that are being held by the addon
1671should be freed up.
1672
1673#### napi_add_env_cleanup_hook
1674<!-- YAML
1675added: v10.2.0
1676napiVersion: 3
1677-->
1678
1679```c
1680NODE_EXTERN napi_status napi_add_env_cleanup_hook(napi_env env,
1681                                                  void (*fun)(void* arg),
1682                                                  void* arg);
1683```
1684
1685Registers `fun` as a function to be run with the `arg` parameter once the
1686current Node.js environment exits.
1687
1688A function can safely be specified multiple times with different
1689`arg` values. In that case, it will be called multiple times as well.
1690Providing the same `fun` and `arg` values multiple times is not allowed
1691and will lead the process to abort.
1692
1693The hooks will be called in reverse order, i.e. the most recently added one
1694will be called first.
1695
1696Removing this hook can be done by using [`napi_remove_env_cleanup_hook`][].
1697Typically, that happens when the resource for which this hook was added
1698is being torn down anyway.
1699
1700For asynchronous cleanup, [`napi_add_async_cleanup_hook`][] is available.
1701
1702#### napi_remove_env_cleanup_hook
1703<!-- YAML
1704added: v10.2.0
1705napiVersion: 3
1706-->
1707
1708```c
1709NAPI_EXTERN napi_status napi_remove_env_cleanup_hook(napi_env env,
1710                                                     void (*fun)(void* arg),
1711                                                     void* arg);
1712```
1713
1714Unregisters `fun` as a function to be run with the `arg` parameter once the
1715current Node.js environment exits. Both the argument and the function value
1716need to be exact matches.
1717
1718The function must have originally been registered
1719with `napi_add_env_cleanup_hook`, otherwise the process will abort.
1720
1721#### napi_add_async_cleanup_hook
1722<!-- YAML
1723added:
1724  - v14.8.0
1725  - v12.19.0
1726napiVersion: 8
1727changes:
1728  - version: v14.10.0
1729    pr-url: https://github.com/nodejs/node/pull/34819
1730    description: Changed signature of the `hook` callback.
1731-->
1732
1733```c
1734NAPI_EXTERN napi_status napi_add_async_cleanup_hook(
1735    napi_env env,
1736    napi_async_cleanup_hook hook,
1737    void* arg,
1738    napi_async_cleanup_hook_handle* remove_handle);
1739```
1740
1741* `[in] env`: The environment that the API is invoked under.
1742* `[in] hook`: The function pointer to call at environment teardown.
1743* `[in] arg`: The pointer to pass to `hook` when it gets called.
1744* `[out] remove_handle`: Optional handle that refers to the asynchronous cleanup
1745  hook.
1746
1747Registers `hook`, which is a function of type [`napi_async_cleanup_hook`][], as
1748a function to be run with the `remove_handle` and `arg` parameters once the
1749current Node.js environment exits.
1750
1751Unlike [`napi_add_env_cleanup_hook`][], the hook is allowed to be asynchronous.
1752
1753Otherwise, behavior generally matches that of [`napi_add_env_cleanup_hook`][].
1754
1755If `remove_handle` is not `NULL`, an opaque value will be stored in it
1756that must later be passed to [`napi_remove_async_cleanup_hook`][],
1757regardless of whether the hook has already been invoked.
1758Typically, that happens when the resource for which this hook was added
1759is being torn down anyway.
1760
1761#### napi_remove_async_cleanup_hook
1762<!-- YAML
1763added: v14.8.0
1764changes:
1765  - version: v14.10.0
1766    pr-url: https://github.com/nodejs/node/pull/34819
1767    description: Removed `env` parameter.
1768-->
1769
1770```c
1771NAPI_EXTERN napi_status napi_remove_async_cleanup_hook(
1772    napi_async_cleanup_hook_handle remove_handle);
1773```
1774
1775* `[in] remove_handle`: The handle to an asynchronous cleanup hook that was
1776  created with [`napi_add_async_cleanup_hook`][].
1777
1778Unregisters the cleanup hook corresponding to `remove_handle`. This will prevent
1779the hook from being executed, unless it has already started executing.
1780This must be called on any `napi_async_cleanup_hook_handle` value obtained
1781from [`napi_add_async_cleanup_hook`][].
1782
1783## Module registration
1784Node-API modules are registered in a manner similar to other modules
1785except that instead of using the `NODE_MODULE` macro the following
1786is used:
1787
1788```c
1789NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
1790```
1791
1792The next difference is the signature for the `Init` method. For a Node-API
1793module it is as follows:
1794
1795```c
1796napi_value Init(napi_env env, napi_value exports);
1797```
1798
1799The return value from `Init` is treated as the `exports` object for the module.
1800The `Init` method is passed an empty object via the `exports` parameter as a
1801convenience. If `Init` returns `NULL`, the parameter passed as `exports` is
1802exported by the module. Node-API modules cannot modify the `module` object but
1803can specify anything as the `exports` property of the module.
1804
1805To add the method `hello` as a function so that it can be called as a method
1806provided by the addon:
1807
1808```c
1809napi_value Init(napi_env env, napi_value exports) {
1810  napi_status status;
1811  napi_property_descriptor desc = {
1812    "hello",
1813    NULL,
1814    Method,
1815    NULL,
1816    NULL,
1817    NULL,
1818    napi_writable | napi_enumerable | napi_configurable,
1819    NULL
1820  };
1821  status = napi_define_properties(env, exports, 1, &desc);
1822  if (status != napi_ok) return NULL;
1823  return exports;
1824}
1825```
1826
1827To set a function to be returned by the `require()` for the addon:
1828
1829```c
1830napi_value Init(napi_env env, napi_value exports) {
1831  napi_value method;
1832  napi_status status;
1833  status = napi_create_function(env, "exports", NAPI_AUTO_LENGTH, Method, NULL, &method);
1834  if (status != napi_ok) return NULL;
1835  return method;
1836}
1837```
1838
1839To define a class so that new instances can be created (often used with
1840[Object wrap][]):
1841
1842```c
1843// NOTE: partial example, not all referenced code is included
1844napi_value Init(napi_env env, napi_value exports) {
1845  napi_status status;
1846  napi_property_descriptor properties[] = {
1847    { "value", NULL, NULL, GetValue, SetValue, NULL, napi_writable | napi_configurable, NULL },
1848    DECLARE_NAPI_METHOD("plusOne", PlusOne),
1849    DECLARE_NAPI_METHOD("multiply", Multiply),
1850  };
1851
1852  napi_value cons;
1853  status =
1854      napi_define_class(env, "MyObject", New, NULL, 3, properties, &cons);
1855  if (status != napi_ok) return NULL;
1856
1857  status = napi_create_reference(env, cons, 1, &constructor);
1858  if (status != napi_ok) return NULL;
1859
1860  status = napi_set_named_property(env, exports, "MyObject", cons);
1861  if (status != napi_ok) return NULL;
1862
1863  return exports;
1864}
1865```
1866
1867You can also use the `NAPI_MODULE_INIT` macro, which acts as a shorthand
1868for `NAPI_MODULE` and defining an `Init` function:
1869
1870```c
1871NAPI_MODULE_INIT() {
1872  napi_value answer;
1873  napi_status result;
1874
1875  status = napi_create_int64(env, 42, &answer);
1876  if (status != napi_ok) return NULL;
1877
1878  status = napi_set_named_property(env, exports, "answer", answer);
1879  if (status != napi_ok) return NULL;
1880
1881  return exports;
1882}
1883```
1884
1885All Node-API addons are context-aware, meaning they may be loaded multiple
1886times. There are a few design considerations when declaring such a module.
1887The documentation on [context-aware addons][] provides more details.
1888
1889The variables `env` and `exports` will be available inside the function body
1890following the macro invocation.
1891
1892For more details on setting properties on objects, see the section on
1893[Working with JavaScript properties][].
1894
1895For more details on building addon modules in general, refer to the existing
1896API.
1897
1898## Working with JavaScript values
1899Node-API exposes a set of APIs to create all types of JavaScript values.
1900Some of these types are documented under [Section 6][]
1901of the [ECMAScript Language Specification][].
1902
1903Fundamentally, these APIs are used to do one of the following:
1904
19051. Create a new JavaScript object
19062. Convert from a primitive C type to a Node-API value
19073. Convert from Node-API value to a primitive C type
19084. Get global instances including `undefined` and `null`
1909
1910Node-API values are represented by the type `napi_value`.
1911Any Node-API call that requires a JavaScript value takes in a `napi_value`.
1912In some cases, the API does check the type of the `napi_value` up-front.
1913However, for better performance, it's better for the caller to make sure that
1914the `napi_value` in question is of the JavaScript type expected by the API.
1915
1916### Enum types
1917#### napi_key_collection_mode
1918<!-- YAML
1919added:
1920 - v13.7.0
1921 - v10.20.0
1922napiVersion: 6
1923-->
1924
1925```c
1926typedef enum {
1927  napi_key_include_prototypes,
1928  napi_key_own_only
1929} napi_key_collection_mode;
1930```
1931
1932Describes the `Keys/Properties` filter enums:
1933
1934`napi_key_collection_mode` limits the range of collected properties.
1935
1936`napi_key_own_only` limits the collected properties to the given
1937object only. `napi_key_include_prototypes` will include all keys
1938of the objects's prototype chain as well.
1939
1940#### napi_key_filter
1941<!-- YAML
1942added:
1943 - v13.7.0
1944 - v10.20.0
1945napiVersion: 6
1946-->
1947
1948```c
1949typedef enum {
1950  napi_key_all_properties = 0,
1951  napi_key_writable = 1,
1952  napi_key_enumerable = 1 << 1,
1953  napi_key_configurable = 1 << 2,
1954  napi_key_skip_strings = 1 << 3,
1955  napi_key_skip_symbols = 1 << 4
1956} napi_key_filter;
1957```
1958
1959Property filter bits. They can be or'ed to build a composite filter.
1960
1961#### napi_key_conversion
1962<!-- YAML
1963added:
1964 - v13.7.0
1965 - v10.20.0
1966napiVersion: 6
1967-->
1968
1969```c
1970typedef enum {
1971  napi_key_keep_numbers,
1972  napi_key_numbers_to_strings
1973} napi_key_conversion;
1974```
1975
1976`napi_key_numbers_to_strings` will convert integer indices to
1977strings. `napi_key_keep_numbers` will return numbers for integer
1978indices.
1979
1980#### napi_valuetype
1981
1982```c
1983typedef enum {
1984  // ES6 types (corresponds to typeof)
1985  napi_undefined,
1986  napi_null,
1987  napi_boolean,
1988  napi_number,
1989  napi_string,
1990  napi_symbol,
1991  napi_object,
1992  napi_function,
1993  napi_external,
1994  napi_bigint,
1995} napi_valuetype;
1996```
1997
1998Describes the type of a `napi_value`. This generally corresponds to the types
1999described in [Section 6.1][] of the ECMAScript Language Specification.
2000In addition to types in that section, `napi_valuetype` can also represent
2001`Function`s and `Object`s with external data.
2002
2003A JavaScript value of type `napi_external` appears in JavaScript as a plain
2004object such that no properties can be set on it, and no prototype.
2005
2006#### napi_typedarray_type
2007
2008```c
2009typedef enum {
2010  napi_int8_array,
2011  napi_uint8_array,
2012  napi_uint8_clamped_array,
2013  napi_int16_array,
2014  napi_uint16_array,
2015  napi_int32_array,
2016  napi_uint32_array,
2017  napi_float32_array,
2018  napi_float64_array,
2019  napi_bigint64_array,
2020  napi_biguint64_array,
2021} napi_typedarray_type;
2022```
2023
2024This represents the underlying binary scalar datatype of the `TypedArray`.
2025Elements of this enum correspond to
2026[Section 22.2][] of the [ECMAScript Language Specification][].
2027
2028### Object creation functions
2029#### napi_create_array
2030<!-- YAML
2031added: v8.0.0
2032napiVersion: 1
2033-->
2034
2035```c
2036napi_status napi_create_array(napi_env env, napi_value* result)
2037```
2038
2039* `[in] env`: The environment that the Node-API call is invoked under.
2040* `[out] result`: A `napi_value` representing a JavaScript `Array`.
2041
2042Returns `napi_ok` if the API succeeded.
2043
2044This API returns a Node-API value corresponding to a JavaScript `Array` type.
2045JavaScript arrays are described in
2046[Section 22.1][] of the ECMAScript Language Specification.
2047
2048#### napi_create_array_with_length
2049<!-- YAML
2050added: v8.0.0
2051napiVersion: 1
2052-->
2053
2054```c
2055napi_status napi_create_array_with_length(napi_env env,
2056                                          size_t length,
2057                                          napi_value* result)
2058```
2059
2060* `[in] env`: The environment that the API is invoked under.
2061* `[in] length`: The initial length of the `Array`.
2062* `[out] result`: A `napi_value` representing a JavaScript `Array`.
2063
2064Returns `napi_ok` if the API succeeded.
2065
2066This API returns a Node-API value corresponding to a JavaScript `Array` type.
2067The `Array`'s length property is set to the passed-in length parameter.
2068However, the underlying buffer is not guaranteed to be pre-allocated by the VM
2069when the array is created. That behavior is left to the underlying VM
2070implementation. If the buffer must be a contiguous block of memory that can be
2071directly read and/or written via C, consider using
2072[`napi_create_external_arraybuffer`][].
2073
2074JavaScript arrays are described in
2075[Section 22.1][] of the ECMAScript Language Specification.
2076
2077#### napi_create_arraybuffer
2078<!-- YAML
2079added: v8.0.0
2080napiVersion: 1
2081-->
2082
2083```c
2084napi_status napi_create_arraybuffer(napi_env env,
2085                                    size_t byte_length,
2086                                    void** data,
2087                                    napi_value* result)
2088```
2089
2090* `[in] env`: The environment that the API is invoked under.
2091* `[in] length`: The length in bytes of the array buffer to create.
2092* `[out] data`: Pointer to the underlying byte buffer of the `ArrayBuffer`.
2093* `[out] result`: A `napi_value` representing a JavaScript `ArrayBuffer`.
2094
2095Returns `napi_ok` if the API succeeded.
2096
2097This API returns a Node-API value corresponding to a JavaScript `ArrayBuffer`.
2098`ArrayBuffer`s are used to represent fixed-length binary data buffers. They are
2099normally used as a backing-buffer for `TypedArray` objects.
2100The `ArrayBuffer` allocated will have an underlying byte buffer whose size is
2101determined by the `length` parameter that's passed in.
2102The underlying buffer is optionally returned back to the caller in case the
2103caller wants to directly manipulate the buffer. This buffer can only be
2104written to directly from native code. To write to this buffer from JavaScript,
2105a typed array or `DataView` object would need to be created.
2106
2107JavaScript `ArrayBuffer` objects are described in
2108[Section 24.1][] of the ECMAScript Language Specification.
2109
2110#### napi_create_buffer
2111<!-- YAML
2112added: v8.0.0
2113napiVersion: 1
2114-->
2115
2116```c
2117napi_status napi_create_buffer(napi_env env,
2118                               size_t size,
2119                               void** data,
2120                               napi_value* result)
2121```
2122
2123* `[in] env`: The environment that the API is invoked under.
2124* `[in] size`: Size in bytes of the underlying buffer.
2125* `[out] data`: Raw pointer to the underlying buffer.
2126* `[out] result`: A `napi_value` representing a `node::Buffer`.
2127
2128Returns `napi_ok` if the API succeeded.
2129
2130This API allocates a `node::Buffer` object. While this is still a
2131fully-supported data structure, in most cases using a `TypedArray` will suffice.
2132
2133#### napi_create_buffer_copy
2134<!-- YAML
2135added: v8.0.0
2136napiVersion: 1
2137-->
2138
2139```c
2140napi_status napi_create_buffer_copy(napi_env env,
2141                                    size_t length,
2142                                    const void* data,
2143                                    void** result_data,
2144                                    napi_value* result)
2145```
2146
2147* `[in] env`: The environment that the API is invoked under.
2148* `[in] size`: Size in bytes of the input buffer (should be the same as the size
2149  of the new buffer).
2150* `[in] data`: Raw pointer to the underlying buffer to copy from.
2151* `[out] result_data`: Pointer to the new `Buffer`'s underlying data buffer.
2152* `[out] result`: A `napi_value` representing a `node::Buffer`.
2153
2154Returns `napi_ok` if the API succeeded.
2155
2156This API allocates a `node::Buffer` object and initializes it with data copied
2157from the passed-in buffer. While this is still a fully-supported data
2158structure, in most cases using a `TypedArray` will suffice.
2159
2160#### napi_create_date
2161<!-- YAML
2162added:
2163 - v11.11.0
2164 - v10.17.0
2165napiVersion: 5
2166-->
2167
2168```c
2169napi_status napi_create_date(napi_env env,
2170                             double time,
2171                             napi_value* result);
2172```
2173
2174* `[in] env`: The environment that the API is invoked under.
2175* `[in] time`: ECMAScript time value in milliseconds since 01 January, 1970 UTC.
2176* `[out] result`: A `napi_value` representing a JavaScript `Date`.
2177
2178Returns `napi_ok` if the API succeeded.
2179
2180This API does not observe leap seconds; they are ignored, as
2181ECMAScript aligns with POSIX time specification.
2182
2183This API allocates a JavaScript `Date` object.
2184
2185JavaScript `Date` objects are described in
2186[Section 20.3][] of the ECMAScript Language Specification.
2187
2188#### napi_create_external
2189<!-- YAML
2190added: v8.0.0
2191napiVersion: 1
2192-->
2193
2194```c
2195napi_status napi_create_external(napi_env env,
2196                                 void* data,
2197                                 napi_finalize finalize_cb,
2198                                 void* finalize_hint,
2199                                 napi_value* result)
2200```
2201
2202* `[in] env`: The environment that the API is invoked under.
2203* `[in] data`: Raw pointer to the external data.
2204* `[in] finalize_cb`: Optional callback to call when the external value is being
2205  collected. [`napi_finalize`][] provides more details.
2206* `[in] finalize_hint`: Optional hint to pass to the finalize callback during
2207  collection.
2208* `[out] result`: A `napi_value` representing an external value.
2209
2210Returns `napi_ok` if the API succeeded.
2211
2212This API allocates a JavaScript value with external data attached to it. This
2213is used to pass external data through JavaScript code, so it can be retrieved
2214later by native code using [`napi_get_value_external`][].
2215
2216The API adds a `napi_finalize` callback which will be called when the JavaScript
2217object just created is ready for garbage collection. It is similar to
2218`napi_wrap()` except that:
2219
2220* the native data cannot be retrieved later using `napi_unwrap()`,
2221* nor can it be removed later using `napi_remove_wrap()`, and
2222* the object created by the API can be used with `napi_wrap()`.
2223
2224The created value is not an object, and therefore does not support additional
2225properties. It is considered a distinct value type: calling `napi_typeof()` with
2226an external value yields `napi_external`.
2227
2228#### napi_create_external_arraybuffer
2229<!-- YAML
2230added: v8.0.0
2231napiVersion: 1
2232-->
2233
2234```c
2235napi_status
2236napi_create_external_arraybuffer(napi_env env,
2237                                 void* external_data,
2238                                 size_t byte_length,
2239                                 napi_finalize finalize_cb,
2240                                 void* finalize_hint,
2241                                 napi_value* result)
2242```
2243
2244* `[in] env`: The environment that the API is invoked under.
2245* `[in] external_data`: Pointer to the underlying byte buffer of the
2246  `ArrayBuffer`.
2247* `[in] byte_length`: The length in bytes of the underlying buffer.
2248* `[in] finalize_cb`: Optional callback to call when the `ArrayBuffer` is being
2249  collected. [`napi_finalize`][] provides more details.
2250* `[in] finalize_hint`: Optional hint to pass to the finalize callback during
2251  collection.
2252* `[out] result`: A `napi_value` representing a JavaScript `ArrayBuffer`.
2253
2254Returns `napi_ok` if the API succeeded.
2255
2256**Some runtimes other than Node.js have dropped support for external buffers**.
2257On runtimes other than Node.js this method may return
2258`napi_no_external_buffers_allowed` to indicate that external
2259buffers are not supported. One such runtime is Electron as
2260described in this issue
2261[electron/issues/35801](https://github.com/electron/electron/issues/35801).
2262
2263In order to maintain broadest compatibility with all runtimes
2264you may define `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` in your addon before
2265includes for the node-api headers. Doing so will hide the 2 functions
2266that create external buffers. This will ensure a compilation error
2267occurs if you accidentally use one of these methods.
2268
2269This API returns a Node-API value corresponding to a JavaScript `ArrayBuffer`.
2270The underlying byte buffer of the `ArrayBuffer` is externally allocated and
2271managed. The caller must ensure that the byte buffer remains valid until the
2272finalize callback is called.
2273
2274The API adds a `napi_finalize` callback which will be called when the JavaScript
2275object just created is ready for garbage collection. It is similar to
2276`napi_wrap()` except that:
2277
2278* the native data cannot be retrieved later using `napi_unwrap()`,
2279* nor can it be removed later using `napi_remove_wrap()`, and
2280* the object created by the API can be used with `napi_wrap()`.
2281
2282JavaScript `ArrayBuffer`s are described in
2283[Section 24.1][] of the ECMAScript Language Specification.
2284
2285#### napi_create_external_buffer
2286<!-- YAML
2287added: v8.0.0
2288napiVersion: 1
2289-->
2290
2291```c
2292napi_status napi_create_external_buffer(napi_env env,
2293                                        size_t length,
2294                                        void* data,
2295                                        napi_finalize finalize_cb,
2296                                        void* finalize_hint,
2297                                        napi_value* result)
2298```
2299
2300* `[in] env`: The environment that the API is invoked under.
2301* `[in] length`: Size in bytes of the input buffer (should be the same as the
2302  size of the new buffer).
2303* `[in] data`: Raw pointer to the underlying buffer to expose to JavaScript.
2304* `[in] finalize_cb`: Optional callback to call when the `ArrayBuffer` is being
2305  collected. [`napi_finalize`][] provides more details.
2306* `[in] finalize_hint`: Optional hint to pass to the finalize callback during
2307  collection.
2308* `[out] result`: A `napi_value` representing a `node::Buffer`.
2309
2310Returns `napi_ok` if the API succeeded.
2311
2312**Some runtimes other than Node.js have dropped support for external buffers**.
2313On runtimes other than Node.js this method may return
2314`napi_no_external_buffers_allowed` to indicate that external
2315buffers are not supported. One such runtime is Electron as
2316described in this issue
2317[electron/issues/35801](https://github.com/electron/electron/issues/35801).
2318
2319In order to maintain broadest compatibility with all runtimes
2320you may define `NODE_API_NO_EXTERNAL_BUFFERS_ALLOWED` in your addon before
2321includes for the node-api headers. Doing so will hide the 2 functions
2322that create external buffers. This will ensure a compilation error
2323occurs if you accidentally use one of these methods.
2324
2325This API allocates a `node::Buffer` object and initializes it with data
2326backed by the passed in buffer. While this is still a fully-supported data
2327structure, in most cases using a `TypedArray` will suffice.
2328
2329The API adds a `napi_finalize` callback which will be called when the JavaScript
2330object just created is ready for garbage collection. It is similar to
2331`napi_wrap()` except that:
2332
2333* the native data cannot be retrieved later using `napi_unwrap()`,
2334* nor can it be removed later using `napi_remove_wrap()`, and
2335* the object created by the API can be used with `napi_wrap()`.
2336
2337For Node.js >=4 `Buffers` are `Uint8Array`s.
2338
2339#### napi_create_object
2340<!-- YAML
2341added: v8.0.0
2342napiVersion: 1
2343-->
2344
2345```c
2346napi_status napi_create_object(napi_env env, napi_value* result)
2347```
2348
2349* `[in] env`: The environment that the API is invoked under.
2350* `[out] result`: A `napi_value` representing a JavaScript `Object`.
2351
2352Returns `napi_ok` if the API succeeded.
2353
2354This API allocates a default JavaScript `Object`.
2355It is the equivalent of doing `new Object()` in JavaScript.
2356
2357The JavaScript `Object` type is described in [Section 6.1.7][] of the
2358ECMAScript Language Specification.
2359
2360#### napi_create_symbol
2361<!-- YAML
2362added: v8.0.0
2363napiVersion: 1
2364-->
2365
2366```c
2367napi_status napi_create_symbol(napi_env env,
2368                               napi_value description,
2369                               napi_value* result)
2370```
2371
2372* `[in] env`: The environment that the API is invoked under.
2373* `[in] description`: Optional `napi_value` which refers to a JavaScript
2374  `string` to be set as the description for the symbol.
2375* `[out] result`: A `napi_value` representing a JavaScript `symbol`.
2376
2377Returns `napi_ok` if the API succeeded.
2378
2379This API creates a JavaScript `symbol` value from a UTF8-encoded C string.
2380
2381The JavaScript `symbol` type is described in [Section 19.4][]
2382of the ECMAScript Language Specification.
2383
2384#### napi_create_typedarray
2385<!-- YAML
2386added: v8.0.0
2387napiVersion: 1
2388-->
2389
2390```c
2391napi_status napi_create_typedarray(napi_env env,
2392                                   napi_typedarray_type type,
2393                                   size_t length,
2394                                   napi_value arraybuffer,
2395                                   size_t byte_offset,
2396                                   napi_value* result)
2397```
2398
2399* `[in] env`: The environment that the API is invoked under.
2400* `[in] type`: Scalar datatype of the elements within the `TypedArray`.
2401* `[in] length`: Number of elements in the `TypedArray`.
2402* `[in] arraybuffer`: `ArrayBuffer` underlying the typed array.
2403* `[in] byte_offset`: The byte offset within the `ArrayBuffer` from which to
2404  start projecting the `TypedArray`.
2405* `[out] result`: A `napi_value` representing a JavaScript `TypedArray`.
2406
2407Returns `napi_ok` if the API succeeded.
2408
2409This API creates a JavaScript `TypedArray` object over an existing
2410`ArrayBuffer`. `TypedArray` objects provide an array-like view over an
2411underlying data buffer where each element has the same underlying binary scalar
2412datatype.
2413
2414It's required that `(length * size_of_element) + byte_offset` should
2415be <= the size in bytes of the array passed in. If not, a `RangeError` exception
2416is raised.
2417
2418JavaScript `TypedArray` objects are described in
2419[Section 22.2][] of the ECMAScript Language Specification.
2420
2421#### napi_create_dataview
2422<!-- YAML
2423added: v8.3.0
2424napiVersion: 1
2425-->
2426
2427```c
2428napi_status napi_create_dataview(napi_env env,
2429                                 size_t byte_length,
2430                                 napi_value arraybuffer,
2431                                 size_t byte_offset,
2432                                 napi_value* result)
2433```
2434
2435* `[in] env`: The environment that the API is invoked under.
2436* `[in] length`: Number of elements in the `DataView`.
2437* `[in] arraybuffer`: `ArrayBuffer` underlying the `DataView`.
2438* `[in] byte_offset`: The byte offset within the `ArrayBuffer` from which to
2439  start projecting the `DataView`.
2440* `[out] result`: A `napi_value` representing a JavaScript `DataView`.
2441
2442Returns `napi_ok` if the API succeeded.
2443
2444This API creates a JavaScript `DataView` object over an existing `ArrayBuffer`.
2445`DataView` objects provide an array-like view over an underlying data buffer,
2446but one which allows items of different size and type in the `ArrayBuffer`.
2447
2448It is required that `byte_length + byte_offset` is less than or equal to the
2449size in bytes of the array passed in. If not, a `RangeError` exception is
2450raised.
2451
2452JavaScript `DataView` objects are described in
2453[Section 24.3][] of the ECMAScript Language Specification.
2454
2455### Functions to convert from C types to Node-API
2456#### napi_create_int32
2457<!-- YAML
2458added: v8.4.0
2459napiVersion: 1
2460-->
2461
2462```c
2463napi_status napi_create_int32(napi_env env, int32_t value, napi_value* result)
2464```
2465
2466* `[in] env`: The environment that the API is invoked under.
2467* `[in] value`: Integer value to be represented in JavaScript.
2468* `[out] result`: A `napi_value` representing a JavaScript `number`.
2469
2470Returns `napi_ok` if the API succeeded.
2471
2472This API is used to convert from the C `int32_t` type to the JavaScript
2473`number` type.
2474
2475The JavaScript `number` type is described in
2476[Section 6.1.6][] of the ECMAScript Language Specification.
2477
2478#### napi_create_uint32
2479<!-- YAML
2480added: v8.4.0
2481napiVersion: 1
2482-->
2483
2484```c
2485napi_status napi_create_uint32(napi_env env, uint32_t value, napi_value* result)
2486```
2487
2488* `[in] env`: The environment that the API is invoked under.
2489* `[in] value`: Unsigned integer value to be represented in JavaScript.
2490* `[out] result`: A `napi_value` representing a JavaScript `number`.
2491
2492Returns `napi_ok` if the API succeeded.
2493
2494This API is used to convert from the C `uint32_t` type to the JavaScript
2495`number` type.
2496
2497The JavaScript `number` type is described in
2498[Section 6.1.6][] of the ECMAScript Language Specification.
2499
2500#### napi_create_int64
2501<!-- YAML
2502added: v8.4.0
2503napiVersion: 1
2504-->
2505
2506```c
2507napi_status napi_create_int64(napi_env env, int64_t value, napi_value* result)
2508```
2509
2510* `[in] env`: The environment that the API is invoked under.
2511* `[in] value`: Integer value to be represented in JavaScript.
2512* `[out] result`: A `napi_value` representing a JavaScript `number`.
2513
2514Returns `napi_ok` if the API succeeded.
2515
2516This API is used to convert from the C `int64_t` type to the JavaScript
2517`number` type.
2518
2519The JavaScript `number` type is described in [Section 6.1.6][]
2520of the ECMAScript Language Specification. Note the complete range of `int64_t`
2521cannot be represented with full precision in JavaScript. Integer values
2522outside the range of [`Number.MIN_SAFE_INTEGER`][] `-(2**53 - 1)` -
2523[`Number.MAX_SAFE_INTEGER`][] `(2**53 - 1)` will lose precision.
2524
2525#### napi_create_double
2526<!-- YAML
2527added: v8.4.0
2528napiVersion: 1
2529-->
2530
2531```c
2532napi_status napi_create_double(napi_env env, double value, napi_value* result)
2533```
2534
2535* `[in] env`: The environment that the API is invoked under.
2536* `[in] value`: Double-precision value to be represented in JavaScript.
2537* `[out] result`: A `napi_value` representing a JavaScript `number`.
2538
2539Returns `napi_ok` if the API succeeded.
2540
2541This API is used to convert from the C `double` type to the JavaScript
2542`number` type.
2543
2544The JavaScript `number` type is described in
2545[Section 6.1.6][] of the ECMAScript Language Specification.
2546
2547#### napi_create_bigint_int64
2548<!-- YAML
2549added: v10.7.0
2550napiVersion: 6
2551-->
2552
2553```c
2554napi_status napi_create_bigint_int64(napi_env env,
2555                                     int64_t value,
2556                                     napi_value* result);
2557```
2558
2559* `[in] env`: The environment that the API is invoked under.
2560* `[in] value`: Integer value to be represented in JavaScript.
2561* `[out] result`: A `napi_value` representing a JavaScript `BigInt`.
2562
2563Returns `napi_ok` if the API succeeded.
2564
2565This API converts the C `int64_t` type to the JavaScript `BigInt` type.
2566
2567#### napi_create_bigint_uint64
2568<!-- YAML
2569added: v10.7.0
2570napiVersion: 6
2571-->
2572
2573```c
2574napi_status napi_create_bigint_uint64(napi_env env,
2575                                      uint64_t value,
2576                                      napi_value* result);
2577```
2578
2579* `[in] env`: The environment that the API is invoked under.
2580* `[in] value`: Unsigned integer value to be represented in JavaScript.
2581* `[out] result`: A `napi_value` representing a JavaScript `BigInt`.
2582
2583Returns `napi_ok` if the API succeeded.
2584
2585This API converts the C `uint64_t` type to the JavaScript `BigInt` type.
2586
2587#### napi_create_bigint_words
2588<!-- YAML
2589added: v10.7.0
2590napiVersion: 6
2591-->
2592
2593```c
2594napi_status napi_create_bigint_words(napi_env env,
2595                                     int sign_bit,
2596                                     size_t word_count,
2597                                     const uint64_t* words,
2598                                     napi_value* result);
2599```
2600
2601* `[in] env`: The environment that the API is invoked under.
2602* `[in] sign_bit`: Determines if the resulting `BigInt` will be positive or
2603  negative.
2604* `[in] word_count`: The length of the `words` array.
2605* `[in] words`: An array of `uint64_t` little-endian 64-bit words.
2606* `[out] result`: A `napi_value` representing a JavaScript `BigInt`.
2607
2608Returns `napi_ok` if the API succeeded.
2609
2610This API converts an array of unsigned 64-bit words into a single `BigInt`
2611value.
2612
2613The resulting `BigInt` is calculated as: (–1)<sup>`sign_bit`</sup> (`words[0]`
2614× (2<sup>64</sup>)<sup>0</sup> + `words[1]` × (2<sup>64</sup>)<sup>1</sup> + …)
2615
2616#### napi_create_string_latin1
2617<!-- YAML
2618added: v8.0.0
2619napiVersion: 1
2620-->
2621
2622```c
2623napi_status napi_create_string_latin1(napi_env env,
2624                                      const char* str,
2625                                      size_t length,
2626                                      napi_value* result);
2627```
2628
2629* `[in] env`: The environment that the API is invoked under.
2630* `[in] str`: Character buffer representing an ISO-8859-1-encoded string.
2631* `[in] length`: The length of the string in bytes, or `NAPI_AUTO_LENGTH` if it
2632  is null-terminated.
2633* `[out] result`: A `napi_value` representing a JavaScript `string`.
2634
2635Returns `napi_ok` if the API succeeded.
2636
2637This API creates a JavaScript `string` value from an ISO-8859-1-encoded C
2638string. The native string is copied.
2639
2640The JavaScript `string` type is described in
2641[Section 6.1.4][] of the ECMAScript Language Specification.
2642
2643#### napi_create_string_utf16
2644<!-- YAML
2645added: v8.0.0
2646napiVersion: 1
2647-->
2648
2649```c
2650napi_status napi_create_string_utf16(napi_env env,
2651                                     const char16_t* str,
2652                                     size_t length,
2653                                     napi_value* result)
2654```
2655
2656* `[in] env`: The environment that the API is invoked under.
2657* `[in] str`: Character buffer representing a UTF16-LE-encoded string.
2658* `[in] length`: The length of the string in two-byte code units, or
2659  `NAPI_AUTO_LENGTH` if it is null-terminated.
2660* `[out] result`: A `napi_value` representing a JavaScript `string`.
2661
2662Returns `napi_ok` if the API succeeded.
2663
2664This API creates a JavaScript `string` value from a UTF16-LE-encoded C string.
2665The native string is copied.
2666
2667The JavaScript `string` type is described in
2668[Section 6.1.4][] of the ECMAScript Language Specification.
2669
2670#### napi_create_string_utf8
2671<!-- YAML
2672added: v8.0.0
2673napiVersion: 1
2674-->
2675
2676```c
2677napi_status napi_create_string_utf8(napi_env env,
2678                                    const char* str,
2679                                    size_t length,
2680                                    napi_value* result)
2681```
2682
2683* `[in] env`: The environment that the API is invoked under.
2684* `[in] str`: Character buffer representing a UTF8-encoded string.
2685* `[in] length`: The length of the string in bytes, or `NAPI_AUTO_LENGTH` if it
2686  is null-terminated.
2687* `[out] result`: A `napi_value` representing a JavaScript `string`.
2688
2689Returns `napi_ok` if the API succeeded.
2690
2691This API creates a JavaScript `string` value from a UTF8-encoded C string.
2692The native string is copied.
2693
2694The JavaScript `string` type is described in
2695[Section 6.1.4][] of the ECMAScript Language Specification.
2696
2697### Functions to convert from Node-API to C types
2698#### napi_get_array_length
2699<!-- YAML
2700added: v8.0.0
2701napiVersion: 1
2702-->
2703
2704```c
2705napi_status napi_get_array_length(napi_env env,
2706                                  napi_value value,
2707                                  uint32_t* result)
2708```
2709
2710* `[in] env`: The environment that the API is invoked under.
2711* `[in] value`: `napi_value` representing the JavaScript `Array` whose length is
2712  being queried.
2713* `[out] result`: `uint32` representing length of the array.
2714
2715Returns `napi_ok` if the API succeeded.
2716
2717This API returns the length of an array.
2718
2719`Array` length is described in [Section 22.1.4.1][] of the ECMAScript Language
2720Specification.
2721
2722#### napi_get_arraybuffer_info
2723<!-- YAML
2724added: v8.0.0
2725napiVersion: 1
2726-->
2727
2728```c
2729napi_status napi_get_arraybuffer_info(napi_env env,
2730                                      napi_value arraybuffer,
2731                                      void** data,
2732                                      size_t* byte_length)
2733```
2734
2735* `[in] env`: The environment that the API is invoked under.
2736* `[in] arraybuffer`: `napi_value` representing the `ArrayBuffer` being queried.
2737* `[out] data`: The underlying data buffer of the `ArrayBuffer`. If byte_length
2738  is `0`, this may be `NULL` or any other pointer value.
2739* `[out] byte_length`: Length in bytes of the underlying data buffer.
2740
2741Returns `napi_ok` if the API succeeded.
2742
2743This API is used to retrieve the underlying data buffer of an `ArrayBuffer` and
2744its length.
2745
2746*WARNING*: Use caution while using this API. The lifetime of the underlying data
2747buffer is managed by the `ArrayBuffer` even after it's returned. A
2748possible safe way to use this API is in conjunction with
2749[`napi_create_reference`][], which can be used to guarantee control over the
2750lifetime of the `ArrayBuffer`. It's also safe to use the returned data buffer
2751within the same callback as long as there are no calls to other APIs that might
2752trigger a GC.
2753
2754#### napi_get_buffer_info
2755<!-- YAML
2756added: v8.0.0
2757napiVersion: 1
2758-->
2759
2760```c
2761napi_status napi_get_buffer_info(napi_env env,
2762                                 napi_value value,
2763                                 void** data,
2764                                 size_t* length)
2765```
2766
2767* `[in] env`: The environment that the API is invoked under.
2768* `[in] value`: `napi_value` representing the `node::Buffer` being queried.
2769* `[out] data`: The underlying data buffer of the `node::Buffer`.
2770  If length is `0`, this may be `NULL` or any other pointer value.
2771* `[out] length`: Length in bytes of the underlying data buffer.
2772
2773Returns `napi_ok` if the API succeeded.
2774
2775This API is used to retrieve the underlying data buffer of a `node::Buffer`
2776and it's length.
2777
2778*Warning*: Use caution while using this API since the underlying data buffer's
2779lifetime is not guaranteed if it's managed by the VM.
2780
2781#### napi_get_prototype
2782<!-- YAML
2783added: v8.0.0
2784napiVersion: 1
2785-->
2786
2787```c
2788napi_status napi_get_prototype(napi_env env,
2789                               napi_value object,
2790                               napi_value* result)
2791```
2792
2793* `[in] env`: The environment that the API is invoked under.
2794* `[in] object`: `napi_value` representing JavaScript `Object` whose prototype
2795  to return. This returns the equivalent of `Object.getPrototypeOf` (which is
2796  not the same as the function's `prototype` property).
2797* `[out] result`: `napi_value` representing prototype of the given object.
2798
2799Returns `napi_ok` if the API succeeded.
2800
2801#### napi_get_typedarray_info
2802<!-- YAML
2803added: v8.0.0
2804napiVersion: 1
2805-->
2806
2807```c
2808napi_status napi_get_typedarray_info(napi_env env,
2809                                     napi_value typedarray,
2810                                     napi_typedarray_type* type,
2811                                     size_t* length,
2812                                     void** data,
2813                                     napi_value* arraybuffer,
2814                                     size_t* byte_offset)
2815```
2816
2817* `[in] env`: The environment that the API is invoked under.
2818* `[in] typedarray`: `napi_value` representing the `TypedArray` whose
2819  properties to query.
2820* `[out] type`: Scalar datatype of the elements within the `TypedArray`.
2821* `[out] length`: The number of elements in the `TypedArray`.
2822* `[out] data`: The data buffer underlying the `TypedArray` adjusted by
2823  the `byte_offset` value so that it points to the first element in the
2824  `TypedArray`. If the length of the array is `0`, this may be `NULL` or
2825  any other pointer value.
2826* `[out] arraybuffer`: The `ArrayBuffer` underlying the `TypedArray`.
2827* `[out] byte_offset`: The byte offset within the underlying native array
2828  at which the first element of the arrays is located. The value for the data
2829  parameter has already been adjusted so that data points to the first element
2830  in the array. Therefore, the first byte of the native array would be at
2831  `data - byte_offset`.
2832
2833Returns `napi_ok` if the API succeeded.
2834
2835This API returns various properties of a typed array.
2836
2837*Warning*: Use caution while using this API since the underlying data buffer
2838is managed by the VM.
2839
2840#### napi_get_dataview_info
2841<!-- YAML
2842added: v8.3.0
2843napiVersion: 1
2844-->
2845
2846```c
2847napi_status napi_get_dataview_info(napi_env env,
2848                                   napi_value dataview,
2849                                   size_t* byte_length,
2850                                   void** data,
2851                                   napi_value* arraybuffer,
2852                                   size_t* byte_offset)
2853```
2854
2855* `[in] env`: The environment that the API is invoked under.
2856* `[in] dataview`: `napi_value` representing the `DataView` whose
2857  properties to query.
2858* `[out] byte_length`: Number of bytes in the `DataView`.
2859* `[out] data`: The data buffer underlying the `DataView`.
2860  If byte_length is `0`, this may be `NULL` or any other pointer value.
2861* `[out] arraybuffer`: `ArrayBuffer` underlying the `DataView`.
2862* `[out] byte_offset`: The byte offset within the data buffer from which
2863  to start projecting the `DataView`.
2864
2865Returns `napi_ok` if the API succeeded.
2866
2867This API returns various properties of a `DataView`.
2868
2869#### napi_get_date_value
2870<!-- YAML
2871added:
2872 - v11.11.0
2873 - v10.17.0
2874napiVersion: 5
2875-->
2876
2877```c
2878napi_status napi_get_date_value(napi_env env,
2879                                napi_value value,
2880                                double* result)
2881```
2882
2883* `[in] env`: The environment that the API is invoked under.
2884* `[in] value`: `napi_value` representing a JavaScript `Date`.
2885* `[out] result`: Time value as a `double` represented as milliseconds since
2886  midnight at the beginning of 01 January, 1970 UTC.
2887
2888This API does not observe leap seconds; they are ignored, as
2889ECMAScript aligns with POSIX time specification.
2890
2891Returns `napi_ok` if the API succeeded. If a non-date `napi_value` is passed
2892in it returns `napi_date_expected`.
2893
2894This API returns the C double primitive of time value for the given JavaScript
2895`Date`.
2896
2897#### napi_get_value_bool
2898<!-- YAML
2899added: v8.0.0
2900napiVersion: 1
2901-->
2902
2903```c
2904napi_status napi_get_value_bool(napi_env env, napi_value value, bool* result)
2905```
2906
2907* `[in] env`: The environment that the API is invoked under.
2908* `[in] value`: `napi_value` representing JavaScript `Boolean`.
2909* `[out] result`: C boolean primitive equivalent of the given JavaScript
2910  `Boolean`.
2911
2912Returns `napi_ok` if the API succeeded. If a non-boolean `napi_value` is
2913passed in it returns `napi_boolean_expected`.
2914
2915This API returns the C boolean primitive equivalent of the given JavaScript
2916`Boolean`.
2917
2918#### napi_get_value_double
2919<!-- YAML
2920added: v8.0.0
2921napiVersion: 1
2922-->
2923
2924```c
2925napi_status napi_get_value_double(napi_env env,
2926                                  napi_value value,
2927                                  double* result)
2928```
2929
2930* `[in] env`: The environment that the API is invoked under.
2931* `[in] value`: `napi_value` representing JavaScript `number`.
2932* `[out] result`: C double primitive equivalent of the given JavaScript
2933  `number`.
2934
2935Returns `napi_ok` if the API succeeded. If a non-number `napi_value` is passed
2936in it returns `napi_number_expected`.
2937
2938This API returns the C double primitive equivalent of the given JavaScript
2939`number`.
2940
2941#### napi_get_value_bigint_int64
2942<!-- YAML
2943added: v10.7.0
2944napiVersion: 6
2945-->
2946
2947```c
2948napi_status napi_get_value_bigint_int64(napi_env env,
2949                                        napi_value value,
2950                                        int64_t* result,
2951                                        bool* lossless);
2952```
2953
2954* `[in] env`: The environment that the API is invoked under
2955* `[in] value`: `napi_value` representing JavaScript `BigInt`.
2956* `[out] result`: C `int64_t` primitive equivalent of the given JavaScript
2957  `BigInt`.
2958* `[out] lossless`: Indicates whether the `BigInt` value was converted
2959  losslessly.
2960
2961Returns `napi_ok` if the API succeeded. If a non-`BigInt` is passed in it
2962returns `napi_bigint_expected`.
2963
2964This API returns the C `int64_t` primitive equivalent of the given JavaScript
2965`BigInt`. If needed it will truncate the value, setting `lossless` to `false`.
2966
2967#### napi_get_value_bigint_uint64
2968<!-- YAML
2969added: v10.7.0
2970napiVersion: 6
2971-->
2972
2973```c
2974napi_status napi_get_value_bigint_uint64(napi_env env,
2975                                        napi_value value,
2976                                        uint64_t* result,
2977                                        bool* lossless);
2978```
2979
2980* `[in] env`: The environment that the API is invoked under.
2981* `[in] value`: `napi_value` representing JavaScript `BigInt`.
2982* `[out] result`: C `uint64_t` primitive equivalent of the given JavaScript
2983  `BigInt`.
2984* `[out] lossless`: Indicates whether the `BigInt` value was converted
2985  losslessly.
2986
2987Returns `napi_ok` if the API succeeded. If a non-`BigInt` is passed in it
2988returns `napi_bigint_expected`.
2989
2990This API returns the C `uint64_t` primitive equivalent of the given JavaScript
2991`BigInt`. If needed it will truncate the value, setting `lossless` to `false`.
2992
2993#### napi_get_value_bigint_words
2994<!-- YAML
2995added: v10.7.0
2996napiVersion: 6
2997-->
2998
2999```c
3000napi_status napi_get_value_bigint_words(napi_env env,
3001                                        napi_value value,
3002                                        int* sign_bit,
3003                                        size_t* word_count,
3004                                        uint64_t* words);
3005```
3006
3007* `[in] env`: The environment that the API is invoked under.
3008* `[in] value`: `napi_value` representing JavaScript `BigInt`.
3009* `[out] sign_bit`: Integer representing if the JavaScript `BigInt` is positive
3010   or negative.
3011* `[in/out] word_count`: Must be initialized to the length of the `words`
3012   array. Upon return, it will be set to the actual number of words that
3013   would be needed to store this `BigInt`.
3014* `[out] words`: Pointer to a pre-allocated 64-bit word array.
3015
3016Returns `napi_ok` if the API succeeded.
3017
3018This API converts a single `BigInt` value into a sign bit, 64-bit little-endian
3019array, and the number of elements in the array. `sign_bit` and `words` may be
3020both set to `NULL`, in order to get only `word_count`.
3021
3022#### napi_get_value_external
3023<!-- YAML
3024added: v8.0.0
3025napiVersion: 1
3026-->
3027
3028```c
3029napi_status napi_get_value_external(napi_env env,
3030                                    napi_value value,
3031                                    void** result)
3032```
3033
3034* `[in] env`: The environment that the API is invoked under.
3035* `[in] value`: `napi_value` representing JavaScript external value.
3036* `[out] result`: Pointer to the data wrapped by the JavaScript external value.
3037
3038Returns `napi_ok` if the API succeeded. If a non-external `napi_value` is
3039passed in it returns `napi_invalid_arg`.
3040
3041This API retrieves the external data pointer that was previously passed to
3042`napi_create_external()`.
3043
3044#### napi_get_value_int32
3045<!-- YAML
3046added: v8.0.0
3047napiVersion: 1
3048-->
3049
3050```c
3051napi_status napi_get_value_int32(napi_env env,
3052                                 napi_value value,
3053                                 int32_t* result)
3054```
3055
3056* `[in] env`: The environment that the API is invoked under.
3057* `[in] value`: `napi_value` representing JavaScript `number`.
3058* `[out] result`: C `int32` primitive equivalent of the given JavaScript
3059  `number`.
3060
3061Returns `napi_ok` if the API succeeded. If a non-number `napi_value`
3062is passed in `napi_number_expected`.
3063
3064This API returns the C `int32` primitive equivalent
3065of the given JavaScript `number`.
3066
3067If the number exceeds the range of the 32 bit integer, then the result is
3068truncated to the equivalent of the bottom 32 bits. This can result in a large
3069positive number becoming a negative number if the value is > 2<sup>31</sup> - 1.
3070
3071Non-finite number values (`NaN`, `+Infinity`, or `-Infinity`) set the
3072result to zero.
3073
3074#### napi_get_value_int64
3075<!-- YAML
3076added: v8.0.0
3077napiVersion: 1
3078-->
3079
3080```c
3081napi_status napi_get_value_int64(napi_env env,
3082                                 napi_value value,
3083                                 int64_t* result)
3084```
3085
3086* `[in] env`: The environment that the API is invoked under.
3087* `[in] value`: `napi_value` representing JavaScript `number`.
3088* `[out] result`: C `int64` primitive equivalent of the given JavaScript
3089  `number`.
3090
3091Returns `napi_ok` if the API succeeded. If a non-number `napi_value`
3092is passed in it returns `napi_number_expected`.
3093
3094This API returns the C `int64` primitive equivalent of the given JavaScript
3095`number`.
3096
3097`number` values outside the range of [`Number.MIN_SAFE_INTEGER`][]
3098`-(2**53 - 1)` - [`Number.MAX_SAFE_INTEGER`][] `(2**53 - 1)` will lose
3099precision.
3100
3101Non-finite number values (`NaN`, `+Infinity`, or `-Infinity`) set the
3102result to zero.
3103
3104#### napi_get_value_string_latin1
3105<!-- YAML
3106added: v8.0.0
3107napiVersion: 1
3108-->
3109
3110```c
3111napi_status napi_get_value_string_latin1(napi_env env,
3112                                         napi_value value,
3113                                         char* buf,
3114                                         size_t bufsize,
3115                                         size_t* result)
3116```
3117
3118* `[in] env`: The environment that the API is invoked under.
3119* `[in] value`: `napi_value` representing JavaScript string.
3120* `[in] buf`: Buffer to write the ISO-8859-1-encoded string into. If `NULL` is
3121  passed in, the length of the string in bytes and excluding the null terminator
3122  is returned in `result`.
3123* `[in] bufsize`: Size of the destination buffer. When this value is
3124  insufficient, the returned string is truncated and null-terminated.
3125* `[out] result`: Number of bytes copied into the buffer, excluding the null
3126  terminator.
3127
3128Returns `napi_ok` if the API succeeded. If a non-`string` `napi_value`
3129is passed in it returns `napi_string_expected`.
3130
3131This API returns the ISO-8859-1-encoded string corresponding the value passed
3132in.
3133
3134#### napi_get_value_string_utf8
3135<!-- YAML
3136added: v8.0.0
3137napiVersion: 1
3138-->
3139
3140```c
3141napi_status napi_get_value_string_utf8(napi_env env,
3142                                       napi_value value,
3143                                       char* buf,
3144                                       size_t bufsize,
3145                                       size_t* result)
3146```
3147
3148* `[in] env`: The environment that the API is invoked under.
3149* `[in] value`: `napi_value` representing JavaScript string.
3150* `[in] buf`: Buffer to write the UTF8-encoded string into. If `NULL` is passed
3151  in, the length of the string in bytes and excluding the null terminator is
3152  returned in `result`.
3153* `[in] bufsize`: Size of the destination buffer. When this value is
3154  insufficient, the returned string is truncated and null-terminated.
3155* `[out] result`: Number of bytes copied into the buffer, excluding the null
3156  terminator.
3157
3158Returns `napi_ok` if the API succeeded. If a non-`string` `napi_value`
3159is passed in it returns `napi_string_expected`.
3160
3161This API returns the UTF8-encoded string corresponding the value passed in.
3162
3163#### napi_get_value_string_utf16
3164<!-- YAML
3165added: v8.0.0
3166napiVersion: 1
3167-->
3168
3169```c
3170napi_status napi_get_value_string_utf16(napi_env env,
3171                                        napi_value value,
3172                                        char16_t* buf,
3173                                        size_t bufsize,
3174                                        size_t* result)
3175```
3176
3177* `[in] env`: The environment that the API is invoked under.
3178* `[in] value`: `napi_value` representing JavaScript string.
3179* `[in] buf`: Buffer to write the UTF16-LE-encoded string into. If `NULL` is
3180  passed in, the length of the string in 2-byte code units and excluding the
3181  null terminator is returned.
3182* `[in] bufsize`: Size of the destination buffer. When this value is
3183  insufficient, the returned string is truncated and null-terminated.
3184* `[out] result`: Number of 2-byte code units copied into the buffer, excluding
3185  the null terminator.
3186
3187Returns `napi_ok` if the API succeeded. If a non-`string` `napi_value`
3188is passed in it returns `napi_string_expected`.
3189
3190This API returns the UTF16-encoded string corresponding the value passed in.
3191
3192#### napi_get_value_uint32
3193<!-- YAML
3194added: v8.0.0
3195napiVersion: 1
3196-->
3197
3198```c
3199napi_status napi_get_value_uint32(napi_env env,
3200                                  napi_value value,
3201                                  uint32_t* result)
3202```
3203
3204* `[in] env`: The environment that the API is invoked under.
3205* `[in] value`: `napi_value` representing JavaScript `number`.
3206* `[out] result`: C primitive equivalent of the given `napi_value` as a
3207  `uint32_t`.
3208
3209Returns `napi_ok` if the API succeeded. If a non-number `napi_value`
3210is passed in it returns `napi_number_expected`.
3211
3212This API returns the C primitive equivalent of the given `napi_value` as a
3213`uint32_t`.
3214
3215### Functions to get global instances
3216#### napi_get_boolean
3217<!-- YAML
3218added: v8.0.0
3219napiVersion: 1
3220-->
3221
3222```c
3223napi_status napi_get_boolean(napi_env env, bool value, napi_value* result)
3224```
3225
3226* `[in] env`: The environment that the API is invoked under.
3227* `[in] value`: The value of the boolean to retrieve.
3228* `[out] result`: `napi_value` representing JavaScript `Boolean` singleton to
3229  retrieve.
3230
3231Returns `napi_ok` if the API succeeded.
3232
3233This API is used to return the JavaScript singleton object that is used to
3234represent the given boolean value.
3235
3236#### napi_get_global
3237<!-- YAML
3238added: v8.0.0
3239napiVersion: 1
3240-->
3241
3242```c
3243napi_status napi_get_global(napi_env env, napi_value* result)
3244```
3245
3246* `[in] env`: The environment that the API is invoked under.
3247* `[out] result`: `napi_value` representing JavaScript `global` object.
3248
3249Returns `napi_ok` if the API succeeded.
3250
3251This API returns the `global` object.
3252
3253#### napi_get_null
3254<!-- YAML
3255added: v8.0.0
3256napiVersion: 1
3257-->
3258
3259```c
3260napi_status napi_get_null(napi_env env, napi_value* result)
3261```
3262
3263* `[in] env`: The environment that the API is invoked under.
3264* `[out] result`: `napi_value` representing JavaScript `null` object.
3265
3266Returns `napi_ok` if the API succeeded.
3267
3268This API returns the `null` object.
3269
3270#### napi_get_undefined
3271<!-- YAML
3272added: v8.0.0
3273napiVersion: 1
3274-->
3275
3276```c
3277napi_status napi_get_undefined(napi_env env, napi_value* result)
3278```
3279
3280* `[in] env`: The environment that the API is invoked under.
3281* `[out] result`: `napi_value` representing JavaScript Undefined value.
3282
3283Returns `napi_ok` if the API succeeded.
3284
3285This API returns the Undefined object.
3286
3287## Working with JavaScript values and abstract operations
3288
3289Node-API exposes a set of APIs to perform some abstract operations on JavaScript
3290values. Some of these operations are documented under [Section 7][]
3291of the [ECMAScript Language Specification][].
3292
3293These APIs support doing one of the following:
3294
32951. Coerce JavaScript values to specific JavaScript types (such as `number` or
3296   `string`).
32972. Check the type of a JavaScript value.
32983. Check for equality between two JavaScript values.
3299
3300### napi_coerce_to_bool
3301<!-- YAML
3302added: v8.0.0
3303napiVersion: 1
3304-->
3305
3306```c
3307napi_status napi_coerce_to_bool(napi_env env,
3308                                napi_value value,
3309                                napi_value* result)
3310```
3311
3312* `[in] env`: The environment that the API is invoked under.
3313* `[in] value`: The JavaScript value to coerce.
3314* `[out] result`: `napi_value` representing the coerced JavaScript `Boolean`.
3315
3316Returns `napi_ok` if the API succeeded.
3317
3318This API implements the abstract operation `ToBoolean()` as defined in
3319[Section 7.1.2][] of the ECMAScript Language Specification.
3320This API can be re-entrant if getters are defined on the passed-in `Object`.
3321
3322### napi_coerce_to_number
3323<!-- YAML
3324added: v8.0.0
3325napiVersion: 1
3326-->
3327
3328```c
3329napi_status napi_coerce_to_number(napi_env env,
3330                                  napi_value value,
3331                                  napi_value* result)
3332```
3333
3334* `[in] env`: The environment that the API is invoked under.
3335* `[in] value`: The JavaScript value to coerce.
3336* `[out] result`: `napi_value` representing the coerced JavaScript `number`.
3337
3338Returns `napi_ok` if the API succeeded.
3339
3340This API implements the abstract operation `ToNumber()` as defined in
3341[Section 7.1.3][] of the ECMAScript Language Specification.
3342This API can be re-entrant if getters are defined on the passed-in `Object`.
3343
3344### napi_coerce_to_object
3345<!-- YAML
3346added: v8.0.0
3347napiVersion: 1
3348-->
3349
3350```c
3351napi_status napi_coerce_to_object(napi_env env,
3352                                  napi_value value,
3353                                  napi_value* result)
3354```
3355
3356* `[in] env`: The environment that the API is invoked under.
3357* `[in] value`: The JavaScript value to coerce.
3358* `[out] result`: `napi_value` representing the coerced JavaScript `Object`.
3359
3360Returns `napi_ok` if the API succeeded.
3361
3362This API implements the abstract operation `ToObject()` as defined in
3363[Section 7.1.13][] of the ECMAScript Language Specification.
3364This API can be re-entrant if getters are defined on the passed-in `Object`.
3365
3366### napi_coerce_to_string
3367<!-- YAML
3368added: v8.0.0
3369napiVersion: 1
3370-->
3371
3372```c
3373napi_status napi_coerce_to_string(napi_env env,
3374                                  napi_value value,
3375                                  napi_value* result)
3376```
3377
3378* `[in] env`: The environment that the API is invoked under.
3379* `[in] value`: The JavaScript value to coerce.
3380* `[out] result`: `napi_value` representing the coerced JavaScript `string`.
3381
3382Returns `napi_ok` if the API succeeded.
3383
3384This API implements the abstract operation `ToString()` as defined in
3385[Section 7.1.13][] of the ECMAScript Language Specification.
3386This API can be re-entrant if getters are defined on the passed-in `Object`.
3387
3388### napi_typeof
3389<!-- YAML
3390added: v8.0.0
3391napiVersion: 1
3392-->
3393
3394```c
3395napi_status napi_typeof(napi_env env, napi_value value, napi_valuetype* result)
3396```
3397
3398* `[in] env`: The environment that the API is invoked under.
3399* `[in] value`: The JavaScript value whose type to query.
3400* `[out] result`: The type of the JavaScript value.
3401
3402Returns `napi_ok` if the API succeeded.
3403
3404* `napi_invalid_arg` if the type of `value` is not a known ECMAScript type and
3405  `value` is not an External value.
3406
3407This API represents behavior similar to invoking the `typeof` Operator on
3408the object as defined in [Section 12.5.5][] of the ECMAScript Language
3409Specification. However, there are some differences:
3410
34111. It has support for detecting an External value.
34122. It detects `null` as a separate type, while ECMAScript `typeof` would detect
3413   `object`.
3414
3415If `value` has a type that is invalid, an error is returned.
3416
3417### napi_instanceof
3418<!-- YAML
3419added: v8.0.0
3420napiVersion: 1
3421-->
3422
3423```c
3424napi_status napi_instanceof(napi_env env,
3425                            napi_value object,
3426                            napi_value constructor,
3427                            bool* result)
3428```
3429
3430* `[in] env`: The environment that the API is invoked under.
3431* `[in] object`: The JavaScript value to check.
3432* `[in] constructor`: The JavaScript function object of the constructor function
3433  to check against.
3434* `[out] result`: Boolean that is set to true if `object instanceof constructor`
3435  is true.
3436
3437Returns `napi_ok` if the API succeeded.
3438
3439This API represents invoking the `instanceof` Operator on the object as
3440defined in [Section 12.10.4][] of the ECMAScript Language Specification.
3441
3442### napi_is_array
3443<!-- YAML
3444added: v8.0.0
3445napiVersion: 1
3446-->
3447
3448```c
3449napi_status napi_is_array(napi_env env, napi_value value, bool* result)
3450```
3451
3452* `[in] env`: The environment that the API is invoked under.
3453* `[in] value`: The JavaScript value to check.
3454* `[out] result`: Whether the given object is an array.
3455
3456Returns `napi_ok` if the API succeeded.
3457
3458This API represents invoking the `IsArray` operation on the object
3459as defined in [Section 7.2.2][] of the ECMAScript Language Specification.
3460
3461### napi_is_arraybuffer
3462<!-- YAML
3463added: v8.0.0
3464napiVersion: 1
3465-->
3466
3467```c
3468napi_status napi_is_arraybuffer(napi_env env, napi_value value, bool* result)
3469```
3470
3471* `[in] env`: The environment that the API is invoked under.
3472* `[in] value`: The JavaScript value to check.
3473* `[out] result`: Whether the given object is an `ArrayBuffer`.
3474
3475Returns `napi_ok` if the API succeeded.
3476
3477This API checks if the `Object` passed in is an array buffer.
3478
3479### napi_is_buffer
3480<!-- YAML
3481added: v8.0.0
3482napiVersion: 1
3483-->
3484
3485```c
3486napi_status napi_is_buffer(napi_env env, napi_value value, bool* result)
3487```
3488
3489* `[in] env`: The environment that the API is invoked under.
3490* `[in] value`: The JavaScript value to check.
3491* `[out] result`: Whether the given `napi_value` represents a `node::Buffer`
3492  object.
3493
3494Returns `napi_ok` if the API succeeded.
3495
3496This API checks if the `Object` passed in is a buffer.
3497
3498### napi_is_date
3499<!-- YAML
3500added:
3501 - v11.11.0
3502 - v10.17.0
3503napiVersion: 5
3504-->
3505
3506```c
3507napi_status napi_is_date(napi_env env, napi_value value, bool* result)
3508```
3509
3510* `[in] env`: The environment that the API is invoked under.
3511* `[in] value`: The JavaScript value to check.
3512* `[out] result`: Whether the given `napi_value` represents a JavaScript `Date`
3513  object.
3514
3515Returns `napi_ok` if the API succeeded.
3516
3517This API checks if the `Object` passed in is a date.
3518
3519### napi_is_error
3520<!-- YAML
3521added: v8.0.0
3522napiVersion: 1
3523-->
3524
3525```c
3526napi_status napi_is_error(napi_env env, napi_value value, bool* result)
3527```
3528
3529* `[in] env`: The environment that the API is invoked under.
3530* `[in] value`: The JavaScript value to check.
3531* `[out] result`: Whether the given `napi_value` represents an `Error` object.
3532
3533Returns `napi_ok` if the API succeeded.
3534
3535This API checks if the `Object` passed in is an `Error`.
3536
3537### napi_is_typedarray
3538<!-- YAML
3539added: v8.0.0
3540napiVersion: 1
3541-->
3542
3543```c
3544napi_status napi_is_typedarray(napi_env env, napi_value value, bool* result)
3545```
3546
3547* `[in] env`: The environment that the API is invoked under.
3548* `[in] value`: The JavaScript value to check.
3549* `[out] result`: Whether the given `napi_value` represents a `TypedArray`.
3550
3551Returns `napi_ok` if the API succeeded.
3552
3553This API checks if the `Object` passed in is a typed array.
3554
3555### napi_is_dataview
3556<!-- YAML
3557added: v8.3.0
3558napiVersion: 1
3559-->
3560
3561```c
3562napi_status napi_is_dataview(napi_env env, napi_value value, bool* result)
3563```
3564
3565* `[in] env`: The environment that the API is invoked under.
3566* `[in] value`: The JavaScript value to check.
3567* `[out] result`: Whether the given `napi_value` represents a `DataView`.
3568
3569Returns `napi_ok` if the API succeeded.
3570
3571This API checks if the `Object` passed in is a `DataView`.
3572
3573### napi_strict_equals
3574<!-- YAML
3575added: v8.0.0
3576napiVersion: 1
3577-->
3578
3579```c
3580napi_status napi_strict_equals(napi_env env,
3581                               napi_value lhs,
3582                               napi_value rhs,
3583                               bool* result)
3584```
3585
3586* `[in] env`: The environment that the API is invoked under.
3587* `[in] lhs`: The JavaScript value to check.
3588* `[in] rhs`: The JavaScript value to check against.
3589* `[out] result`: Whether the two `napi_value` objects are equal.
3590
3591Returns `napi_ok` if the API succeeded.
3592
3593This API represents the invocation of the Strict Equality algorithm as
3594defined in [Section 7.2.14][] of the ECMAScript Language Specification.
3595
3596### napi_detach_arraybuffer
3597<!-- YAML
3598added:
3599 - v13.0.0
3600 - v12.16.0
3601 - v10.22.0
3602napiVersion: 7
3603-->
3604
3605```c
3606napi_status napi_detach_arraybuffer(napi_env env,
3607                                    napi_value arraybuffer)
3608```
3609
3610* `[in] env`: The environment that the API is invoked under.
3611* `[in] arraybuffer`: The JavaScript `ArrayBuffer` to be detached.
3612
3613Returns `napi_ok` if the API succeeded. If a non-detachable `ArrayBuffer` is
3614passed in it returns `napi_detachable_arraybuffer_expected`.
3615
3616Generally, an `ArrayBuffer` is non-detachable if it has been detached before.
3617The engine may impose additional conditions on whether an `ArrayBuffer` is
3618detachable. For example, V8 requires that the `ArrayBuffer` be external,
3619that is, created with [`napi_create_external_arraybuffer`][].
3620
3621This API represents the invocation of the `ArrayBuffer` detach operation as
3622defined in [Section 24.1.1.3][] of the ECMAScript Language Specification.
3623
3624### napi_is_detached_arraybuffer
3625<!-- YAML
3626added:
3627 - v13.3.0
3628 - v12.16.0
3629 - v10.22.0
3630napiVersion: 7
3631-->
3632
3633```c
3634napi_status napi_is_detached_arraybuffer(napi_env env,
3635                                         napi_value arraybuffer,
3636                                         bool* result)
3637```
3638
3639* `[in] env`: The environment that the API is invoked under.
3640* `[in] arraybuffer`: The JavaScript `ArrayBuffer` to be checked.
3641* `[out] result`: Whether the `arraybuffer` is detached.
3642
3643Returns `napi_ok` if the API succeeded.
3644
3645The `ArrayBuffer` is considered detached if its internal data is `null`.
3646
3647This API represents the invocation of the `ArrayBuffer` `IsDetachedBuffer`
3648operation as defined in [Section 24.1.1.2][] of the ECMAScript Language
3649Specification.
3650
3651## Working with JavaScript properties
3652
3653Node-API exposes a set of APIs to get and set properties on JavaScript
3654objects. Some of these types are documented under [Section 7][] of the
3655[ECMAScript Language Specification][].
3656
3657Properties in JavaScript are represented as a tuple of a key and a value.
3658Fundamentally, all property keys in Node-API can be represented in one of the
3659following forms:
3660
3661* Named: a simple UTF8-encoded string
3662* Integer-Indexed: an index value represented by `uint32_t`
3663* JavaScript value: these are represented in Node-API by `napi_value`. This can
3664  be a `napi_value` representing a `string`, `number`, or `symbol`.
3665
3666Node-API values are represented by the type `napi_value`.
3667Any Node-API call that requires a JavaScript value takes in a `napi_value`.
3668However, it's the caller's responsibility to make sure that the
3669`napi_value` in question is of the JavaScript type expected by the API.
3670
3671The APIs documented in this section provide a simple interface to
3672get and set properties on arbitrary JavaScript objects represented by
3673`napi_value`.
3674
3675For instance, consider the following JavaScript code snippet:
3676
3677```js
3678const obj = {};
3679obj.myProp = 123;
3680```
3681
3682The equivalent can be done using Node-API values with the following snippet:
3683
3684```c
3685napi_status status = napi_generic_failure;
3686
3687// const obj = {}
3688napi_value obj, value;
3689status = napi_create_object(env, &obj);
3690if (status != napi_ok) return status;
3691
3692// Create a napi_value for 123
3693status = napi_create_int32(env, 123, &value);
3694if (status != napi_ok) return status;
3695
3696// obj.myProp = 123
3697status = napi_set_named_property(env, obj, "myProp", value);
3698if (status != napi_ok) return status;
3699```
3700
3701Indexed properties can be set in a similar manner. Consider the following
3702JavaScript snippet:
3703
3704```js
3705const arr = [];
3706arr[123] = 'hello';
3707```
3708
3709The equivalent can be done using Node-API values with the following snippet:
3710
3711```c
3712napi_status status = napi_generic_failure;
3713
3714// const arr = [];
3715napi_value arr, value;
3716status = napi_create_array(env, &arr);
3717if (status != napi_ok) return status;
3718
3719// Create a napi_value for 'hello'
3720status = napi_create_string_utf8(env, "hello", NAPI_AUTO_LENGTH, &value);
3721if (status != napi_ok) return status;
3722
3723// arr[123] = 'hello';
3724status = napi_set_element(env, arr, 123, value);
3725if (status != napi_ok) return status;
3726```
3727
3728Properties can be retrieved using the APIs described in this section.
3729Consider the following JavaScript snippet:
3730
3731```js
3732const arr = [];
3733const value = arr[123];
3734```
3735
3736The following is the approximate equivalent of the Node-API counterpart:
3737
3738```c
3739napi_status status = napi_generic_failure;
3740
3741// const arr = []
3742napi_value arr, value;
3743status = napi_create_array(env, &arr);
3744if (status != napi_ok) return status;
3745
3746// const value = arr[123]
3747status = napi_get_element(env, arr, 123, &value);
3748if (status != napi_ok) return status;
3749```
3750
3751Finally, multiple properties can also be defined on an object for performance
3752reasons. Consider the following JavaScript:
3753
3754```js
3755const obj = {};
3756Object.defineProperties(obj, {
3757  'foo': { value: 123, writable: true, configurable: true, enumerable: true },
3758  'bar': { value: 456, writable: true, configurable: true, enumerable: true }
3759});
3760```
3761
3762The following is the approximate equivalent of the Node-API counterpart:
3763
3764```c
3765napi_status status = napi_status_generic_failure;
3766
3767// const obj = {};
3768napi_value obj;
3769status = napi_create_object(env, &obj);
3770if (status != napi_ok) return status;
3771
3772// Create napi_values for 123 and 456
3773napi_value fooValue, barValue;
3774status = napi_create_int32(env, 123, &fooValue);
3775if (status != napi_ok) return status;
3776status = napi_create_int32(env, 456, &barValue);
3777if (status != napi_ok) return status;
3778
3779// Set the properties
3780napi_property_descriptor descriptors[] = {
3781  { "foo", NULL, NULL, NULL, NULL, fooValue, napi_writable | napi_configurable, NULL },
3782  { "bar", NULL, NULL, NULL, NULL, barValue, napi_writable | napi_configurable, NULL }
3783}
3784status = napi_define_properties(env,
3785                                obj,
3786                                sizeof(descriptors) / sizeof(descriptors[0]),
3787                                descriptors);
3788if (status != napi_ok) return status;
3789```
3790
3791### Structures
3792#### napi_property_attributes
3793<!-- YAML
3794changes:
3795 - version: v14.12.0
3796   pr-url: https://github.com/nodejs/node/pull/35214
3797   description: added `napi_default_method` and `napi_default_property`.
3798-->
3799
3800```c
3801typedef enum {
3802  napi_default = 0,
3803  napi_writable = 1 << 0,
3804  napi_enumerable = 1 << 1,
3805  napi_configurable = 1 << 2,
3806
3807  // Used with napi_define_class to distinguish static properties
3808  // from instance properties. Ignored by napi_define_properties.
3809  napi_static = 1 << 10,
3810
3811  // Default for class methods.
3812  napi_default_method = napi_writable | napi_configurable,
3813
3814  // Default for object properties, like in JS obj[prop].
3815  napi_default_jsproperty = napi_writable |
3816                          napi_enumerable |
3817                          napi_configurable,
3818} napi_property_attributes;
3819```
3820
3821`napi_property_attributes` are flags used to control the behavior of properties
3822set on a JavaScript object. Other than `napi_static` they correspond to the
3823attributes listed in [Section 6.1.7.1][]
3824of the [ECMAScript Language Specification][].
3825They can be one or more of the following bitflags:
3826
3827* `napi_default`: No explicit attributes are set on the property. By default, a
3828  property is read only, not enumerable and not configurable.
3829* `napi_writable`: The property is writable.
3830* `napi_enumerable`: The property is enumerable.
3831* `napi_configurable`: The property is configurable as defined in
3832  [Section 6.1.7.1][] of the [ECMAScript Language Specification][].
3833* `napi_static`: The property will be defined as a static property on a class as
3834  opposed to an instance property, which is the default. This is used only by
3835  [`napi_define_class`][]. It is ignored by `napi_define_properties`.
3836* `napi_default_method`: Like a method in a JS class, the property is
3837  configurable and writeable, but not enumerable.
3838* `napi_default_jsproperty`: Like a property set via assignment in JavaScript,
3839  the property is writable, enumerable, and configurable.
3840
3841#### napi_property_descriptor
3842
3843```c
3844typedef struct {
3845  // One of utf8name or name should be NULL.
3846  const char* utf8name;
3847  napi_value name;
3848
3849  napi_callback method;
3850  napi_callback getter;
3851  napi_callback setter;
3852  napi_value value;
3853
3854  napi_property_attributes attributes;
3855  void* data;
3856} napi_property_descriptor;
3857```
3858
3859* `utf8name`: Optional string describing the key for the property,
3860  encoded as UTF8. One of `utf8name` or `name` must be provided for the
3861  property.
3862* `name`: Optional `napi_value` that points to a JavaScript string or symbol
3863  to be used as the key for the property. One of `utf8name` or `name` must
3864  be provided for the property.
3865* `value`: The value that's retrieved by a get access of the property if the
3866  property is a data property. If this is passed in, set `getter`, `setter`,
3867  `method` and `data` to `NULL` (since these members won't be used).
3868* `getter`: A function to call when a get access of the property is performed.
3869  If this is passed in, set `value` and `method` to `NULL` (since these members
3870  won't be used). The given function is called implicitly by the runtime when
3871  the property is accessed from JavaScript code (or if a get on the property is
3872  performed using a Node-API call). [`napi_callback`][] provides more details.
3873* `setter`: A function to call when a set access of the property is performed.
3874  If this is passed in, set `value` and `method` to `NULL` (since these members
3875  won't be used). The given function is called implicitly by the runtime when
3876  the property is set from JavaScript code (or if a set on the property is
3877  performed using a Node-API call). [`napi_callback`][] provides more details.
3878* `method`: Set this to make the property descriptor object's `value`
3879  property to be a JavaScript function represented by `method`. If this is
3880  passed in, set `value`, `getter` and `setter` to `NULL` (since these members
3881  won't be used). [`napi_callback`][] provides more details.
3882* `attributes`: The attributes associated with the particular property. See
3883  [`napi_property_attributes`][].
3884* `data`: The callback data passed into `method`, `getter` and `setter` if this
3885  function is invoked.
3886
3887### Functions
3888#### napi_get_property_names
3889<!-- YAML
3890added: v8.0.0
3891napiVersion: 1
3892-->
3893
3894```c
3895napi_status napi_get_property_names(napi_env env,
3896                                    napi_value object,
3897                                    napi_value* result);
3898```
3899
3900* `[in] env`: The environment that the Node-API call is invoked under.
3901* `[in] object`: The object from which to retrieve the properties.
3902* `[out] result`: A `napi_value` representing an array of JavaScript values
3903  that represent the property names of the object. The API can be used to
3904  iterate over `result` using [`napi_get_array_length`][]
3905  and [`napi_get_element`][].
3906
3907Returns `napi_ok` if the API succeeded.
3908
3909This API returns the names of the enumerable properties of `object` as an array
3910of strings. The properties of `object` whose key is a symbol will not be
3911included.
3912
3913#### napi_get_all_property_names
3914<!-- YAML
3915added:
3916 - v13.7.0
3917 - v10.20.0
3918napiVersion: 6
3919-->
3920
3921```c
3922napi_get_all_property_names(napi_env env,
3923                            napi_value object,
3924                            napi_key_collection_mode key_mode,
3925                            napi_key_filter key_filter,
3926                            napi_key_conversion key_conversion,
3927                            napi_value* result);
3928```
3929
3930* `[in] env`: The environment that the Node-API call is invoked under.
3931* `[in] object`: The object from which to retrieve the properties.
3932* `[in] key_mode`: Whether to retrieve prototype properties as well.
3933* `[in] key_filter`: Which properties to retrieve
3934  (enumerable/readable/writable).
3935* `[in] key_conversion`: Whether to convert numbered property keys to strings.
3936* `[out] result`: A `napi_value` representing an array of JavaScript values
3937  that represent the property names of the object. [`napi_get_array_length`][]
3938  and [`napi_get_element`][] can be used to iterate over `result`.
3939
3940Returns `napi_ok` if the API succeeded.
3941
3942This API returns an array containing the names of the available properties
3943of this object.
3944
3945#### napi_set_property
3946<!-- YAML
3947added: v8.0.0
3948napiVersion: 1
3949-->
3950
3951```c
3952napi_status napi_set_property(napi_env env,
3953                              napi_value object,
3954                              napi_value key,
3955                              napi_value value);
3956```
3957
3958* `[in] env`: The environment that the Node-API call is invoked under.
3959* `[in] object`: The object on which to set the property.
3960* `[in] key`: The name of the property to set.
3961* `[in] value`: The property value.
3962
3963Returns `napi_ok` if the API succeeded.
3964
3965This API set a property on the `Object` passed in.
3966
3967#### napi_get_property
3968<!-- YAML
3969added: v8.0.0
3970napiVersion: 1
3971-->
3972
3973```c
3974napi_status napi_get_property(napi_env env,
3975                              napi_value object,
3976                              napi_value key,
3977                              napi_value* result);
3978```
3979
3980* `[in] env`: The environment that the Node-API call is invoked under.
3981* `[in] object`: The object from which to retrieve the property.
3982* `[in] key`: The name of the property to retrieve.
3983* `[out] result`: The value of the property.
3984
3985Returns `napi_ok` if the API succeeded.
3986
3987This API gets the requested property from the `Object` passed in.
3988
3989#### napi_has_property
3990<!-- YAML
3991added: v8.0.0
3992napiVersion: 1
3993-->
3994
3995```c
3996napi_status napi_has_property(napi_env env,
3997                              napi_value object,
3998                              napi_value key,
3999                              bool* result);
4000```
4001
4002* `[in] env`: The environment that the Node-API call is invoked under.
4003* `[in] object`: The object to query.
4004* `[in] key`: The name of the property whose existence to check.
4005* `[out] result`: Whether the property exists on the object or not.
4006
4007Returns `napi_ok` if the API succeeded.
4008
4009This API checks if the `Object` passed in has the named property.
4010
4011#### napi_delete_property
4012<!-- YAML
4013added: v8.2.0
4014napiVersion: 1
4015-->
4016
4017```c
4018napi_status napi_delete_property(napi_env env,
4019                                 napi_value object,
4020                                 napi_value key,
4021                                 bool* result);
4022```
4023
4024* `[in] env`: The environment that the Node-API call is invoked under.
4025* `[in] object`: The object to query.
4026* `[in] key`: The name of the property to delete.
4027* `[out] result`: Whether the property deletion succeeded or not. `result` can
4028  optionally be ignored by passing `NULL`.
4029
4030Returns `napi_ok` if the API succeeded.
4031
4032This API attempts to delete the `key` own property from `object`.
4033
4034#### napi_has_own_property
4035<!-- YAML
4036added: v8.2.0
4037napiVersion: 1
4038-->
4039
4040```c
4041napi_status napi_has_own_property(napi_env env,
4042                                  napi_value object,
4043                                  napi_value key,
4044                                  bool* result);
4045```
4046
4047* `[in] env`: The environment that the Node-API call is invoked under.
4048* `[in] object`: The object to query.
4049* `[in] key`: The name of the own property whose existence to check.
4050* `[out] result`: Whether the own property exists on the object or not.
4051
4052Returns `napi_ok` if the API succeeded.
4053
4054This API checks if the `Object` passed in has the named own property. `key` must
4055be a `string` or a `symbol`, or an error will be thrown. Node-API will not
4056perform any conversion between data types.
4057
4058#### napi_set_named_property
4059<!-- YAML
4060added: v8.0.0
4061napiVersion: 1
4062-->
4063
4064```c
4065napi_status napi_set_named_property(napi_env env,
4066                                    napi_value object,
4067                                    const char* utf8Name,
4068                                    napi_value value);
4069```
4070
4071* `[in] env`: The environment that the Node-API call is invoked under.
4072* `[in] object`: The object on which to set the property.
4073* `[in] utf8Name`: The name of the property to set.
4074* `[in] value`: The property value.
4075
4076Returns `napi_ok` if the API succeeded.
4077
4078This method is equivalent to calling [`napi_set_property`][] with a `napi_value`
4079created from the string passed in as `utf8Name`.
4080
4081#### napi_get_named_property
4082<!-- YAML
4083added: v8.0.0
4084napiVersion: 1
4085-->
4086
4087```c
4088napi_status napi_get_named_property(napi_env env,
4089                                    napi_value object,
4090                                    const char* utf8Name,
4091                                    napi_value* result);
4092```
4093
4094* `[in] env`: The environment that the Node-API call is invoked under.
4095* `[in] object`: The object from which to retrieve the property.
4096* `[in] utf8Name`: The name of the property to get.
4097* `[out] result`: The value of the property.
4098
4099Returns `napi_ok` if the API succeeded.
4100
4101This method is equivalent to calling [`napi_get_property`][] with a `napi_value`
4102created from the string passed in as `utf8Name`.
4103
4104#### napi_has_named_property
4105<!-- YAML
4106added: v8.0.0
4107napiVersion: 1
4108-->
4109
4110```c
4111napi_status napi_has_named_property(napi_env env,
4112                                    napi_value object,
4113                                    const char* utf8Name,
4114                                    bool* result);
4115```
4116
4117* `[in] env`: The environment that the Node-API call is invoked under.
4118* `[in] object`: The object to query.
4119* `[in] utf8Name`: The name of the property whose existence to check.
4120* `[out] result`: Whether the property exists on the object or not.
4121
4122Returns `napi_ok` if the API succeeded.
4123
4124This method is equivalent to calling [`napi_has_property`][] with a `napi_value`
4125created from the string passed in as `utf8Name`.
4126
4127#### napi_set_element
4128<!-- YAML
4129added: v8.0.0
4130napiVersion: 1
4131-->
4132
4133```c
4134napi_status napi_set_element(napi_env env,
4135                             napi_value object,
4136                             uint32_t index,
4137                             napi_value value);
4138```
4139
4140* `[in] env`: The environment that the Node-API call is invoked under.
4141* `[in] object`: The object from which to set the properties.
4142* `[in] index`: The index of the property to set.
4143* `[in] value`: The property value.
4144
4145Returns `napi_ok` if the API succeeded.
4146
4147This API sets and element on the `Object` passed in.
4148
4149#### napi_get_element
4150<!-- YAML
4151added: v8.0.0
4152napiVersion: 1
4153-->
4154
4155```c
4156napi_status napi_get_element(napi_env env,
4157                             napi_value object,
4158                             uint32_t index,
4159                             napi_value* result);
4160```
4161
4162* `[in] env`: The environment that the Node-API call is invoked under.
4163* `[in] object`: The object from which to retrieve the property.
4164* `[in] index`: The index of the property to get.
4165* `[out] result`: The value of the property.
4166
4167Returns `napi_ok` if the API succeeded.
4168
4169This API gets the element at the requested index.
4170
4171#### napi_has_element
4172<!-- YAML
4173added: v8.0.0
4174napiVersion: 1
4175-->
4176
4177```c
4178napi_status napi_has_element(napi_env env,
4179                             napi_value object,
4180                             uint32_t index,
4181                             bool* result);
4182```
4183
4184* `[in] env`: The environment that the Node-API call is invoked under.
4185* `[in] object`: The object to query.
4186* `[in] index`: The index of the property whose existence to check.
4187* `[out] result`: Whether the property exists on the object or not.
4188
4189Returns `napi_ok` if the API succeeded.
4190
4191This API returns if the `Object` passed in has an element at the
4192requested index.
4193
4194#### napi_delete_element
4195<!-- YAML
4196added: v8.2.0
4197napiVersion: 1
4198-->
4199
4200```c
4201napi_status napi_delete_element(napi_env env,
4202                                napi_value object,
4203                                uint32_t index,
4204                                bool* result);
4205```
4206
4207* `[in] env`: The environment that the Node-API call is invoked under.
4208* `[in] object`: The object to query.
4209* `[in] index`: The index of the property to delete.
4210* `[out] result`: Whether the element deletion succeeded or not. `result` can
4211  optionally be ignored by passing `NULL`.
4212
4213Returns `napi_ok` if the API succeeded.
4214
4215This API attempts to delete the specified `index` from `object`.
4216
4217#### napi_define_properties
4218<!-- YAML
4219added: v8.0.0
4220napiVersion: 1
4221-->
4222
4223```c
4224napi_status napi_define_properties(napi_env env,
4225                                   napi_value object,
4226                                   size_t property_count,
4227                                   const napi_property_descriptor* properties);
4228```
4229
4230* `[in] env`: The environment that the Node-API call is invoked under.
4231* `[in] object`: The object from which to retrieve the properties.
4232* `[in] property_count`: The number of elements in the `properties` array.
4233* `[in] properties`: The array of property descriptors.
4234
4235Returns `napi_ok` if the API succeeded.
4236
4237This method allows the efficient definition of multiple properties on a given
4238object. The properties are defined using property descriptors (see
4239[`napi_property_descriptor`][]). Given an array of such property descriptors,
4240this API will set the properties on the object one at a time, as defined by
4241`DefineOwnProperty()` (described in [Section 9.1.6][] of the ECMA-262
4242specification).
4243
4244#### napi_object_freeze
4245<!-- YAML
4246added:
4247  - v14.14.0
4248  - v12.20.0
4249napiVersion: 8
4250-->
4251
4252```c
4253napi_status napi_object_freeze(napi_env env,
4254                               napi_value object);
4255```
4256
4257* `[in] env`: The environment that the Node-API call is invoked under.
4258* `[in] object`: The object to freeze.
4259
4260Returns `napi_ok` if the API succeeded.
4261
4262This method freezes a given object. This prevents new properties from
4263being added to it, existing properties from being removed, prevents
4264changing the enumerability, configurability, or writability of existing
4265properties, and prevents the values of existing properties from being changed.
4266It also prevents the object's prototype from being changed. This is described
4267in [Section 19.1.2.6](https://tc39.es/ecma262/#sec-object.freeze) of the
4268ECMA-262 specification.
4269
4270#### napi_object_seal
4271<!-- YAML
4272added:
4273  - v14.14.0
4274  - v12.20.0
4275napiVersion: 8
4276-->
4277
4278```c
4279napi_status napi_object_seal(napi_env env,
4280                             napi_value object);
4281```
4282
4283* `[in] env`: The environment that the Node-API call is invoked under.
4284* `[in] object`: The object to seal.
4285
4286Returns `napi_ok` if the API succeeded.
4287
4288This method seals a given object. This prevents new properties from being
4289added to it, as well as marking all existing properties as non-configurable.
4290This is described in [Section 19.1.2.20](https://tc39.es/ecma262/#sec-object.seal)
4291of the ECMA-262 specification.
4292
4293## Working with JavaScript functions
4294
4295Node-API provides a set of APIs that allow JavaScript code to
4296call back into native code. Node-APIs that support calling back
4297into native code take in a callback functions represented by
4298the `napi_callback` type. When the JavaScript VM calls back to
4299native code, the `napi_callback` function provided is invoked. The APIs
4300documented in this section allow the callback function to do the
4301following:
4302
4303* Get information about the context in which the callback was invoked.
4304* Get the arguments passed into the callback.
4305* Return a `napi_value` back from the callback.
4306
4307Additionally, Node-API provides a set of functions which allow calling
4308JavaScript functions from native code. One can either call a function
4309like a regular JavaScript function call, or as a constructor
4310function.
4311
4312Any non-`NULL` data which is passed to this API via the `data` field of the
4313`napi_property_descriptor` items can be associated with `object` and freed
4314whenever `object` is garbage-collected by passing both `object` and the data to
4315[`napi_add_finalizer`][].
4316
4317### napi_call_function
4318<!-- YAML
4319added: v8.0.0
4320napiVersion: 1
4321-->
4322
4323```c
4324NAPI_EXTERN napi_status napi_call_function(napi_env env,
4325                                           napi_value recv,
4326                                           napi_value func,
4327                                           size_t argc,
4328                                           const napi_value* argv,
4329                                           napi_value* result);
4330```
4331
4332* `[in] env`: The environment that the API is invoked under.
4333* `[in] recv`: The `this` value passed to the called function.
4334* `[in] func`: `napi_value` representing the JavaScript function to be invoked.
4335* `[in] argc`: The count of elements in the `argv` array.
4336* `[in] argv`: Array of `napi_values` representing JavaScript values passed in
4337  as arguments to the function.
4338* `[out] result`: `napi_value` representing the JavaScript object returned.
4339
4340Returns `napi_ok` if the API succeeded.
4341
4342This method allows a JavaScript function object to be called from a native
4343add-on. This is the primary mechanism of calling back *from* the add-on's
4344native code *into* JavaScript. For the special case of calling into JavaScript
4345after an async operation, see [`napi_make_callback`][].
4346
4347A sample use case might look as follows. Consider the following JavaScript
4348snippet:
4349
4350```js
4351function AddTwo(num) {
4352  return num + 2;
4353}
4354```
4355
4356Then, the above function can be invoked from a native add-on using the
4357following code:
4358
4359```c
4360// Get the function named "AddTwo" on the global object
4361napi_value global, add_two, arg;
4362napi_status status = napi_get_global(env, &global);
4363if (status != napi_ok) return;
4364
4365status = napi_get_named_property(env, global, "AddTwo", &add_two);
4366if (status != napi_ok) return;
4367
4368// const arg = 1337
4369status = napi_create_int32(env, 1337, &arg);
4370if (status != napi_ok) return;
4371
4372napi_value* argv = &arg;
4373size_t argc = 1;
4374
4375// AddTwo(arg);
4376napi_value return_val;
4377status = napi_call_function(env, global, add_two, argc, argv, &return_val);
4378if (status != napi_ok) return;
4379
4380// Convert the result back to a native type
4381int32_t result;
4382status = napi_get_value_int32(env, return_val, &result);
4383if (status != napi_ok) return;
4384```
4385
4386### napi_create_function
4387<!-- YAML
4388added: v8.0.0
4389napiVersion: 1
4390-->
4391
4392```c
4393napi_status napi_create_function(napi_env env,
4394                                 const char* utf8name,
4395                                 size_t length,
4396                                 napi_callback cb,
4397                                 void* data,
4398                                 napi_value* result);
4399```
4400
4401* `[in] env`: The environment that the API is invoked under.
4402* `[in] utf8Name`: The name of the function encoded as UTF8. This is visible
4403  within JavaScript as the new function object's `name` property.
4404* `[in] length`: The length of the `utf8name` in bytes, or `NAPI_AUTO_LENGTH` if
4405  it is null-terminated.
4406* `[in] cb`: The native function which should be called when this function
4407  object is invoked. [`napi_callback`][] provides more details.
4408* `[in] data`: User-provided data context. This will be passed back into the
4409  function when invoked later.
4410* `[out] result`: `napi_value` representing the JavaScript function object for
4411  the newly created function.
4412
4413Returns `napi_ok` if the API succeeded.
4414
4415This API allows an add-on author to create a function object in native code.
4416This is the primary mechanism to allow calling *into* the add-on's native code
4417*from* JavaScript.
4418
4419The newly created function is not automatically visible from script after this
4420call. Instead, a property must be explicitly set on any object that is visible
4421to JavaScript, in order for the function to be accessible from script.
4422
4423In order to expose a function as part of the
4424add-on's module exports, set the newly created function on the exports
4425object. A sample module might look as follows:
4426
4427```c
4428napi_value SayHello(napi_env env, napi_callback_info info) {
4429  printf("Hello\n");
4430  return NULL;
4431}
4432
4433napi_value Init(napi_env env, napi_value exports) {
4434  napi_status status;
4435
4436  napi_value fn;
4437  status = napi_create_function(env, NULL, 0, SayHello, NULL, &fn);
4438  if (status != napi_ok) return NULL;
4439
4440  status = napi_set_named_property(env, exports, "sayHello", fn);
4441  if (status != napi_ok) return NULL;
4442
4443  return exports;
4444}
4445
4446NAPI_MODULE(NODE_GYP_MODULE_NAME, Init)
4447```
4448
4449Given the above code, the add-on can be used from JavaScript as follows:
4450
4451```js
4452const myaddon = require('./addon');
4453myaddon.sayHello();
4454```
4455
4456The string passed to `require()` is the name of the target in `binding.gyp`
4457responsible for creating the `.node` file.
4458
4459Any non-`NULL` data which is passed to this API via the `data` parameter can
4460be associated with the resulting JavaScript function (which is returned in the
4461`result` parameter) and freed whenever the function is garbage-collected by
4462passing both the JavaScript function and the data to [`napi_add_finalizer`][].
4463
4464JavaScript `Function`s are described in [Section 19.2][] of the ECMAScript
4465Language Specification.
4466
4467### napi_get_cb_info
4468<!-- YAML
4469added: v8.0.0
4470napiVersion: 1
4471-->
4472
4473```c
4474napi_status napi_get_cb_info(napi_env env,
4475                             napi_callback_info cbinfo,
4476                             size_t* argc,
4477                             napi_value* argv,
4478                             napi_value* thisArg,
4479                             void** data)
4480```
4481
4482* `[in] env`: The environment that the API is invoked under.
4483* `[in] cbinfo`: The callback info passed into the callback function.
4484* `[in-out] argc`: Specifies the length of the provided `argv` array and
4485  receives the actual count of arguments.
4486* `[out] argv`: Buffer to which the `napi_value` representing the arguments are
4487  copied. If there are more arguments than the provided count, only the
4488  requested number of arguments are copied. If there are fewer arguments
4489  provided than claimed, the rest of `argv` is filled with `napi_value` values
4490  that represent `undefined`.
4491* `[out] this`: Receives the JavaScript `this` argument for the call.
4492* `[out] data`: Receives the data pointer for the callback.
4493
4494Returns `napi_ok` if the API succeeded.
4495
4496This method is used within a callback function to retrieve details about the
4497call like the arguments and the `this` pointer from a given callback info.
4498
4499### napi_get_new_target
4500<!-- YAML
4501added: v8.6.0
4502napiVersion: 1
4503-->
4504
4505```c
4506napi_status napi_get_new_target(napi_env env,
4507                                napi_callback_info cbinfo,
4508                                napi_value* result)
4509```
4510
4511* `[in] env`: The environment that the API is invoked under.
4512* `[in] cbinfo`: The callback info passed into the callback function.
4513* `[out] result`: The `new.target` of the constructor call.
4514
4515Returns `napi_ok` if the API succeeded.
4516
4517This API returns the `new.target` of the constructor call. If the current
4518callback is not a constructor call, the result is `NULL`.
4519
4520### napi_new_instance
4521<!-- YAML
4522added: v8.0.0
4523napiVersion: 1
4524-->
4525
4526```c
4527napi_status napi_new_instance(napi_env env,
4528                              napi_value cons,
4529                              size_t argc,
4530                              napi_value* argv,
4531                              napi_value* result)
4532```
4533
4534* `[in] env`: The environment that the API is invoked under.
4535* `[in] cons`: `napi_value` representing the JavaScript function to be invoked
4536  as a constructor.
4537* `[in] argc`: The count of elements in the `argv` array.
4538* `[in] argv`: Array of JavaScript values as `napi_value` representing the
4539  arguments to the constructor.
4540* `[out] result`: `napi_value` representing the JavaScript object returned,
4541  which in this case is the constructed object.
4542
4543This method is used to instantiate a new JavaScript value using a given
4544`napi_value` that represents the constructor for the object. For example,
4545consider the following snippet:
4546
4547```js
4548function MyObject(param) {
4549  this.param = param;
4550}
4551
4552const arg = 'hello';
4553const value = new MyObject(arg);
4554```
4555
4556The following can be approximated in Node-API using the following snippet:
4557
4558```c
4559// Get the constructor function MyObject
4560napi_value global, constructor, arg, value;
4561napi_status status = napi_get_global(env, &global);
4562if (status != napi_ok) return;
4563
4564status = napi_get_named_property(env, global, "MyObject", &constructor);
4565if (status != napi_ok) return;
4566
4567// const arg = "hello"
4568status = napi_create_string_utf8(env, "hello", NAPI_AUTO_LENGTH, &arg);
4569if (status != napi_ok) return;
4570
4571napi_value* argv = &arg;
4572size_t argc = 1;
4573
4574// const value = new MyObject(arg)
4575status = napi_new_instance(env, constructor, argc, argv, &value);
4576```
4577
4578Returns `napi_ok` if the API succeeded.
4579
4580## Object wrap
4581
4582Node-API offers a way to "wrap" C++ classes and instances so that the class
4583constructor and methods can be called from JavaScript.
4584
45851. The [`napi_define_class`][] API defines a JavaScript class with constructor,
4586    static properties and methods, and instance properties and methods that
4587    correspond to the C++ class.
45882. When JavaScript code invokes the constructor, the constructor callback
4589    uses [`napi_wrap`][] to wrap a new C++ instance in a JavaScript object,
4590    then returns the wrapper object.
45913. When JavaScript code invokes a method or property accessor on the class,
4592    the corresponding `napi_callback` C++ function is invoked. For an instance
4593    callback, [`napi_unwrap`][] obtains the C++ instance that is the target of
4594    the call.
4595
4596For wrapped objects it may be difficult to distinguish between a function
4597called on a class prototype and a function called on an instance of a class.
4598A common pattern used to address this problem is to save a persistent
4599reference to the class constructor for later `instanceof` checks.
4600
4601```c
4602napi_value MyClass_constructor = NULL;
4603status = napi_get_reference_value(env, MyClass::es_constructor, &MyClass_constructor);
4604assert(napi_ok == status);
4605bool is_instance = false;
4606status = napi_instanceof(env, es_this, MyClass_constructor, &is_instance);
4607assert(napi_ok == status);
4608if (is_instance) {
4609  // napi_unwrap() ...
4610} else {
4611  // otherwise...
4612}
4613```
4614
4615The reference must be freed once it is no longer needed.
4616
4617There are occasions where `napi_instanceof()` is insufficient for ensuring that
4618a JavaScript object is a wrapper for a certain native type. This is the case
4619especially when wrapped JavaScript objects are passed back into the addon via
4620static methods rather than as the `this` value of prototype methods. In such
4621cases there is a chance that they may be unwrapped incorrectly.
4622
4623```js
4624const myAddon = require('./build/Release/my_addon.node');
4625
4626// `openDatabase()` returns a JavaScript object that wraps a native database
4627// handle.
4628const dbHandle = myAddon.openDatabase();
4629
4630// `query()` returns a JavaScript object that wraps a native query handle.
4631const queryHandle = myAddon.query(dbHandle, 'Gimme ALL the things!');
4632
4633// There is an accidental error in the line below. The first parameter to
4634// `myAddon.queryHasRecords()` should be the database handle (`dbHandle`), not
4635// the query handle (`query`), so the correct condition for the while-loop
4636// should be
4637//
4638// myAddon.queryHasRecords(dbHandle, queryHandle)
4639//
4640while (myAddon.queryHasRecords(queryHandle, dbHandle)) {
4641  // retrieve records
4642}
4643```
4644
4645In the above example `myAddon.queryHasRecords()` is a method that accepts two
4646arguments. The first is a database handle and the second is a query handle.
4647Internally, it unwraps the first argument and casts the resulting pointer to a
4648native database handle. It then unwraps the second argument and casts the
4649resulting pointer to a query handle. If the arguments are passed in the wrong
4650order, the casts will work, however, there is a good chance that the underlying
4651database operation will fail, or will even cause an invalid memory access.
4652
4653To ensure that the pointer retrieved from the first argument is indeed a pointer
4654to a database handle and, similarly, that the pointer retrieved from the second
4655argument is indeed a pointer to a query handle, the implementation of
4656`queryHasRecords()` has to perform a type validation. Retaining the JavaScript
4657class constructor from which the database handle was instantiated and the
4658constructor from which the query handle was instantiated in `napi_ref`s can
4659help, because `napi_instanceof()` can then be used to ensure that the instances
4660passed into `queryHashRecords()` are indeed of the correct type.
4661
4662Unfortunately, `napi_instanceof()` does not protect against prototype
4663manipulation. For example, the prototype of the database handle instance can be
4664set to the prototype of the constructor for query handle instances. In this
4665case, the database handle instance can appear as a query handle instance, and it
4666will pass the `napi_instanceof()` test for a query handle instance, while still
4667containing a pointer to a database handle.
4668
4669To this end, Node-API provides type-tagging capabilities.
4670
4671A type tag is a 128-bit integer unique to the addon. Node-API provides the
4672`napi_type_tag` structure for storing a type tag. When such a value is passed
4673along with a JavaScript object stored in a `napi_value` to
4674`napi_type_tag_object()`, the JavaScript object will be "marked" with the
4675type tag. The "mark" is invisible on the JavaScript side. When a JavaScript
4676object arrives into a native binding, `napi_check_object_type_tag()` can be used
4677along with the original type tag to determine whether the JavaScript object was
4678previously "marked" with the type tag. This creates a type-checking capability
4679of a higher fidelity than `napi_instanceof()` can provide, because such type-
4680tagging survives prototype manipulation and addon unloading/reloading.
4681
4682Continuing the above example, the following skeleton addon implementation
4683illustrates the use of `napi_type_tag_object()` and
4684`napi_check_object_type_tag()`.
4685
4686```c
4687// This value is the type tag for a database handle. The command
4688//
4689//   uuidgen | sed -r -e 's/-//g' -e 's/(.{16})(.*)/0x\1, 0x\2/'
4690//
4691// can be used to obtain the two values with which to initialize the structure.
4692static const napi_type_tag DatabaseHandleTypeTag = {
4693  0x1edf75a38336451d, 0xa5ed9ce2e4c00c38
4694};
4695
4696// This value is the type tag for a query handle.
4697static const napi_type_tag QueryHandleTypeTag = {
4698  0x9c73317f9fad44a3, 0x93c3920bf3b0ad6a
4699};
4700
4701static napi_value
4702openDatabase(napi_env env, napi_callback_info info) {
4703  napi_status status;
4704  napi_value result;
4705
4706  // Perform the underlying action which results in a database handle.
4707  DatabaseHandle* dbHandle = open_database();
4708
4709  // Create a new, empty JS object.
4710  status = napi_create_object(env, &result);
4711  if (status != napi_ok) return NULL;
4712
4713  // Tag the object to indicate that it holds a pointer to a `DatabaseHandle`.
4714  status = napi_type_tag_object(env, result, &DatabaseHandleTypeTag);
4715  if (status != napi_ok) return NULL;
4716
4717  // Store the pointer to the `DatabaseHandle` structure inside the JS object.
4718  status = napi_wrap(env, result, dbHandle, NULL, NULL, NULL);
4719  if (status != napi_ok) return NULL;
4720
4721  return result;
4722}
4723
4724// Later when we receive a JavaScript object purporting to be a database handle
4725// we can use `napi_check_object_type_tag()` to ensure that it is indeed such a
4726// handle.
4727
4728static napi_value
4729query(napi_env env, napi_callback_info info) {
4730  napi_status status;
4731  size_t argc = 2;
4732  napi_value argv[2];
4733  bool is_db_handle;
4734
4735  status = napi_get_cb_info(env, info, &argc, argv, NULL, NULL);
4736  if (status != napi_ok) return NULL;
4737
4738  // Check that the object passed as the first parameter has the previously
4739  // applied tag.
4740  status = napi_check_object_type_tag(env,
4741                                      argv[0],
4742                                      &DatabaseHandleTypeTag,
4743                                      &is_db_handle);
4744  if (status != napi_ok) return NULL;
4745
4746  // Throw a `TypeError` if it doesn't.
4747  if (!is_db_handle) {
4748    // Throw a TypeError.
4749    return NULL;
4750  }
4751}
4752```
4753
4754### napi_define_class
4755<!-- YAML
4756added: v8.0.0
4757napiVersion: 1
4758-->
4759
4760```c
4761napi_status napi_define_class(napi_env env,
4762                              const char* utf8name,
4763                              size_t length,
4764                              napi_callback constructor,
4765                              void* data,
4766                              size_t property_count,
4767                              const napi_property_descriptor* properties,
4768                              napi_value* result);
4769```
4770
4771* `[in] env`: The environment that the API is invoked under.
4772* `[in] utf8name`: Name of the JavaScript constructor function; When wrapping a
4773  C++ class, we recommend for clarity that this name be the same as that of
4774  the C++ class.
4775* `[in] length`: The length of the `utf8name` in bytes, or `NAPI_AUTO_LENGTH`
4776  if it is null-terminated.
4777* `[in] constructor`: Callback function that handles constructing instances
4778  of the class. When wrapping a C++ class, this method must be a static member
4779  with the [`napi_callback`][] signature. A C++ class constructor cannot be
4780  used. [`napi_callback`][] provides more details.
4781* `[in] data`: Optional data to be passed to the constructor callback as
4782  the `data` property of the callback info.
4783* `[in] property_count`: Number of items in the `properties` array argument.
4784* `[in] properties`: Array of property descriptors describing static and
4785  instance data properties, accessors, and methods on the class
4786  See `napi_property_descriptor`.
4787* `[out] result`: A `napi_value` representing the constructor function for
4788  the class.
4789
4790Returns `napi_ok` if the API succeeded.
4791
4792Defines a JavaScript class, including:
4793
4794* A JavaScript constructor function that has the class name. When wrapping a
4795  corresponding C++ class, the callback passed via `constructor` can be used to
4796  instantiate a new C++ class instance, which can then be placed inside the
4797  JavaScript object instance being constructed using [`napi_wrap`][].
4798* Properties on the constructor function whose implementation can call
4799  corresponding _static_ data properties, accessors, and methods of the C++
4800  class (defined by property descriptors with the `napi_static` attribute).
4801* Properties on the constructor function's `prototype` object. When wrapping a
4802  C++ class, _non-static_ data properties, accessors, and methods of the C++
4803  class can be called from the static functions given in the property
4804  descriptors without the `napi_static` attribute after retrieving the C++ class
4805  instance placed inside the JavaScript object instance by using
4806  [`napi_unwrap`][].
4807
4808When wrapping a C++ class, the C++ constructor callback passed via `constructor`
4809should be a static method on the class that calls the actual class constructor,
4810then wraps the new C++ instance in a JavaScript object, and returns the wrapper
4811object. See [`napi_wrap`][] for details.
4812
4813The JavaScript constructor function returned from [`napi_define_class`][] is
4814often saved and used later to construct new instances of the class from native
4815code, and/or to check whether provided values are instances of the class. In
4816that case, to prevent the function value from being garbage-collected, a
4817strong persistent reference to it can be created using
4818[`napi_create_reference`][], ensuring that the reference count is kept >= 1.
4819
4820Any non-`NULL` data which is passed to this API via the `data` parameter or via
4821the `data` field of the `napi_property_descriptor` array items can be associated
4822with the resulting JavaScript constructor (which is returned in the `result`
4823parameter) and freed whenever the class is garbage-collected by passing both
4824the JavaScript function and the data to [`napi_add_finalizer`][].
4825
4826### napi_wrap
4827<!-- YAML
4828added: v8.0.0
4829napiVersion: 1
4830-->
4831
4832```c
4833napi_status napi_wrap(napi_env env,
4834                      napi_value js_object,
4835                      void* native_object,
4836                      napi_finalize finalize_cb,
4837                      void* finalize_hint,
4838                      napi_ref* result);
4839```
4840
4841* `[in] env`: The environment that the API is invoked under.
4842* `[in] js_object`: The JavaScript object that will be the wrapper for the
4843  native object.
4844* `[in] native_object`: The native instance that will be wrapped in the
4845  JavaScript object.
4846* `[in] finalize_cb`: Optional native callback that can be used to free the
4847  native instance when the JavaScript object is ready for garbage-collection.
4848  [`napi_finalize`][] provides more details.
4849* `[in] finalize_hint`: Optional contextual hint that is passed to the
4850  finalize callback.
4851* `[out] result`: Optional reference to the wrapped object.
4852
4853Returns `napi_ok` if the API succeeded.
4854
4855Wraps a native instance in a JavaScript object. The native instance can be
4856retrieved later using `napi_unwrap()`.
4857
4858When JavaScript code invokes a constructor for a class that was defined using
4859`napi_define_class()`, the `napi_callback` for the constructor is invoked.
4860After constructing an instance of the native class, the callback must then call
4861`napi_wrap()` to wrap the newly constructed instance in the already-created
4862JavaScript object that is the `this` argument to the constructor callback.
4863(That `this` object was created from the constructor function's `prototype`,
4864so it already has definitions of all the instance properties and methods.)
4865
4866Typically when wrapping a class instance, a finalize callback should be
4867provided that simply deletes the native instance that is received as the `data`
4868argument to the finalize callback.
4869
4870The optional returned reference is initially a weak reference, meaning it
4871has a reference count of 0. Typically this reference count would be incremented
4872temporarily during async operations that require the instance to remain valid.
4873
4874*Caution*: The optional returned reference (if obtained) should be deleted via
4875[`napi_delete_reference`][] ONLY in response to the finalize callback
4876invocation. If it is deleted before then, then the finalize callback may never
4877be invoked. Therefore, when obtaining a reference a finalize callback is also
4878required in order to enable correct disposal of the reference.
4879
4880Calling `napi_wrap()` a second time on an object will return an error. To
4881associate another native instance with the object, use `napi_remove_wrap()`
4882first.
4883
4884### napi_unwrap
4885<!-- YAML
4886added: v8.0.0
4887napiVersion: 1
4888-->
4889
4890```c
4891napi_status napi_unwrap(napi_env env,
4892                        napi_value js_object,
4893                        void** result);
4894```
4895
4896* `[in] env`: The environment that the API is invoked under.
4897* `[in] js_object`: The object associated with the native instance.
4898* `[out] result`: Pointer to the wrapped native instance.
4899
4900Returns `napi_ok` if the API succeeded.
4901
4902Retrieves a native instance that was previously wrapped in a JavaScript
4903object using `napi_wrap()`.
4904
4905When JavaScript code invokes a method or property accessor on the class, the
4906corresponding `napi_callback` is invoked. If the callback is for an instance
4907method or accessor, then the `this` argument to the callback is the wrapper
4908object; the wrapped C++ instance that is the target of the call can be obtained
4909then by calling `napi_unwrap()` on the wrapper object.
4910
4911### napi_remove_wrap
4912<!-- YAML
4913added: v8.5.0
4914napiVersion: 1
4915-->
4916
4917```c
4918napi_status napi_remove_wrap(napi_env env,
4919                             napi_value js_object,
4920                             void** result);
4921```
4922
4923* `[in] env`: The environment that the API is invoked under.
4924* `[in] js_object`: The object associated with the native instance.
4925* `[out] result`: Pointer to the wrapped native instance.
4926
4927Returns `napi_ok` if the API succeeded.
4928
4929Retrieves a native instance that was previously wrapped in the JavaScript
4930object `js_object` using `napi_wrap()` and removes the wrapping. If a finalize
4931callback was associated with the wrapping, it will no longer be called when the
4932JavaScript object becomes garbage-collected.
4933
4934### napi_type_tag_object
4935<!-- YAML
4936added:
4937  - v14.8.0
4938  - v12.19.0
4939napiVersion: 8
4940-->
4941
4942```c
4943napi_status napi_type_tag_object(napi_env env,
4944                                 napi_value js_object,
4945                                 const napi_type_tag* type_tag);
4946```
4947
4948* `[in] env`: The environment that the API is invoked under.
4949* `[in] js_object`: The JavaScript object to be marked.
4950* `[in] type_tag`: The tag with which the object is to be marked.
4951
4952Returns `napi_ok` if the API succeeded.
4953
4954Associates the value of the `type_tag` pointer with the JavaScript object.
4955`napi_check_object_type_tag()` can then be used to compare the tag that was
4956attached to the object with one owned by the addon to ensure that the object
4957has the right type.
4958
4959If the object already has an associated type tag, this API will return
4960`napi_invalid_arg`.
4961
4962### napi_check_object_type_tag
4963<!-- YAML
4964added:
4965  - v14.8.0
4966  - v12.19.0
4967napiVersion: 8
4968-->
4969
4970```c
4971napi_status napi_check_object_type_tag(napi_env env,
4972                                       napi_value js_object,
4973                                       const napi_type_tag* type_tag,
4974                                       bool* result);
4975```
4976
4977* `[in] env`: The environment that the API is invoked under.
4978* `[in] js_object`: The JavaScript object whose type tag to examine.
4979* `[in] type_tag`: The tag with which to compare any tag found on the object.
4980* `[out] result`: Whether the type tag given matched the type tag on the
4981  object. `false` is also returned if no type tag was found on the object.
4982
4983Returns `napi_ok` if the API succeeded.
4984
4985Compares the pointer given as `type_tag` with any that can be found on
4986`js_object`. If no tag is found on `js_object` or, if a tag is found but it does
4987not match `type_tag`, then `result` is set to `false`. If a tag is found and it
4988matches `type_tag`, then `result` is set to `true`.
4989
4990### napi_add_finalizer
4991
4992<!-- YAML
4993added: v8.0.0
4994napiVersion: 5
4995-->
4996
4997```c
4998napi_status napi_add_finalizer(napi_env env,
4999                               napi_value js_object,
5000                               void* native_object,
5001                               napi_finalize finalize_cb,
5002                               void* finalize_hint,
5003                               napi_ref* result);
5004```
5005
5006* `[in] env`: The environment that the API is invoked under.
5007* `[in] js_object`: The JavaScript object to which the native data will be
5008  attached.
5009* `[in] native_object`: The native data that will be attached to the JavaScript
5010  object.
5011* `[in] finalize_cb`: Native callback that will be used to free the
5012  native data when the JavaScript object is ready for garbage-collection.
5013  [`napi_finalize`][] provides more details.
5014* `[in] finalize_hint`: Optional contextual hint that is passed to the
5015  finalize callback.
5016* `[out] result`: Optional reference to the JavaScript object.
5017
5018Returns `napi_ok` if the API succeeded.
5019
5020Adds a `napi_finalize` callback which will be called when the JavaScript object
5021in `js_object` is ready for garbage collection. This API is similar to
5022`napi_wrap()` except that:
5023
5024* the native data cannot be retrieved later using `napi_unwrap()`,
5025* nor can it be removed later using `napi_remove_wrap()`, and
5026* the API can be called multiple times with different data items in order to
5027  attach each of them to the JavaScript object, and
5028* the object manipulated by the API can be used with `napi_wrap()`.
5029
5030*Caution*: The optional returned reference (if obtained) should be deleted via
5031[`napi_delete_reference`][] ONLY in response to the finalize callback
5032invocation. If it is deleted before then, then the finalize callback may never
5033be invoked. Therefore, when obtaining a reference a finalize callback is also
5034required in order to enable correct disposal of the reference.
5035
5036## Simple asynchronous operations
5037
5038Addon modules often need to leverage async helpers from libuv as part of their
5039implementation. This allows them to schedule work to be executed asynchronously
5040so that their methods can return in advance of the work being completed. This
5041allows them to avoid blocking overall execution of the Node.js application.
5042
5043Node-API provides an ABI-stable interface for these
5044supporting functions which covers the most common asynchronous use cases.
5045
5046Node-API defines the `napi_async_work` structure which is used to manage
5047asynchronous workers. Instances are created/deleted with
5048[`napi_create_async_work`][] and [`napi_delete_async_work`][].
5049
5050The `execute` and `complete` callbacks are functions that will be
5051invoked when the executor is ready to execute and when it completes its
5052task respectively.
5053
5054The `execute` function should avoid making any Node-API calls
5055that could result in the execution of JavaScript or interaction with
5056JavaScript objects. Most often, any code that needs to make Node-API
5057calls should be made in `complete` callback instead.
5058Avoid using the `napi_env` parameter in the execute callback as
5059it will likely execute JavaScript.
5060
5061These functions implement the following interfaces:
5062
5063```c
5064typedef void (*napi_async_execute_callback)(napi_env env,
5065                                            void* data);
5066typedef void (*napi_async_complete_callback)(napi_env env,
5067                                             napi_status status,
5068                                             void* data);
5069```
5070
5071When these methods are invoked, the `data` parameter passed will be the
5072addon-provided `void*` data that was passed into the
5073`napi_create_async_work` call.
5074
5075Once created the async worker can be queued
5076for execution using the [`napi_queue_async_work`][] function:
5077
5078```c
5079napi_status napi_queue_async_work(napi_env env,
5080                                  napi_async_work work);
5081```
5082
5083[`napi_cancel_async_work`][] can be used if the work needs
5084to be cancelled before the work has started execution.
5085
5086After calling [`napi_cancel_async_work`][], the `complete` callback
5087will be invoked with a status value of `napi_cancelled`.
5088The work should not be deleted before the `complete`
5089callback invocation, even when it was cancelled.
5090
5091### napi_create_async_work
5092<!-- YAML
5093added: v8.0.0
5094napiVersion: 1
5095changes:
5096  - version: v8.6.0
5097    pr-url: https://github.com/nodejs/node/pull/14697
5098    description: Added `async_resource` and `async_resource_name` parameters.
5099-->
5100
5101```c
5102napi_status napi_create_async_work(napi_env env,
5103                                   napi_value async_resource,
5104                                   napi_value async_resource_name,
5105                                   napi_async_execute_callback execute,
5106                                   napi_async_complete_callback complete,
5107                                   void* data,
5108                                   napi_async_work* result);
5109```
5110
5111* `[in] env`: The environment that the API is invoked under.
5112* `[in] async_resource`: An optional object associated with the async work
5113  that will be passed to possible `async_hooks` [`init` hooks][].
5114* `[in] async_resource_name`: Identifier for the kind of resource that is being
5115  provided for diagnostic information exposed by the `async_hooks` API.
5116* `[in] execute`: The native function which should be called to execute the
5117  logic asynchronously. The given function is called from a worker pool thread
5118  and can execute in parallel with the main event loop thread.
5119* `[in] complete`: The native function which will be called when the
5120  asynchronous logic is completed or is cancelled. The given function is called
5121  from the main event loop thread. [`napi_async_complete_callback`][] provides
5122  more details.
5123* `[in] data`: User-provided data context. This will be passed back into the
5124  execute and complete functions.
5125* `[out] result`: `napi_async_work*` which is the handle to the newly created
5126  async work.
5127
5128Returns `napi_ok` if the API succeeded.
5129
5130This API allocates a work object that is used to execute logic asynchronously.
5131It should be freed using [`napi_delete_async_work`][] once the work is no longer
5132required.
5133
5134`async_resource_name` should be a null-terminated, UTF-8-encoded string.
5135
5136The `async_resource_name` identifier is provided by the user and should be
5137representative of the type of async work being performed. It is also recommended
5138to apply namespacing to the identifier, e.g. by including the module name. See
5139the [`async_hooks` documentation][async_hooks `type`] for more information.
5140
5141### napi_delete_async_work
5142<!-- YAML
5143added: v8.0.0
5144napiVersion: 1
5145-->
5146
5147```c
5148napi_status napi_delete_async_work(napi_env env,
5149                                   napi_async_work work);
5150```
5151
5152* `[in] env`: The environment that the API is invoked under.
5153* `[in] work`: The handle returned by the call to `napi_create_async_work`.
5154
5155Returns `napi_ok` if the API succeeded.
5156
5157This API frees a previously allocated work object.
5158
5159This API can be called even if there is a pending JavaScript exception.
5160
5161### napi_queue_async_work
5162<!-- YAML
5163added: v8.0.0
5164napiVersion: 1
5165-->
5166
5167```c
5168napi_status napi_queue_async_work(napi_env env,
5169                                  napi_async_work work);
5170```
5171
5172* `[in] env`: The environment that the API is invoked under.
5173* `[in] work`: The handle returned by the call to `napi_create_async_work`.
5174
5175Returns `napi_ok` if the API succeeded.
5176
5177This API requests that the previously allocated work be scheduled
5178for execution. Once it returns successfully, this API must not be called again
5179with the same `napi_async_work` item or the result will be undefined.
5180
5181### napi_cancel_async_work
5182<!-- YAML
5183added: v8.0.0
5184napiVersion: 1
5185-->
5186
5187```c
5188napi_status napi_cancel_async_work(napi_env env,
5189                                   napi_async_work work);
5190```
5191
5192* `[in] env`: The environment that the API is invoked under.
5193* `[in] work`: The handle returned by the call to `napi_create_async_work`.
5194
5195Returns `napi_ok` if the API succeeded.
5196
5197This API cancels queued work if it has not yet
5198been started. If it has already started executing, it cannot be
5199cancelled and `napi_generic_failure` will be returned. If successful,
5200the `complete` callback will be invoked with a status value of
5201`napi_cancelled`. The work should not be deleted before the `complete`
5202callback invocation, even if it has been successfully cancelled.
5203
5204This API can be called even if there is a pending JavaScript exception.
5205
5206## Custom asynchronous operations
5207
5208The simple asynchronous work APIs above may not be appropriate for every
5209scenario. When using any other asynchronous mechanism, the following APIs
5210are necessary to ensure an asynchronous operation is properly tracked by
5211the runtime.
5212
5213### napi_async_init
5214<!-- YAML
5215added: v8.6.0
5216napiVersion: 1
5217-->
5218
5219```c
5220napi_status napi_async_init(napi_env env,
5221                            napi_value async_resource,
5222                            napi_value async_resource_name,
5223                            napi_async_context* result)
5224```
5225
5226* `[in] env`: The environment that the API is invoked under.
5227* `[in] async_resource`: Object associated with the async work
5228  that will be passed to possible `async_hooks` [`init` hooks][] and can be
5229  accessed by [`async_hooks.executionAsyncResource()`][].
5230* `[in] async_resource_name`: Identifier for the kind of resource that is being
5231  provided for diagnostic information exposed by the `async_hooks` API.
5232* `[out] result`: The initialized async context.
5233
5234Returns `napi_ok` if the API succeeded.
5235
5236The `async_resource` object needs to be kept alive until
5237[`napi_async_destroy`][] to keep `async_hooks` related API acts correctly. In
5238order to retain ABI compatibility with previous versions, `napi_async_context`s
5239are not maintaining the strong reference to the `async_resource` objects to
5240avoid introducing causing memory leaks. However, if the `async_resource` is
5241garbage collected by JavaScript engine before the `napi_async_context` was
5242destroyed by `napi_async_destroy`, calling `napi_async_context` related APIs
5243like [`napi_open_callback_scope`][] and [`napi_make_callback`][] can cause
5244problems like loss of async context when using the `AsyncLocalStoage` API.
5245
5246In order to retain ABI compatibility with previous versions, passing `NULL`
5247for `async_resource` does not result in an error. However, this is not
5248recommended as this will result poor results with  `async_hooks`
5249[`init` hooks][] and `async_hooks.executionAsyncResource()` as the resource is
5250now required by the underlying `async_hooks` implementation in order to provide
5251the linkage between async callbacks.
5252
5253### napi_async_destroy
5254<!-- YAML
5255added: v8.6.0
5256napiVersion: 1
5257-->
5258
5259```c
5260napi_status napi_async_destroy(napi_env env,
5261                               napi_async_context async_context);
5262```
5263
5264* `[in] env`: The environment that the API is invoked under.
5265* `[in] async_context`: The async context to be destroyed.
5266
5267Returns `napi_ok` if the API succeeded.
5268
5269This API can be called even if there is a pending JavaScript exception.
5270
5271### napi_make_callback
5272<!-- YAML
5273added: v8.0.0
5274napiVersion: 1
5275changes:
5276  - version: v8.6.0
5277    pr-url: https://github.com/nodejs/node/pull/15189
5278    description: Added `async_context` parameter.
5279-->
5280
5281```c
5282NAPI_EXTERN napi_status napi_make_callback(napi_env env,
5283                                           napi_async_context async_context,
5284                                           napi_value recv,
5285                                           napi_value func,
5286                                           size_t argc,
5287                                           const napi_value* argv,
5288                                           napi_value* result);
5289```
5290
5291* `[in] env`: The environment that the API is invoked under.
5292* `[in] async_context`: Context for the async operation that is
5293   invoking the callback. This should normally be a value previously
5294   obtained from [`napi_async_init`][].
5295   In order to retain ABI compatibility with previous versions, passing `NULL`
5296   for `async_context` does not result in an error. However, this results
5297   in incorrect operation of async hooks. Potential issues include loss of
5298   async context when using the `AsyncLocalStorage` API.
5299* `[in] recv`: The `this` value passed to the called function.
5300* `[in] func`: `napi_value` representing the JavaScript function to be invoked.
5301* `[in] argc`: The count of elements in the `argv` array.
5302* `[in] argv`: Array of JavaScript values as `napi_value` representing the
5303  arguments to the function.
5304* `[out] result`: `napi_value` representing the JavaScript object returned.
5305
5306Returns `napi_ok` if the API succeeded.
5307
5308This method allows a JavaScript function object to be called from a native
5309add-on. This API is similar to `napi_call_function`. However, it is used to call
5310*from* native code back *into* JavaScript *after* returning from an async
5311operation (when there is no other script on the stack). It is a fairly simple
5312wrapper around `node::MakeCallback`.
5313
5314Note it is *not* necessary to use `napi_make_callback` from within a
5315`napi_async_complete_callback`; in that situation the callback's async
5316context has already been set up, so a direct call to `napi_call_function`
5317is sufficient and appropriate. Use of the `napi_make_callback` function
5318may be required when implementing custom async behavior that does not use
5319`napi_create_async_work`.
5320
5321Any `process.nextTick`s or Promises scheduled on the microtask queue by
5322JavaScript during the callback are ran before returning back to C/C++.
5323
5324### napi_open_callback_scope
5325<!-- YAML
5326added: v9.6.0
5327napiVersion: 3
5328-->
5329
5330```c
5331NAPI_EXTERN napi_status napi_open_callback_scope(napi_env env,
5332                                                 napi_value resource_object,
5333                                                 napi_async_context context,
5334                                                 napi_callback_scope* result)
5335```
5336
5337* `[in] env`: The environment that the API is invoked under.
5338* `[in] resource_object`: An object associated with the async work
5339  that will be passed to possible `async_hooks` [`init` hooks][]. This
5340  parameter has been deprecated and is ignored at runtime. Use the
5341  `async_resource` parameter in [`napi_async_init`][] instead.
5342* `[in] context`: Context for the async operation that is invoking the callback.
5343  This should be a value previously obtained from [`napi_async_init`][].
5344* `[out] result`: The newly created scope.
5345
5346There are cases (for example, resolving promises) where it is
5347necessary to have the equivalent of the scope associated with a callback
5348in place when making certain Node-API calls. If there is no other script on
5349the stack the [`napi_open_callback_scope`][] and
5350[`napi_close_callback_scope`][] functions can be used to open/close
5351the required scope.
5352
5353### napi_close_callback_scope
5354<!-- YAML
5355added: v9.6.0
5356napiVersion: 3
5357-->
5358
5359```c
5360NAPI_EXTERN napi_status napi_close_callback_scope(napi_env env,
5361                                                  napi_callback_scope scope)
5362```
5363
5364* `[in] env`: The environment that the API is invoked under.
5365* `[in] scope`: The scope to be closed.
5366
5367This API can be called even if there is a pending JavaScript exception.
5368
5369## Version management
5370
5371### napi_get_node_version
5372<!-- YAML
5373added: v8.4.0
5374napiVersion: 1
5375-->
5376
5377```c
5378typedef struct {
5379  uint32_t major;
5380  uint32_t minor;
5381  uint32_t patch;
5382  const char* release;
5383} napi_node_version;
5384
5385napi_status napi_get_node_version(napi_env env,
5386                                  const napi_node_version** version);
5387```
5388
5389* `[in] env`: The environment that the API is invoked under.
5390* `[out] version`: A pointer to version information for Node.js itself.
5391
5392Returns `napi_ok` if the API succeeded.
5393
5394This function fills the `version` struct with the major, minor, and patch
5395version of Node.js that is currently running, and the `release` field with the
5396value of [`process.release.name`][`process.release`].
5397
5398The returned buffer is statically allocated and does not need to be freed.
5399
5400### napi_get_version
5401<!-- YAML
5402added: v8.0.0
5403napiVersion: 1
5404-->
5405
5406```c
5407napi_status napi_get_version(napi_env env,
5408                             uint32_t* result);
5409```
5410
5411* `[in] env`: The environment that the API is invoked under.
5412* `[out] result`: The highest version of Node-API supported.
5413
5414Returns `napi_ok` if the API succeeded.
5415
5416This API returns the highest Node-API version supported by the
5417Node.js runtime. Node-API is planned to be additive such that
5418newer releases of Node.js may support additional API functions.
5419In order to allow an addon to use a newer function when running with
5420versions of Node.js that support it, while providing
5421fallback behavior when running with Node.js versions that don't
5422support it:
5423
5424* Call `napi_get_version()` to determine if the API is available.
5425* If available, dynamically load a pointer to the function using `uv_dlsym()`.
5426* Use the dynamically loaded pointer to invoke the function.
5427* If the function is not available, provide an alternate implementation
5428  that does not use the function.
5429
5430## Memory management
5431
5432### napi_adjust_external_memory
5433<!-- YAML
5434added: v8.5.0
5435napiVersion: 1
5436-->
5437
5438```c
5439NAPI_EXTERN napi_status napi_adjust_external_memory(napi_env env,
5440                                                    int64_t change_in_bytes,
5441                                                    int64_t* result);
5442```
5443
5444* `[in] env`: The environment that the API is invoked under.
5445* `[in] change_in_bytes`: The change in externally allocated memory that is kept
5446  alive by JavaScript objects.
5447* `[out] result`: The adjusted value
5448
5449Returns `napi_ok` if the API succeeded.
5450
5451This function gives V8 an indication of the amount of externally allocated
5452memory that is kept alive by JavaScript objects (i.e. a JavaScript object
5453that points to its own memory allocated by a native module). Registering
5454externally allocated memory will trigger global garbage collections more
5455often than it would otherwise.
5456
5457## Promises
5458
5459Node-API provides facilities for creating `Promise` objects as described in
5460[Section 25.4][] of the ECMA specification. It implements promises as a pair of
5461objects. When a promise is created by `napi_create_promise()`, a "deferred"
5462object is created and returned alongside the `Promise`. The deferred object is
5463bound to the created `Promise` and is the only means to resolve or reject the
5464`Promise` using `napi_resolve_deferred()` or `napi_reject_deferred()`. The
5465deferred object that is created by `napi_create_promise()` is freed by
5466`napi_resolve_deferred()` or `napi_reject_deferred()`. The `Promise` object may
5467be returned to JavaScript where it can be used in the usual fashion.
5468
5469For example, to create a promise and pass it to an asynchronous worker:
5470
5471```c
5472napi_deferred deferred;
5473napi_value promise;
5474napi_status status;
5475
5476// Create the promise.
5477status = napi_create_promise(env, &deferred, &promise);
5478if (status != napi_ok) return NULL;
5479
5480// Pass the deferred to a function that performs an asynchronous action.
5481do_something_asynchronous(deferred);
5482
5483// Return the promise to JS
5484return promise;
5485```
5486
5487The above function `do_something_asynchronous()` would perform its asynchronous
5488action and then it would resolve or reject the deferred, thereby concluding the
5489promise and freeing the deferred:
5490
5491```c
5492napi_deferred deferred;
5493napi_value undefined;
5494napi_status status;
5495
5496// Create a value with which to conclude the deferred.
5497status = napi_get_undefined(env, &undefined);
5498if (status != napi_ok) return NULL;
5499
5500// Resolve or reject the promise associated with the deferred depending on
5501// whether the asynchronous action succeeded.
5502if (asynchronous_action_succeeded) {
5503  status = napi_resolve_deferred(env, deferred, undefined);
5504} else {
5505  status = napi_reject_deferred(env, deferred, undefined);
5506}
5507if (status != napi_ok) return NULL;
5508
5509// At this point the deferred has been freed, so we should assign NULL to it.
5510deferred = NULL;
5511```
5512
5513### napi_create_promise
5514<!-- YAML
5515added: v8.5.0
5516napiVersion: 1
5517-->
5518
5519```c
5520napi_status napi_create_promise(napi_env env,
5521                                napi_deferred* deferred,
5522                                napi_value* promise);
5523```
5524
5525* `[in] env`: The environment that the API is invoked under.
5526* `[out] deferred`: A newly created deferred object which can later be passed to
5527  `napi_resolve_deferred()` or `napi_reject_deferred()` to resolve resp. reject
5528  the associated promise.
5529* `[out] promise`: The JavaScript promise associated with the deferred object.
5530
5531Returns `napi_ok` if the API succeeded.
5532
5533This API creates a deferred object and a JavaScript promise.
5534
5535### napi_resolve_deferred
5536<!-- YAML
5537added: v8.5.0
5538napiVersion: 1
5539-->
5540
5541```c
5542napi_status napi_resolve_deferred(napi_env env,
5543                                  napi_deferred deferred,
5544                                  napi_value resolution);
5545```
5546
5547* `[in] env`: The environment that the API is invoked under.
5548* `[in] deferred`: The deferred object whose associated promise to resolve.
5549* `[in] resolution`: The value with which to resolve the promise.
5550
5551This API resolves a JavaScript promise by way of the deferred object
5552with which it is associated. Thus, it can only be used to resolve JavaScript
5553promises for which the corresponding deferred object is available. This
5554effectively means that the promise must have been created using
5555`napi_create_promise()` and the deferred object returned from that call must
5556have been retained in order to be passed to this API.
5557
5558The deferred object is freed upon successful completion.
5559
5560### napi_reject_deferred
5561<!-- YAML
5562added: v8.5.0
5563napiVersion: 1
5564-->
5565
5566```c
5567napi_status napi_reject_deferred(napi_env env,
5568                                 napi_deferred deferred,
5569                                 napi_value rejection);
5570```
5571
5572* `[in] env`: The environment that the API is invoked under.
5573* `[in] deferred`: The deferred object whose associated promise to resolve.
5574* `[in] rejection`: The value with which to reject the promise.
5575
5576This API rejects a JavaScript promise by way of the deferred object
5577with which it is associated. Thus, it can only be used to reject JavaScript
5578promises for which the corresponding deferred object is available. This
5579effectively means that the promise must have been created using
5580`napi_create_promise()` and the deferred object returned from that call must
5581have been retained in order to be passed to this API.
5582
5583The deferred object is freed upon successful completion.
5584
5585### napi_is_promise
5586<!-- YAML
5587added: v8.5.0
5588napiVersion: 1
5589-->
5590
5591```c
5592napi_status napi_is_promise(napi_env env,
5593                            napi_value value,
5594                            bool* is_promise);
5595```
5596
5597* `[in] env`: The environment that the API is invoked under.
5598* `[in] value`: The value to examine
5599* `[out] is_promise`: Flag indicating whether `promise` is a native promise
5600  object (that is, a promise object created by the underlying engine).
5601
5602## Script execution
5603
5604Node-API provides an API for executing a string containing JavaScript using the
5605underlying JavaScript engine.
5606
5607### napi_run_script
5608<!-- YAML
5609added: v8.5.0
5610napiVersion: 1
5611-->
5612
5613```c
5614NAPI_EXTERN napi_status napi_run_script(napi_env env,
5615                                        napi_value script,
5616                                        napi_value* result);
5617```
5618
5619* `[in] env`: The environment that the API is invoked under.
5620* `[in] script`: A JavaScript string containing the script to execute.
5621* `[out] result`: The value resulting from having executed the script.
5622
5623This function executes a string of JavaScript code and returns its result with
5624the following caveats:
5625
5626* Unlike `eval`, this function does not allow the script to access the current
5627  lexical scope, and therefore also does not allow to access the
5628  [module scope][], meaning that pseudo-globals such as `require` will not be
5629  available.
5630* The script can access the [global scope][]. Function and `var` declarations
5631  in the script will be added to the [`global`][] object. Variable declarations
5632  made using `let` and `const` will be visible globally, but will not be added
5633  to the [`global`][] object.
5634* The value of `this` is [`global`][] within the script.
5635
5636## libuv event loop
5637
5638Node-API provides a function for getting the current event loop associated with
5639a specific `napi_env`.
5640
5641### napi_get_uv_event_loop
5642<!-- YAML
5643added:
5644  - v9.3.0
5645  - v8.10.0
5646napiVersion: 2
5647-->
5648
5649```c
5650NAPI_EXTERN napi_status napi_get_uv_event_loop(napi_env env,
5651                                               struct uv_loop_s** loop);
5652```
5653
5654* `[in] env`: The environment that the API is invoked under.
5655* `[out] loop`: The current libuv loop instance.
5656
5657## Asynchronous thread-safe function calls
5658
5659JavaScript functions can normally only be called from a native addon's main
5660thread. If an addon creates additional threads, then Node-API functions that
5661require a `napi_env`, `napi_value`, or `napi_ref` must not be called from those
5662threads.
5663
5664When an addon has additional threads and JavaScript functions need to be invoked
5665based on the processing completed by those threads, those threads must
5666communicate with the addon's main thread so that the main thread can invoke the
5667JavaScript function on their behalf. The thread-safe function APIs provide an
5668easy way to do this.
5669
5670These APIs provide the type `napi_threadsafe_function` as well as APIs to
5671create, destroy, and call objects of this type.
5672`napi_create_threadsafe_function()` creates a persistent reference to a
5673`napi_value` that holds a JavaScript function which can be called from multiple
5674threads. The calls happen asynchronously. This means that values with which the
5675JavaScript callback is to be called will be placed in a queue, and, for each
5676value in the queue, a call will eventually be made to the JavaScript function.
5677
5678Upon creation of a `napi_threadsafe_function` a `napi_finalize` callback can be
5679provided. This callback will be invoked on the main thread when the thread-safe
5680function is about to be destroyed. It receives the context and the finalize data
5681given during construction, and provides an opportunity for cleaning up after the
5682threads e.g. by calling `uv_thread_join()`. **Aside from the main loop thread,
5683no threads should be using the thread-safe function after the finalize callback
5684completes.**
5685
5686The `context` given during the call to `napi_create_threadsafe_function()` can
5687be retrieved from any thread with a call to
5688`napi_get_threadsafe_function_context()`.
5689
5690### Calling a thread-safe function
5691
5692`napi_call_threadsafe_function()` can be used for initiating a call into
5693JavaScript. `napi_call_threadsafe_function()` accepts a parameter which controls
5694whether the API behaves blockingly. If set to `napi_tsfn_nonblocking`, the API
5695behaves non-blockingly, returning `napi_queue_full` if the queue was full,
5696preventing data from being successfully added to the queue. If set to
5697`napi_tsfn_blocking`, the API blocks until space becomes available in the queue.
5698`napi_call_threadsafe_function()` never blocks if the thread-safe function was
5699created with a maximum queue size of 0.
5700
5701`napi_call_threadsafe_function()` should not be called with `napi_tsfn_blocking`
5702from a JavaScript thread, because, if the queue is full, it may cause the
5703JavaScript thread to deadlock.
5704
5705The actual call into JavaScript is controlled by the callback given via the
5706`call_js_cb` parameter. `call_js_cb` is invoked on the main thread once for each
5707value that was placed into the queue by a successful call to
5708`napi_call_threadsafe_function()`. If such a callback is not given, a default
5709callback will be used, and the resulting JavaScript call will have no arguments.
5710The `call_js_cb` callback receives the JavaScript function to call as a
5711`napi_value` in its parameters, as well as the `void*` context pointer used when
5712creating the `napi_threadsafe_function`, and the next data pointer that was
5713created by one of the secondary threads. The callback can then use an API such
5714as `napi_call_function()` to call into JavaScript.
5715
5716The callback may also be invoked with `env` and `call_js_cb` both set to `NULL`
5717to indicate that calls into JavaScript are no longer possible, while items
5718remain in the queue that may need to be freed. This normally occurs when the
5719Node.js process exits while there is a thread-safe function still active.
5720
5721It is not necessary to call into JavaScript via `napi_make_callback()` because
5722Node-API runs `call_js_cb` in a context appropriate for callbacks.
5723
5724### Reference counting of thread-safe functions
5725
5726Threads can be added to and removed from a `napi_threadsafe_function` object
5727during its existence. Thus, in addition to specifying an initial number of
5728threads upon creation, `napi_acquire_threadsafe_function` can be called to
5729indicate that a new thread will start making use of the thread-safe function.
5730Similarly, `napi_release_threadsafe_function` can be called to indicate that an
5731existing thread will stop making use of the thread-safe function.
5732
5733`napi_threadsafe_function` objects are destroyed when every thread which uses
5734the object has called `napi_release_threadsafe_function()` or has received a
5735return status of `napi_closing` in response to a call to
5736`napi_call_threadsafe_function`. The queue is emptied before the
5737`napi_threadsafe_function` is destroyed. `napi_release_threadsafe_function()`
5738should be the last API call made in conjunction with a given
5739`napi_threadsafe_function`, because after the call completes, there is no
5740guarantee that the `napi_threadsafe_function` is still allocated. For the same
5741reason, do not use a thread-safe function
5742after receiving a return value of `napi_closing` in response to a call to
5743`napi_call_threadsafe_function`. Data associated with the
5744`napi_threadsafe_function` can be freed in its `napi_finalize` callback which
5745was passed to `napi_create_threadsafe_function()`. The parameter
5746`initial_thread_count` of `napi_create_threadsafe_function` marks the initial
5747number of aquisitions of the thread-safe functions, instead of calling
5748`napi_acquire_threadsafe_function` multiple times at creation.
5749
5750Once the number of threads making use of a `napi_threadsafe_function` reaches
5751zero, no further threads can start making use of it by calling
5752`napi_acquire_threadsafe_function()`. In fact, all subsequent API calls
5753associated with it, except `napi_release_threadsafe_function()`, will return an
5754error value of `napi_closing`.
5755
5756The thread-safe function can be "aborted" by giving a value of `napi_tsfn_abort`
5757to `napi_release_threadsafe_function()`. This will cause all subsequent APIs
5758associated with the thread-safe function except
5759`napi_release_threadsafe_function()` to return `napi_closing` even before its
5760reference count reaches zero. In particular, `napi_call_threadsafe_function()`
5761will return `napi_closing`, thus informing the threads that it is no longer
5762possible to make asynchronous calls to the thread-safe function. This can be
5763used as a criterion for terminating the thread. **Upon receiving a return value
5764of `napi_closing` from `napi_call_threadsafe_function()` a thread must not use
5765the thread-safe function anymore because it is no longer guaranteed to
5766be allocated.**
5767
5768### Deciding whether to keep the process running
5769
5770Similarly to libuv handles, thread-safe functions can be "referenced" and
5771"unreferenced". A "referenced" thread-safe function will cause the event loop on
5772the thread on which it is created to remain alive until the thread-safe function
5773is destroyed. In contrast, an "unreferenced" thread-safe function will not
5774prevent the event loop from exiting. The APIs `napi_ref_threadsafe_function` and
5775`napi_unref_threadsafe_function` exist for this purpose.
5776
5777Neither does `napi_unref_threadsafe_function` mark the thread-safe functions as
5778able to be destroyed nor does `napi_ref_threadsafe_function` prevent it from
5779being destroyed.
5780
5781### napi_create_threadsafe_function
5782
5783<!-- YAML
5784added: v10.6.0
5785napiVersion: 4
5786changes:
5787  - version:
5788     - v12.6.0
5789     - v10.17.0
5790    pr-url: https://github.com/nodejs/node/pull/27791
5791    description: Made `func` parameter optional with custom `call_js_cb`.
5792-->
5793
5794```c
5795NAPI_EXTERN napi_status
5796napi_create_threadsafe_function(napi_env env,
5797                                napi_value func,
5798                                napi_value async_resource,
5799                                napi_value async_resource_name,
5800                                size_t max_queue_size,
5801                                size_t initial_thread_count,
5802                                void* thread_finalize_data,
5803                                napi_finalize thread_finalize_cb,
5804                                void* context,
5805                                napi_threadsafe_function_call_js call_js_cb,
5806                                napi_threadsafe_function* result);
5807```
5808
5809* `[in] env`: The environment that the API is invoked under.
5810* `[in] func`: An optional JavaScript function to call from another thread. It
5811  must be provided if `NULL` is passed to `call_js_cb`.
5812* `[in] async_resource`: An optional object associated with the async work that
5813  will be passed to possible `async_hooks` [`init` hooks][].
5814* `[in] async_resource_name`: A JavaScript string to provide an identifier for
5815  the kind of resource that is being provided for diagnostic information exposed
5816  by the `async_hooks` API.
5817* `[in] max_queue_size`: Maximum size of the queue. `0` for no limit.
5818* `[in] initial_thread_count`: The initial number of acquisitions, i.e. the
5819  initial number of threads, including the main thread, which will be making use
5820  of this function.
5821* `[in] thread_finalize_data`: Optional data to be passed to `thread_finalize_cb`.
5822* `[in] thread_finalize_cb`: Optional function to call when the
5823  `napi_threadsafe_function` is being destroyed.
5824* `[in] context`: Optional data to attach to the resulting
5825  `napi_threadsafe_function`.
5826* `[in] call_js_cb`: Optional callback which calls the JavaScript function in
5827  response to a call on a different thread. This callback will be called on the
5828  main thread. If not given, the JavaScript function will be called with no
5829  parameters and with `undefined` as its `this` value.
5830  [`napi_threadsafe_function_call_js`][] provides more details.
5831* `[out] result`: The asynchronous thread-safe JavaScript function.
5832
5833### napi_get_threadsafe_function_context
5834
5835<!-- YAML
5836added: v10.6.0
5837napiVersion: 4
5838-->
5839
5840```c
5841NAPI_EXTERN napi_status
5842napi_get_threadsafe_function_context(napi_threadsafe_function func,
5843                                     void** result);
5844```
5845
5846* `[in] func`: The thread-safe function for which to retrieve the context.
5847* `[out] result`: The location where to store the context.
5848
5849This API may be called from any thread which makes use of `func`.
5850
5851### napi_call_threadsafe_function
5852
5853<!-- YAML
5854added: v10.6.0
5855napiVersion: 4
5856changes:
5857  - version: v14.5.0
5858    pr-url: https://github.com/nodejs/node/pull/33453
5859    description: Support for `napi_would_deadlock` has been reverted.
5860  - version: v14.1.0
5861    pr-url: https://github.com/nodejs/node/pull/32689
5862    description: Return `napi_would_deadlock` when called with
5863                 `napi_tsfn_blocking` from the main thread or a worker thread
5864                 and the queue is full.
5865-->
5866
5867```c
5868NAPI_EXTERN napi_status
5869napi_call_threadsafe_function(napi_threadsafe_function func,
5870                              void* data,
5871                              napi_threadsafe_function_call_mode is_blocking);
5872```
5873
5874* `[in] func`: The asynchronous thread-safe JavaScript function to invoke.
5875* `[in] data`: Data to send into JavaScript via the callback `call_js_cb`
5876  provided during the creation of the thread-safe JavaScript function.
5877* `[in] is_blocking`: Flag whose value can be either `napi_tsfn_blocking` to
5878  indicate that the call should block if the queue is full or
5879  `napi_tsfn_nonblocking` to indicate that the call should return immediately
5880  with a status of `napi_queue_full` whenever the queue is full.
5881
5882This API should not be called with `napi_tsfn_blocking` from a JavaScript
5883thread, because, if the queue is full, it may cause the JavaScript thread to
5884deadlock.
5885
5886This API will return `napi_closing` if `napi_release_threadsafe_function()` was
5887called with `abort` set to `napi_tsfn_abort` from any thread. The value is only
5888added to the queue if the API returns `napi_ok`.
5889
5890This API may be called from any thread which makes use of `func`.
5891
5892### napi_acquire_threadsafe_function
5893
5894<!-- YAML
5895added: v10.6.0
5896napiVersion: 4
5897-->
5898
5899```c
5900NAPI_EXTERN napi_status
5901napi_acquire_threadsafe_function(napi_threadsafe_function func);
5902```
5903
5904* `[in] func`: The asynchronous thread-safe JavaScript function to start making
5905  use of.
5906
5907A thread should call this API before passing `func` to any other thread-safe
5908function APIs to indicate that it will be making use of `func`. This prevents
5909`func` from being destroyed when all other threads have stopped making use of
5910it.
5911
5912This API may be called from any thread which will start making use of `func`.
5913
5914### napi_release_threadsafe_function
5915
5916<!-- YAML
5917added: v10.6.0
5918napiVersion: 4
5919-->
5920
5921```c
5922NAPI_EXTERN napi_status
5923napi_release_threadsafe_function(napi_threadsafe_function func,
5924                                 napi_threadsafe_function_release_mode mode);
5925```
5926
5927* `[in] func`: The asynchronous thread-safe JavaScript function whose reference
5928  count to decrement.
5929* `[in] mode`: Flag whose value can be either `napi_tsfn_release` to indicate
5930  that the current thread will make no further calls to the thread-safe
5931  function, or `napi_tsfn_abort` to indicate that in addition to the current
5932  thread, no other thread should make any further calls to the thread-safe
5933  function. If set to `napi_tsfn_abort`, further calls to
5934  `napi_call_threadsafe_function()` will return `napi_closing`, and no further
5935  values will be placed in the queue.
5936
5937A thread should call this API when it stops making use of `func`. Passing `func`
5938to any thread-safe APIs after having called this API has undefined results, as
5939`func` may have been destroyed.
5940
5941This API may be called from any thread which will stop making use of `func`.
5942
5943### napi_ref_threadsafe_function
5944
5945<!-- YAML
5946added: v10.6.0
5947napiVersion: 4
5948-->
5949
5950```c
5951NAPI_EXTERN napi_status
5952napi_ref_threadsafe_function(napi_env env, napi_threadsafe_function func);
5953```
5954
5955* `[in] env`: The environment that the API is invoked under.
5956* `[in] func`: The thread-safe function to reference.
5957
5958This API is used to indicate that the event loop running on the main thread
5959should not exit until `func` has been destroyed. Similar to [`uv_ref`][] it is
5960also idempotent.
5961
5962Neither does `napi_unref_threadsafe_function` mark the thread-safe functions as
5963able to be destroyed nor does `napi_ref_threadsafe_function` prevent it from
5964being destroyed. `napi_acquire_threadsafe_function` and
5965`napi_release_threadsafe_function` are available for that purpose.
5966
5967This API may only be called from the main thread.
5968
5969### napi_unref_threadsafe_function
5970
5971<!-- YAML
5972added: v10.6.0
5973napiVersion: 4
5974-->
5975
5976```c
5977NAPI_EXTERN napi_status
5978napi_unref_threadsafe_function(napi_env env, napi_threadsafe_function func);
5979```
5980
5981* `[in] env`: The environment that the API is invoked under.
5982* `[in] func`: The thread-safe function to unreference.
5983
5984This API is used to indicate that the event loop running on the main thread
5985may exit before `func` is destroyed. Similar to [`uv_unref`][] it is also
5986idempotent.
5987
5988This API may only be called from the main thread.
5989
5990## Miscellaneous utilities
5991
5992## node_api_get_module_file_name
5993
5994<!-- YAML
5995added: v14.18.0
5996-->
5997
5998> Stability: 1 - Experimental
5999
6000```c
6001NAPI_EXTERN napi_status
6002node_api_get_module_file_name(napi_env env, const char** result);
6003
6004```
6005
6006* `[in] env`: The environment that the API is invoked under.
6007* `[out] result`: A URL containing the absolute path of the
6008  location from which the add-on was loaded. For a file on the local
6009  file system it will start with `file://`. The string is null-terminated and
6010  owned by `env` and must thus not be modified or freed.
6011
6012`result` may be an empty string if the add-on loading process fails to establish
6013the add-on's file name during loading.
6014
6015[ABI Stability]: https://nodejs.org/en/docs/guides/abi-stability/
6016[AppVeyor]: https://www.appveyor.com
6017[C++ Addons]: addons.md
6018[CMake]: https://cmake.org
6019[CMake.js]: https://github.com/cmake-js/cmake-js
6020[ECMAScript Language Specification]: https://tc39.github.io/ecma262/
6021[Error handling]: #n_api_error_handling
6022[GCC]: https://gcc.gnu.org
6023[GYP]: https://gyp.gsrc.io
6024[GitHub releases]: https://help.github.com/en/github/administering-a-repository/about-releases
6025[LLVM]: https://llvm.org
6026[Native Abstractions for Node.js]: https://github.com/nodejs/nan
6027[Object lifetime management]: #n_api_object_lifetime_management
6028[Object wrap]: #n_api_object_wrap
6029[Section 12.10.4]: https://tc39.github.io/ecma262/#sec-instanceofoperator
6030[Section 12.5.5]: https://tc39.github.io/ecma262/#sec-typeof-operator
6031[Section 19.2]: https://tc39.github.io/ecma262/#sec-function-objects
6032[Section 19.4]: https://tc39.github.io/ecma262/#sec-symbol-objects
6033[Section 20.3]: https://tc39.github.io/ecma262/#sec-date-objects
6034[Section 22.1]: https://tc39.github.io/ecma262/#sec-array-objects
6035[Section 22.1.4.1]: https://tc39.github.io/ecma262/#sec-properties-of-array-instances-length
6036[Section 22.2]: https://tc39.github.io/ecma262/#sec-typedarray-objects
6037[Section 24.1]: https://tc39.github.io/ecma262/#sec-arraybuffer-objects
6038[Section 24.1.1.2]: https://tc39.es/ecma262/#sec-isdetachedbuffer
6039[Section 24.1.1.3]: https://tc39.es/ecma262/#sec-detacharraybuffer
6040[Section 24.3]: https://tc39.github.io/ecma262/#sec-dataview-objects
6041[Section 25.4]: https://tc39.github.io/ecma262/#sec-promise-objects
6042[Section 6]: https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values
6043[Section 6.1]: https://tc39.github.io/ecma262/#sec-ecmascript-language-types
6044[Section 6.1.4]: https://tc39.github.io/ecma262/#sec-ecmascript-language-types-string-type
6045[Section 6.1.6]: https://tc39.github.io/ecma262/#sec-ecmascript-language-types-number-type
6046[Section 6.1.7]: https://tc39.github.io/ecma262/#sec-object-type
6047[Section 6.1.7.1]: https://tc39.github.io/ecma262/#table-2
6048[Section 7]: https://tc39.github.io/ecma262/#sec-abstract-operations
6049[Section 7.1.13]: https://tc39.github.io/ecma262/#sec-toobject
6050[Section 7.1.2]: https://tc39.github.io/ecma262/#sec-toboolean
6051[Section 7.1.3]: https://tc39.github.io/ecma262/#sec-tonumber
6052[Section 7.2.14]: https://tc39.github.io/ecma262/#sec-strict-equality-comparison
6053[Section 7.2.2]: https://tc39.github.io/ecma262/#sec-isarray
6054[Section 8.7]: https://tc39.es/ecma262/#sec-agents
6055[Section 9.1.6]: https://tc39.github.io/ecma262/#sec-ordinary-object-internal-methods-and-internal-slots-defineownproperty-p-desc
6056[Travis CI]: https://travis-ci.org
6057[Visual Studio]: https://visualstudio.microsoft.com
6058[Working with JavaScript properties]: #n_api_working_with_javascript_properties
6059[Xcode]: https://developer.apple.com/xcode/
6060[`Number.MAX_SAFE_INTEGER`]: https://tc39.github.io/ecma262/#sec-number.max_safe_integer
6061[`Number.MIN_SAFE_INTEGER`]: https://tc39.github.io/ecma262/#sec-number.min_safe_integer
6062[`Worker`]: worker_threads.md#worker_threads_class_worker
6063[`async_hooks.executionAsyncResource()`]: async_hooks.md#async_hooks_async_hooks_executionasyncresource
6064[`global`]: globals.md#globals_global
6065[`init` hooks]: async_hooks.md#async_hooks_init_asyncid_type_triggerasyncid_resource
6066[`napi_add_async_cleanup_hook`]: #n_api_napi_add_async_cleanup_hook
6067[`napi_add_env_cleanup_hook`]: #n_api_napi_add_env_cleanup_hook
6068[`napi_add_finalizer`]: #n_api_napi_add_finalizer
6069[`napi_async_cleanup_hook`]: #n_api_napi_async_cleanup_hook
6070[`napi_async_complete_callback`]: #n_api_napi_async_complete_callback
6071[`napi_async_destroy`]: #n_api_napi_async_destroy
6072[`napi_async_init`]: #n_api_napi_async_init
6073[`napi_callback`]: #n_api_napi_callback
6074[`napi_cancel_async_work`]: #n_api_napi_cancel_async_work
6075[`napi_close_callback_scope`]: #n_api_napi_close_callback_scope
6076[`napi_close_escapable_handle_scope`]: #n_api_napi_close_escapable_handle_scope
6077[`napi_close_handle_scope`]: #n_api_napi_close_handle_scope
6078[`napi_create_async_work`]: #n_api_napi_create_async_work
6079[`napi_create_error`]: #n_api_napi_create_error
6080[`napi_create_external_arraybuffer`]: #n_api_napi_create_external_arraybuffer
6081[`napi_create_range_error`]: #n_api_napi_create_range_error
6082[`napi_create_reference`]: #n_api_napi_create_reference
6083[`napi_create_type_error`]: #n_api_napi_create_type_error
6084[`napi_define_class`]: #n_api_napi_define_class
6085[`napi_delete_async_work`]: #n_api_napi_delete_async_work
6086[`napi_delete_reference`]: #n_api_napi_delete_reference
6087[`napi_escape_handle`]: #n_api_napi_escape_handle
6088[`napi_finalize`]: #n_api_napi_finalize
6089[`napi_get_and_clear_last_exception`]: #n_api_napi_get_and_clear_last_exception
6090[`napi_get_array_length`]: #n_api_napi_get_array_length
6091[`napi_get_element`]: #n_api_napi_get_element
6092[`napi_get_last_error_info`]: #n_api_napi_get_last_error_info
6093[`napi_get_property`]: #n_api_napi_get_property
6094[`napi_get_reference_value`]: #n_api_napi_get_reference_value
6095[`napi_get_value_external`]: #n_api_napi_get_value_external
6096[`napi_has_property`]: #n_api_napi_has_property
6097[`napi_instanceof`]: #n_api_napi_instanceof
6098[`napi_is_error`]: #n_api_napi_is_error
6099[`napi_is_exception_pending`]: #n_api_napi_is_exception_pending
6100[`napi_make_callback`]: #n_api_napi_make_callback
6101[`napi_open_callback_scope`]: #n_api_napi_open_callback_scope
6102[`napi_open_escapable_handle_scope`]: #n_api_napi_open_escapable_handle_scope
6103[`napi_open_handle_scope`]: #n_api_napi_open_handle_scope
6104[`napi_property_attributes`]: #n_api_napi_property_attributes
6105[`napi_property_descriptor`]: #n_api_napi_property_descriptor
6106[`napi_queue_async_work`]: #n_api_napi_queue_async_work
6107[`napi_reference_ref`]: #n_api_napi_reference_ref
6108[`napi_reference_unref`]: #n_api_napi_reference_unref
6109[`napi_remove_async_cleanup_hook`]: #n_api_napi_remove_async_cleanup_hook
6110[`napi_remove_env_cleanup_hook`]: #n_api_napi_remove_env_cleanup_hook
6111[`napi_set_instance_data`]: #n_api_napi_set_instance_data
6112[`napi_set_property`]: #n_api_napi_set_property
6113[`napi_threadsafe_function_call_js`]: #n_api_napi_threadsafe_function_call_js
6114[`napi_throw_error`]: #n_api_napi_throw_error
6115[`napi_throw_range_error`]: #n_api_napi_throw_range_error
6116[`napi_throw_type_error`]: #n_api_napi_throw_type_error
6117[`napi_throw`]: #n_api_napi_throw
6118[`napi_unwrap`]: #n_api_napi_unwrap
6119[`napi_wrap`]: #n_api_napi_wrap
6120[`node-addon-api`]: https://github.com/nodejs/node-addon-api
6121[`node_api.h`]: https://github.com/nodejs/node/blob/HEAD/src/node_api.h
6122[`process.release`]: process.md#process_process_release
6123[`uv_ref`]: https://docs.libuv.org/en/v1.x/handle.html#c.uv_ref
6124[`uv_unref`]: https://docs.libuv.org/en/v1.x/handle.html#c.uv_unref
6125[async_hooks `type`]: async_hooks.md#async_hooks_type
6126[context-aware addons]: addons.md#addons_context_aware_addons
6127[docs]: https://github.com/nodejs/node-addon-api#api-documentation
6128[global scope]: globals.md
6129[gyp-next]: https://github.com/nodejs/gyp-next
6130[module scope]: modules.md#modules_the_module_scope
6131[node-gyp]: https://github.com/nodejs/node-gyp
6132[node-pre-gyp]: https://github.com/mapbox/node-pre-gyp
6133[prebuild]: https://github.com/prebuild/prebuild
6134[prebuildify]: https://github.com/prebuild/prebuildify
6135[worker threads]: https://nodejs.org/api/worker_threads.html
6136