Skip to content

Commit af53983

Browse files
author
Gabriel Schulhof
committed
guides: add ABI stability guide
1 parent 3ebc248 commit af53983

File tree

2 files changed

+119
-0
lines changed

2 files changed

+119
-0
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
---
2+
title: ABI Stability
3+
layout: docs.hbs
4+
---
5+
6+
# ABI Stability
7+
8+
## Introduction
9+
An Application Binary Interface (ABI) is a way for programs to call functions
10+
and use data structures from other compiled programs. It is the compiled version
11+
of an Application Programming Interface (API). In other words, the headers files
12+
describing the classes, functions, data structures, enumerations, and constants
13+
which enable an application to perform a desired task correspond by way of
14+
compilation to a set of addresses and expected parameter values and memory
15+
structure sizes and layouts with which the provider of the ABI was compiled.
16+
17+
The application using the ABI must be compiled such that the available
18+
addresses, expected parameter values, and memory structure sizes and layouts
19+
agree with those with which the ABI provider was compiled. This is usually
20+
accomplished by compiling against the headers provided by the ABI provider.
21+
22+
Since the provider of the ABI and the user of the ABI may be compiled at
23+
different times with different versions of the compiler, a portion of the
24+
responsibility for ensuring ABI compatibility lies with the compiler. Different
25+
versions of the compiler, perhaps provided by different vendors, must all
26+
produce the same ABI from a header file with a certain content, and must produce
27+
code for the application using the ABI that accesses the API described in a
28+
given header according to the conventions of the ABI resulting from the
29+
description in the header. Modern compilers have a fairly good track record of
30+
not breaking the ABI compatibility of the applications they compile.
31+
32+
The remaining responsibility for ensuring ABI compatibility lies with the team
33+
maintaining the header files which provide the API that results, upon
34+
compilation, in the ABI that is to remain stable. Changes to the header files
35+
can be made, but the nature of the changes has to be closely tracked to ensure
36+
that, upon compilation, the ABI does not change in a way that will render
37+
existing users of the ABI incompatible with the new version.
38+
39+
## ABI Stability in Node.js
40+
Node.js provides header files maintained by several independent teams. For
41+
example, header files such as `node.h` and `node_buffer.h` are maintained by
42+
the Node.js team. `v8.h` is maintained by the V8 team, which, although in close
43+
co-operation with the Node.js team, is independent, and with its own schedule
44+
and priorities. Thus, the Node.js team has only partial control over the
45+
changes that are introduced in the headers the project provides. As a result,
46+
the Node.js project has adopted [semantic versioning](https://semver.org/).
47+
This ensures that the APIs provided by the project will result in a stable ABI
48+
for all minor and patch versions of Node.js released within one major version.
49+
In practice, this means that the Node.js project has committed itself to
50+
ensuring that a Node.js native addon compiled against a given major version of
51+
Node.js will load successfully when loaded by any Node.js minor or patch version
52+
within the major version against which it was compiled.
53+
54+
## N-API
55+
Demand has arisen for equipping Node.js with an API that results in an ABI that
56+
remains stable across multiple Node.js major versions. The motivation for
57+
creating such an API is as follows:
58+
* The JavaScript language has remained compatible with itself since its very
59+
early days, whereas the ABI of the engine executing the JavaScript code changes
60+
with every major version of Node.js. This means that applications consisting of
61+
Node.js packages written entirely in JavaScript need not be recompiled,
62+
reinstalled, or redeployed as a new major version of Node.js is dropped into
63+
the production environment in which such applications run. In contrast, if an
64+
application depends on a package that contains a native addon, the application
65+
has to be recompiled, reinstalled, and redeployed whenever a new major version
66+
of Node.js is introduced into the production environment. This disparity
67+
between Node.js packages containing native addons and those that are written
68+
entirely in JavaScript has added to the maintenance burden of production
69+
systems which rely on native addons.
70+
71+
* Other projects have started to produce JavaScript interfaces that are
72+
essentially alternative implementations of Node.js. Since these projects are
73+
usually built on a different JavaScript engine than V8, their native addons
74+
necessarily take on a different structure and use a different API. Nevertheless,
75+
using a single API for a native addon across different implementations of the
76+
Node.js JavaScript API would allow these projects to take advantage of the
77+
ecosystem of JavaScript packages that has accrued around Node.js.
78+
79+
* Node.js may contain a different JavaScript engine in the future. This means
80+
that, externally, all Node.js interfaces would remain the same, but the V8
81+
header file would be absent. Such a step would cause the disruption of the
82+
Node.js ecosystem in general, and that of the native addons in particular, if
83+
an API that is JavaScript engine agnostic is not first provided by Node.js and
84+
adopted by native addons.
85+
86+
To these ends Node.js has introduced N-API in version 8.6.0 and marked it as a
87+
stable component of the project as of Node.js 8.12.0. The API is defined in the
88+
headers [`node_api.h`][] and [`node_api_types.h`][], and provides a forward-
89+
compatibility guarantee that crosses the Node.js major version boundary. The
90+
guarantee can be stated as follows:
91+
92+
**A given version *n* of N-API will be available in the major version of
93+
Node.js in which it was published, and in all subsequent versions of Node.js,
94+
including subsequent major versions.**
95+
96+
A native addon author can take advantage of the N-API forward compatibility
97+
guarantee by ensuring that the addon makes use only of APIs defined in
98+
`node_api.h` and data structures and constants defined in `node_api_types.h`.
99+
By doing so, the author facilitates adoption of their addon by indicating to
100+
production users that the maintenance burden for their application will increase
101+
no more by the addition of the native addon to their project than it would by
102+
the addition of a package written purely in JavaScript.
103+
104+
N-API is versioned because new APIs are added from time to time. Unlike
105+
semantic versioning, N-API versioning is cumulative. That is, each version of
106+
N-API conveys the same meaning as a minor version in the semver system, meaning
107+
that all changes made to N-API will be backwards compatible. Additionally, new
108+
N-APIs are added under an experimental flag to give the community an opportunity
109+
to vet them in a production environment. Experimental status means that,
110+
although care has been taken to ensure that the new API will not have to be
111+
modified in an ABI-incompatible way in the future, it has not yet been
112+
sufficiently proven in production to be correct and useful as designed and, as
113+
such, may undergo ABI-incompatible changes before it is finally incorporated
114+
into a forthcoming version of N-API. That is, an experimental N-API is not yet
115+
covered by the forward compatibility guarantee.
116+
117+
[`node_api.h`]: https://github.com/nodejs/node/blob/master/src/node_api.h
118+
[`node_api_types.h`]: https://github.com/nodejs/node/blob/master/src/node_api_types.h

locale/en/docs/guides/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,4 @@ layout: docs.hbs
2929
- [Backpressuring in Streams](backpressuring-in-streams/)
3030
- [Domain Module Postmortem](domain-postmortem/)
3131
- [How to publish N-API package](publishing-napi-modules/)
32+
- [ABI Stability](abi-stability/)

0 commit comments

Comments
 (0)