Repository navigation
Expand file tree
/
Copy pathn-api.md
More file actions
7100 lines (5537 loc) Β· 240 KB
/
Copy pathn-api.md
File metadata and controls
7100 lines (5537 loc) Β· 240 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
# Node-API
<!--introduced_in=v8.0.0-->
<!-- type=misc -->
> Stability: 2 - Stable
Node-API (formerly N-API) is an API for building native Addons. It is
independent from the underlying JavaScript runtime (for example, V8) and is
maintained as part of Node.js itself. This API will be Application Binary
Interface (ABI) stable across versions of Node.js. It is intended to insulate
addons from changes in the underlying JavaScript engine and allow modules
compiled for one major version to run on later major versions of Node.js without
recompilation. The [ABI Stability][] guide provides a more in-depth explanation.
Addons are built/packaged with the same approach/tools outlined in the section
titled [C++ Addons][]. The only difference is the set of APIs that are used by
the native code. Instead of using the V8 or [Native Abstractions for Node.js][]
APIs, the functions available in Node-API are used.
APIs exposed by Node-API are generally used to create and manipulate
JavaScript values. Concepts and operations generally map to ideas specified
in the ECMA-262 Language Specification. The APIs have the following
properties:
* All Node-API calls return a status code of type `napi_status`. This
status indicates whether the API call succeeded or failed.
* The API's return value is passed via an out parameter.
* All JavaScript values are abstracted behind an opaque type named
`napi_value`.
* In case of an error status code, additional information can be obtained
using `napi_get_last_error_info`. More information can be found in the error
handling section [Error handling][].
## Writing addons in various programming languages
Node-API is a C API that ensures ABI stability across Node.js versions
and different compiler levels. With this stability guarantee, it is possible
to write addons in other programming languages on top of Node-API. Refer
to [language and engine bindings][] for more programming languages and engines
support details.
[`node-addon-api`][] is the official C++ binding that provides a more efficient way to
write C++ code that calls Node-API. This wrapper is a header-only library that offers an inlinable C++ API.
Binaries built with `node-addon-api` will depend on the symbols of the Node-API
C-based functions exported by Node.js. The following code snippet is an example
of `node-addon-api`:
```cpp
Object obj = Object::New(env);
obj["foo"] = String::New(env, "bar");
```
The above `node-addon-api` C++ code is equivalent to the following C-based
Node-API code:
```cpp
napi_status status;
napi_value object, string;
status = napi_create_object(env, &object);
if (status != napi_ok) {
napi_throw_error(env, ...);
return;
}
status = napi_create_string_utf8(env, "bar", NAPI_AUTO_LENGTH, &string);
if (status != napi_ok) {
napi_throw_error(env, ...);
return;
}
status = napi_set_named_property(env, object, "foo", string);
if (status != napi_ok) {
napi_throw_error(env, ...);
return;
}
```
The end result is that the addon only uses the exported C APIs. Even though
the addon is written in C++, it still gets the benefits of the ABI stability
provided by the C Node-API.
When using `node-addon-api` instead of the C APIs, start with the API [docs][]
for `node-addon-api`.
The [Node-API Resource](https://nodejs.github.io/node-addon-examples/) offers
an excellent orientation and tips for developers just getting started with
Node-API and `node-addon-api`. Additional media resources can be found on the
[Node-API Media][] page.
## Implications of ABI stability
Although Node-API provides an ABI stability guarantee, other parts of Node.js do
not, and any external libraries used from the addon may not. In particular,
none of the following APIs provide an ABI stability guarantee across major
versions:
* the Node.js C++ APIs available via any of
```cpp
#include <node.h>
#include <node_buffer.h>
#include <node_version.h>
#include <node_object_wrap.h>
```
* the libuv APIs which are also included with Node.js and available via
```cpp
#include <uv.h>
```
* the V8 API available via
```cpp
#include <v8.h>
```
Thus, for an addon to remain ABI-compatible across Node.js major versions, it
must use Node-API exclusively by restricting itself to using
```c
#include <node_api.h>
```
and by checking, for all external libraries that it uses, that the external
library makes ABI stability guarantees similar to Node-API.
### Enum values in ABI stability
All enum data types defined in Node-API should be considered as a fixed size
`int32_t` value. Bit flag enum types should be explicitly documented, and they
work with bit operators like bit-OR (`|`) as a bit value. Unless otherwise
documented, an enum type should be considered to be extensible.
A new enum value will be added at the end of the enum definition. An enum value
will not be removed or renamed.
For an enum type returned from a Node-API function, or provided as an out
parameter of a Node-API function, the value is an integer value and an addon
should handle unknown values. New values are allowed to be introduced without
a version guard. For example, when checking `napi_status` in switch statements,
an addon should include a default branch, as new status codes may be introduced
in newer Node.js versions.
For an enum type used in an in-parameter, the result of passing an unknown
integer value to Node-API functions is undefined unless otherwise documented.
A new value is added with a version guard to indicate the Node-API version in
which it was introduced. For example, `napi_get_all_property_names` can be
extended with new enum value of `napi_key_filter`.
For an enum type used in both in-parameters and out-parameters, new values are
allowed to be introduced without a version guard.
## Building
Unlike modules written in JavaScript, developing and deploying Node.js
native addons using Node-API requires an additional set of tools. Besides the
basic tools required to develop for Node.js, the native addon developer
requires a toolchain that can compile C and C++ code into a binary. In
addition, depending upon how the native addon is deployed, the _user_ of
the native addon will also need to have a C/C++ toolchain installed.
For Linux developers, the necessary C/C++ toolchain packages are readily
available. [GCC][] is widely used in the Node.js community to build and
test across a variety of platforms. For many developers, the [LLVM][]
compiler infrastructure is also a good choice.
For Mac developers, [Xcode][] offers all the required compiler tools.
However, it is not necessary to install the entire Xcode IDE. The following
command installs the necessary toolchain:
```bash
xcode-select --install
```
For Windows developers, [Visual Studio][] offers all the required compiler
tools. However, it is not necessary to install the entire Visual Studio
IDE. The following command installs the necessary toolchain:
```bash
npm install --global windows-build-tools
```
The sections below describe the additional tools available for developing
and deploying Node.js native addons.
### Build tools
Both the tools listed here require that _users_ of the native
addon have a C/C++ toolchain installed in order to successfully install
the native addon.
#### node-gyp
[node-gyp][] is a build system based on the [gyp-next][] tool and comes bundled with npm.
node-gyp requires that Python be installed.
Historically, node-gyp has been the tool of choice for building native
addons. It has widespread adoption and documentation. However, some
developers have run into limitations in node-gyp.
#### CMake.js
[CMake.js][] is an alternative build system based on [CMake][].
CMake.js is a good choice for projects that already use CMake or for
developers affected by limitations in node-gyp. [`build_with_cmake`][] is an
example of a CMake-based native addon project.
### Uploading precompiled binaries
The three tools listed here permit native addon developers and maintainers
to create and upload binaries to public or private servers. These tools are
typically integrated with CI/CD build systems like [Travis CI][] and
[AppVeyor][] to build and upload binaries for a variety of platforms and
architectures. These binaries are then available for download by users who
do not need to have a C/C++ toolchain installed.
#### node-pre-gyp
[node-pre-gyp][] is a tool based on node-gyp that adds the ability to
upload binaries to a server of the developer's choice. node-pre-gyp has
particularly good support for uploading binaries to Amazon S3.
#### prebuild
[prebuild][] is a tool that supports builds using either node-gyp or
CMake.js. Unlike node-pre-gyp which supports a variety of servers, prebuild
uploads binaries only to [GitHub releases][]. prebuild is a good choice for
GitHub projects using CMake.js.
#### prebuildify
[prebuildify][] is a tool based on node-gyp. The advantage of prebuildify is
that the built binaries are bundled with the native addon when it's
uploaded to npm. The binaries are downloaded from npm and are immediately
available to the module user when the native addon is installed.
## Usage
In order to use the Node-API functions, include the file [`node_api.h`][] which
is located in the src directory in the node development tree:
```c
#include <node_api.h>
```
This will opt into the default `NAPI_VERSION` for the given release of Node.js.
In order to ensure compatibility with specific versions of Node-API, the version
can be specified explicitly when including the header:
```c
#define NAPI_VERSION 3
#include <node_api.h>
```
This restricts the Node-API surface to just the functionality that was available
in the specified (and earlier) versions.
Some of the Node-API surface is experimental and requires explicit opt-in:
```c
#define NAPI_EXPERIMENTAL
#include <node_api.h>
```
In this case the entire API surface, including any experimental APIs, will be
available to the module code.
Occasionally, experimental features are introduced that affect already-released
and stable APIs. These features can be disabled by an opt-out:
```c
#define NAPI_EXPERIMENTAL
#define NODE_API_EXPERIMENTAL_<FEATURE_NAME>_OPT_OUT
#include <node_api.h>
```
where `<FEATURE_NAME>` is the name of an experimental feature that affects both
experimental and stable APIs.
## Node-API version matrix
Up until version 9, Node-API versions were additive and versioned
independently from Node.js. This meant that any version was
an extension to the previous version in that it had all of
the APIs from the previous version with some additions. Each
Node.js version only supported a single Node-API version.
For example v18.15.0 supports only Node-API version 8. ABI stability was
achieved because 8 was a strict superset of all previous versions.
As of version 9, while Node-API versions continue to be versioned
independently, an add-on that ran with Node-API version 9 may need
code updates to run with Node-API version 10. ABI stability
is maintained, however, because Node.js versions that support
Node-API versions higher than 8 will support all versions
between 8 and the highest version they support and will default
to providing the version 8 APIs unless an add-on opts into a
higher Node-API version. This approach provides the flexibility
of better optimizing existing Node-API functions while
maintaining ABI stability. Existing add-ons can continue to run without
recompilation using an earlier version of Node-API. If an add-on
needs functionality from a newer Node-API version, changes to existing
code and recompilation will be needed to use those new functions anyway.
In versions of Node.js that support Node-API version 9 and later, defining
`NAPI_VERSION=X` and using the existing add-on initialization macros
will bake in the requested Node-API version that will be used at runtime
into the add-on. If `NAPI_VERSION` is not set it will default to 8.
This table may not be up to date in older streams, the most up to date
information is in the latest API documentation in:
[Node-API version matrix](https://nodejs.org/docs/latest/api/n-api.html#node-api-version-matrix)
<!-- For accessibility purposes, this table needs row headers. That means we
can't do it in markdown. Hence, the raw HTML. -->
<table>
<tr>
<th>Node-API version</th>
<th scope="col">Supported In</th>
</tr>
<tr>
<th scope="row">10</th>
<td>v22.14.0+, 23.6.0+ and all later versions</td>
</tr>
<tr>
<th scope="row">9</th>
<td>v18.17.0+, 20.3.0+, 21.0.0 and all later versions</td>
</tr>
<tr>
<th scope="row">8</th>
<td>v12.22.0+, v14.17.0+, v15.12.0+, 16.0.0 and all later versions</td>
</tr>
<tr>
<th scope="row">7</th>
<td>v10.23.0+, v12.19.0+, v14.12.0+, 15.0.0 and all later versions</td>
</tr>
<tr>
<th scope="row">6</th>
<td>v10.20.0+, v12.17.0+, 14.0.0 and all later versions</td>
</tr>
<tr>
<th scope="row">5</th>
<td>v10.17.0+, v12.11.0+, 13.0.0 and all later versions</td>
</tr>
<tr>
<th scope="row">4</th>
<td>v10.16.0+, v11.8.0+, 12.0.0 and all later versions</td>
</tr>
</tr>
<tr>
<th scope="row">3</th>
<td>v6.14.2*, 8.11.2+, v9.11.0+*, 10.0.0 and all later versions</td>
</tr>
<tr>
<th scope="row">2</th>
<td>v8.10.0+*, v9.3.0+*, 10.0.0 and all later versions</td>
</tr>
<tr>
<th scope="row">1</th>
<td>v8.6.0+**, v9.0.0+*, 10.0.0 and all later versions</td>
</tr>
</table>
\* Node-API was experimental.
\*\* Node.js 8.0.0 included Node-API as experimental. It was released as
Node-API version 1 but continued to evolve until Node.js 8.6.0. The API is
different in versions prior to Node.js 8.6.0. We recommend Node-API version 3 or
later.
Each API documented for Node-API will have a header named `added in:`, and APIs
which are stable will have the additional header `Node-API version:`.
APIs are directly usable when using a Node.js version which supports
the Node-API version shown in `Node-API version:` or higher.
When using a Node.js version that does not support the
`Node-API version:` listed or if there is no `Node-API version:` listed,
then the API will only be available if
`#define NAPI_EXPERIMENTAL` precedes the inclusion of `node_api.h`
or `js_native_api.h`. If an API appears not to be available on
a version of Node.js which is later than the one shown in `added in:` then
this is most likely the reason for the apparent absence.
The Node-APIs associated strictly with accessing ECMAScript features from native
code can be found separately in `js_native_api.h` and `js_native_api_types.h`.
The APIs defined in these headers are included in `node_api.h` and
`node_api_types.h`. The headers are structured in this way in order to allow
implementations of Node-API outside of Node.js. For those implementations the
Node.js specific APIs may not be applicable.
The Node.js-specific parts of an addon can be separated from the code that
exposes the actual functionality to the JavaScript environment so that the
latter may be used with multiple implementations of Node-API. In the example
below, `addon.c` and `addon.h` refer only to `js_native_api.h`. This ensures
that `addon.c` can be reused to compile against either the Node.js
implementation of Node-API or any implementation of Node-API outside of Node.js.
`addon_node.c` is a separate file that contains the Node.js specific entry point
to the addon and which instantiates the addon by calling into `addon.c` when the
addon is loaded into a Node.js environment.
```c
// addon.h
#ifndef _ADDON_H_
#define _ADDON_H_
#include <js_native_api.h>
napi_value create_addon(napi_env env);
#endif // _ADDON_H_
```
```c
// addon.c
#include "addon.h"
#define NODE_API_CALL(env, call) \
do { \
napi_status status = (call); \
if (status != napi_ok) { \
const napi_extended_error_info* error_info = NULL; \
napi_get_last_error_info((env), &error_info); \
const char* err_message = error_info->error_message; \
bool is_pending; \
napi_is_exception_pending((env), &is_pending); \
/* If an exception is already pending, don't rethrow it */ \
if (!is_pending) { \
const char* message = (err_message == NULL) \
? "empty error message" \
: err_message; \
napi_throw_error((env), NULL, message); \
} \
return NULL; \
} \
} while(0)
static napi_value
DoSomethingUseful(napi_env env, napi_callback_info info) {
// Do something useful.
return NULL;
}
napi_value create_addon(napi_env env) {
napi_value result;
NODE_API_CALL(env, napi_create_object(env, &result));
napi_value exported_function;
NODE_API_CALL(env, napi_create_function(env,
"doSomethingUseful",
NAPI_AUTO_LENGTH,
DoSomethingUseful,
NULL,
&exported_function));
NODE_API_CALL(env, napi_set_named_property(env,
result,
"doSomethingUseful",
exported_function));
return result;
}
```
```c
// addon_node.c
#include <node_api.h>
#include "addon.h"
NAPI_MODULE_INIT(/* napi_env env, napi_value exports */) {
// This function body is expected to return a `napi_value`.
// The variables `napi_env env` and `napi_value exports` may be used within
// the body, as they are provided by the definition of `NAPI_MODULE_INIT()`.
return create_addon(env);
}
```
## Environment life cycle APIs
[Section Agents][] of the [ECMAScript Language Specification][] defines the concept
of an "Agent" as a self-contained environment in which JavaScript code runs.
Multiple such Agents may be started and terminated either concurrently or in
sequence by the process.
A Node.js environment corresponds to an ECMAScript Agent. In the main process,
an environment is created at startup, and additional environments can be created
on separate threads to serve as [worker threads][]. When Node.js is embedded in
another application, the main thread of the application may also construct and
destroy a Node.js environment multiple times during the life cycle of the
application process such that each Node.js environment created by the
application may, in turn, during its life cycle create and destroy additional
environments as worker threads.
From the perspective of a native addon this means that the bindings it provides
may be called multiple times, from multiple contexts, and even concurrently from
multiple threads.
Native addons may need to allocate global state which they use during
their life cycle of an Node.js environment such that the state can be
unique to each instance of the addon.
To this end, Node-API provides a way to associate data such that its life cycle
is tied to the life cycle of a Node.js environment.
### `napi_set_instance_data`
<!-- YAML
added:
- v12.8.0
- v10.20.0
napiVersion: 6
-->
```c
napi_status napi_set_instance_data(node_api_basic_env env,
void* data,
napi_finalize finalize_cb,
void* finalize_hint);
```
* `[in] env`: The environment that the Node-API call is invoked under.
* `[in] data`: The data item to make available to bindings of this instance.
* `[in] finalize_cb`: The function to call when the environment is being torn
down. The function receives `data` so that it might free it.
[`napi_finalize`][] provides more details.
* `[in] finalize_hint`: Optional hint to pass to the finalize callback during
collection.
Returns `napi_ok` if the API succeeded.
This API associates `data` with the currently running Node.js environment. `data`
can later be retrieved using `napi_get_instance_data()`. Any existing data
associated with the currently running Node.js environment which was set by means
of a previous call to `napi_set_instance_data()` will be overwritten. If a
`finalize_cb` was provided by the previous call, it will not be called.
### `napi_get_instance_data`
<!-- YAML
added:
- v12.8.0
- v10.20.0
napiVersion: 6
-->
```c
napi_status napi_get_instance_data(node_api_basic_env env,
void** data);
```
* `[in] env`: The environment that the Node-API call is invoked under.
* `[out] data`: The data item that was previously associated with the currently
running Node.js environment by a call to `napi_set_instance_data()`.
Returns `napi_ok` if the API succeeded.
This API retrieves data that was previously associated with the currently
running Node.js environment via `napi_set_instance_data()`. If no data is set,
the call will succeed and `data` will be set to `NULL`.
## Basic Node-API data types
Node-API exposes the following fundamental data types as abstractions that are
consumed by the various APIs. These APIs should be treated as opaque,
introspectable only with other Node-API calls.
### `napi_status`
<!-- YAML
added: v8.0.0
napiVersion: 1
-->
Integral status code indicating the success or failure of a Node-API call.
Currently, the following status codes are supported.
```c
typedef enum {
napi_ok,
napi_invalid_arg,
napi_object_expected,
napi_string_expected,
napi_name_expected,
napi_function_expected,
napi_number_expected,
napi_boolean_expected,
napi_array_expected,
napi_generic_failure,
napi_pending_exception,
napi_cancelled,
napi_escape_called_twice,
napi_handle_scope_mismatch,
napi_callback_scope_mismatch,
napi_queue_full,
napi_closing,
napi_bigint_expected,
napi_date_expected,
napi_arraybuffer_expected,
napi_detachable_arraybuffer_expected,
napi_would_deadlock, /* unused */
napi_no_external_buffers_allowed,
napi_cannot_run_js
} napi_status;
```
If additional information is required upon an API returning a failed status,
it can be obtained by calling `napi_get_last_error_info`.
### `napi_extended_error_info`
<!-- YAML
added: v8.0.0
napiVersion: 1
-->
```c
typedef struct {
const char* error_message;
void* engine_reserved;
uint32_t engine_error_code;
napi_status error_code;
} napi_extended_error_info;
```
* `error_message`: UTF8-encoded string containing a VM-neutral description of
the error.
* `engine_reserved`: Reserved for VM-specific error details. This is currently
not implemented for any VM.
* `engine_error_code`: VM-specific error code. This is currently
not implemented for any VM.
* `error_code`: The Node-API status code that originated with the last error.
See the [Error handling][] section for additional information.
### `napi_env`
`napi_env` is used to represent a context that the underlying Node-API
implementation can use to persist VM-specific state. This structure is passed
to native functions when they're invoked, and it must be passed back when
making Node-API calls. Specifically, the same `napi_env` that was passed in when
the initial native function was called must be passed to any subsequent
nested Node-API calls. Caching the `napi_env` for the purpose of general reuse,
and passing the `napi_env` between instances of the same addon running on
different [`Worker`][] threads is not allowed. The `napi_env` becomes invalid
when an instance of a native addon is unloaded. Notification of this event is
delivered through the callbacks given to [`napi_add_env_cleanup_hook`][] and
[`napi_set_instance_data`][].
### `node_api_basic_env`
> Stability: 1 - Experimental
This variant of `napi_env` is passed to synchronous finalizers
([`node_api_basic_finalize`][]). There is a subset of Node-APIs which accept
a parameter of type `node_api_basic_env` as their first argument. These APIs do
not access the state of the JavaScript engine and are thus safe to call from
synchronous finalizers. Passing a parameter of type `napi_env` to these APIs is
allowed, however, passing a parameter of type `node_api_basic_env` to APIs that
access the JavaScript engine state is not allowed. Attempting to do so without
a cast will produce a compiler warning or an error when add-ons are compiled
with flags which cause them to emit warnings and/or errors when incorrect
pointer types are passed into a function. Calling such APIs from a synchronous
finalizer will ultimately result in the termination of the application.
### `napi_value`
This is an opaque pointer that is used to represent a JavaScript value.
### `napi_threadsafe_function`
<!-- YAML
added: v10.6.0
napiVersion: 4
-->
This is an opaque pointer that represents a JavaScript function which can be
called asynchronously from multiple threads via
`napi_call_threadsafe_function()`.
### `napi_threadsafe_function_release_mode`
<!-- YAML
added: v10.6.0
napiVersion: 4
-->
A value to be given to `napi_release_threadsafe_function()` to indicate whether
the thread-safe function is to be closed immediately (`napi_tsfn_abort`) or
merely released (`napi_tsfn_release`) and thus available for subsequent use via
`napi_acquire_threadsafe_function()` and `napi_call_threadsafe_function()`.
```c
typedef enum {
napi_tsfn_release,
napi_tsfn_abort
} napi_threadsafe_function_release_mode;
```
### `napi_threadsafe_function_call_mode`
<!-- YAML
added: v10.6.0
napiVersion: 4
-->
A value to be given to `napi_call_threadsafe_function()` to indicate whether
the call should block whenever the queue associated with the thread-safe
function is full.
```c
typedef enum {
napi_tsfn_nonblocking,
napi_tsfn_blocking
} napi_threadsafe_function_call_mode;
```
### Node-API memory management types
#### `napi_handle_scope`
This is an abstraction used to control and modify the lifetime of objects
created within a particular scope. In general, Node-API values are created
within the context of a handle scope. When a native method is called from
JavaScript, a default handle scope will exist. If the user does not explicitly
create a new handle scope, Node-API values will be created in the default handle
scope. For any invocations of code outside the execution of a native method
(for instance, during a libuv callback invocation), the module is required to
create a scope before invoking any functions that can result in the creation
of JavaScript values.
Handle scopes are created using [`napi_open_handle_scope`][] and are destroyed
using [`napi_close_handle_scope`][]. Closing the scope can indicate to the GC
that all `napi_value`s created during the lifetime of the handle scope are no
longer referenced from the current stack frame.
For more details, review the [Object lifetime management][].
#### `napi_escapable_handle_scope`
<!-- YAML
added: v8.0.0
napiVersion: 1
-->
Escapable handle scopes are a special type of handle scope to return values
created within a particular handle scope to a parent scope.
#### `napi_ref`
<!-- YAML
added: v8.0.0
napiVersion: 1
-->
This is the abstraction to use to reference a `napi_value`. This allows for
users to manage the lifetimes of JavaScript values, including defining their
minimum lifetimes explicitly.
For more details, review the [Object lifetime management][].
#### `napi_type_tag`
<!-- YAML
added:
- v14.8.0
- v12.19.0
napiVersion: 8
-->
A 128-bit value stored as two unsigned 64-bit integers. It serves as a UUID
with which JavaScript objects or [externals][] can be "tagged" in order to
ensure that they are of a certain type. This is a stronger check than
[`napi_instanceof`][], because the latter can report a false positive if the
object's prototype has been manipulated. Type-tagging is most useful in
conjunction with [`napi_wrap`][] because it ensures that the pointer retrieved
from a wrapped object can be safely cast to the native type corresponding to the
type tag that had been previously applied to the JavaScript object.
```c
typedef struct {
uint64_t lower;
uint64_t upper;
} napi_type_tag;
```
#### `napi_async_cleanup_hook_handle`
<!-- YAML
added:
- v14.10.0
- v12.19.0
-->
An opaque value returned by [`napi_add_async_cleanup_hook`][]. It must be passed
to [`napi_remove_async_cleanup_hook`][] when the chain of asynchronous cleanup
events completes.
### Node-API callback types
#### `napi_callback_info`
<!-- YAML
added: v8.0.0
napiVersion: 1
-->
Opaque datatype that is passed to a callback function. It can be used for
getting additional information about the context in which the callback was
invoked.
#### `napi_callback`
<!-- YAML
added: v8.0.0
napiVersion: 1
-->
Function pointer type for user-provided native functions which are to be
exposed to JavaScript via Node-API. Callback functions should satisfy the
following signature:
```c
typedef napi_value (*napi_callback)(napi_env, napi_callback_info);
```
Unless for reasons discussed in [Object Lifetime Management][], creating a
handle and/or callback scope inside a `napi_callback` is not necessary.
#### `node_api_basic_finalize`
<!-- YAML
added:
- v21.6.0
- v20.12.0
- v18.20.0
-->
> Stability: 1 - Experimental
Function pointer type for add-on provided functions that allow the user to be
notified when externally-owned data is ready to be cleaned up because the
object it was associated with has been garbage-collected. The user must provide
a function satisfying the following signature which would get called upon the
object's collection. Currently, `node_api_basic_finalize` can be used for
finding out when objects that have external data are collected.
```c
typedef void (*node_api_basic_finalize)(node_api_basic_env env,
void* finalize_data,
void* finalize_hint);
```
Unless for reasons discussed in [Object Lifetime Management][], creating a
handle and/or callback scope inside the function body is not necessary.
Since these functions may be called while the JavaScript engine is in a state
where it cannot execute JavaScript code, only Node-APIs which accept a
`node_api_basic_env` as their first parameter may be called.
[`node_api_post_finalizer`][] can be used to schedule Node-API calls that
require access to the JavaScript engine's state to run after the current
garbage collection cycle has completed.
In the case of [`node_api_create_external_string_latin1`][] and
[`node_api_create_external_string_utf16`][] the `env` parameter may be null,
because external strings can be collected during the latter part of environment
shutdown.
Change History:
* experimental (`NAPI_EXPERIMENTAL`):
Only Node-API calls that accept a `node_api_basic_env` as their first
parameter may be called, otherwise the application will be terminated with an
appropriate error message. This feature can be turned off by defining
`NODE_API_EXPERIMENTAL_BASIC_ENV_OPT_OUT`.
#### `napi_finalize`
<!-- YAML
added: v8.0.0
napiVersion: 1
-->
Function pointer type for add-on provided function that allow the user to
schedule a group of calls to Node-APIs in response to a garbage collection
event, after the garbage collection cycle has completed. These function
pointers can be used with [`node_api_post_finalizer`][].
```c
typedef void (*napi_finalize)(napi_env env,
void* finalize_data,
void* finalize_hint);
```
Change History:
* experimental (`NAPI_EXPERIMENTAL` is defined):
A function of this type may no longer be used as a finalizer, except with
[`node_api_post_finalizer`][]. [`node_api_basic_finalize`][] must be used
instead. This feature can be turned off by defining
`NODE_API_EXPERIMENTAL_BASIC_ENV_OPT_OUT`.
#### `napi_async_execute_callback`
<!-- YAML
added: v8.0.0
napiVersion: 1
-->
Function pointer used with functions that support asynchronous
operations. Callback functions must satisfy the following signature:
```c
typedef void (*napi_async_execute_callback)(napi_env env, void* data);
```
Implementations of this function must avoid making Node-API calls that execute
JavaScript or interact with JavaScript objects. Node-API calls should be in the
`napi_async_complete_callback` instead. Do not use the `napi_env` parameter as
it will likely result in execution of JavaScript.
#### `napi_async_complete_callback`
<!-- YAML
added: v8.0.0
napiVersion: 1
-->
Function pointer used with functions that support asynchronous
operations. Callback functions must satisfy the following signature:
```c
typedef void (*napi_async_complete_callback)(napi_env env,
napi_status status,
void* data);
```
Unless for reasons discussed in [Object Lifetime Management][], creating a
handle and/or callback scope inside the function body is not necessary.
#### `napi_threadsafe_function_call_js`
<!-- YAML
added: v10.6.0
napiVersion: 4
-->
Function pointer used with asynchronous thread-safe function calls. The callback
will be called on the main thread. Its purpose is to use a data item arriving
via the queue from one of the secondary threads to construct the parameters
necessary for a call into JavaScript, usually via `napi_call_function`, and then
make the call into JavaScript.
The data arriving from the secondary thread via the queue is given in the `data`
parameter and the JavaScript function to call is given in the `js_callback`
parameter.
Node-API sets up the environment prior to calling this callback, so it is
sufficient to call the JavaScript function via `napi_call_function` rather than
via `napi_make_callback`.
Callback functions must satisfy the following signature:
```c
typedef void (*napi_threadsafe_function_call_js)(napi_env env,
napi_value js_callback,
void* context,
void* data);
```
* `[in] env`: The environment to use for API calls, or `NULL` if the thread-safe
function is being torn down and `data` may need to be freed.
* `[in] js_callback`: The JavaScript function to call, or `NULL` if the
thread-safe function is being torn down and `data` may need to be freed. It
may also be `NULL` if the thread-safe function was created without
`js_callback`.
* `[in] context`: The optional data with which the thread-safe function was
created.
* `[in] data`: Data created by the secondary thread. It is the responsibility of
the callback to convert this native data to JavaScript values (with Node-API
functions) that can be passed as parameters when `js_callback` is invoked.
This pointer is managed entirely by the threads and this callback. Thus this
callback should free the data.
Unless for reasons discussed in [Object Lifetime Management][], creating a
handle and/or callback scope inside the function body is not necessary.
#### `napi_cleanup_hook`
<!-- YAML
added:
- v19.2.0
- v18.13.0
napiVersion: 3
-->
Function pointer used with [`napi_add_env_cleanup_hook`][]. It will be called
when the environment is being torn down.