Node.js — ABI Stability (original) (raw)

Change page

Getting Started

Introduction to Node.jsHow much JavaScript do you need to know to use Node.js?Differences between Node.js and the BrowserThe V8 JavaScript EngineAn introduction to the npm package managerECMAScript 2015 (ES6) and beyondNode.js, the difference between development and productionNode.js with WebAssemblyDebugging Node.jsProfiling Node.js ApplicationsFetching data with Node.jsWebSocket client with Node.jsSecurity Best Practices

TypeScript

Introduction to TypeScriptRunning TypeScript NativelyRunning TypeScript with a runnerRunning TypeScript code using transpilationPublishing a TypeScript package

Asynchronous Work

Asynchronous flow controlOverview of Blocking vs Non-BlockingJavaScript Asynchronous Programming and CallbacksDiscover Promises in Node.jsDiscover JavaScript TimersThe Node.js Event LoopThe Node.js Event EmitterUnderstanding process.nextTick()Understanding setImmediate()Don't Block the Event Loop

Manipulating Files

Node.js file statsNode.js File PathsWorking with file descriptors in Node.jsReading files with Node.jsWriting files with Node.jsWorking with folders in Node.jsHow to work with Different Filesystems

Command Line

Run Node.js scripts from the command lineHow to read environment variables from Node.jsHow to use the Node.js REPLOutput to the command line using Node.jsAccept input from the command line in Node.js

Modules

Publishing a packageHow to publish a Node-API packageAnatomy of an HTTP TransactionABI StabilityHow to use streamsBackpressuring in Streams

Diagnostics

User JourneyMemoryLive DebuggingPoor PerformanceFlame Graphs

Test Runner

Discovering Node.js's test runnerUsing Node.js's test runnerMocking in testsCollecting code coverage in Node.js

Introduction

An Application Binary Interface (ABI) is a way for programs to call functions and use data structures from other compiled programs. It is the compiled version of an Application Programming Interface (API). In other words, the headers files describing the classes, functions, data structures, enumerations, and constants which enable an application to perform a desired task correspond by way of compilation to a set of addresses and expected parameter values and memory structure sizes and layouts with which the provider of the ABI was compiled.

The application using the ABI must be compiled such that the available addresses, expected parameter values, and memory structure sizes and layouts agree with those with which the ABI provider was compiled. This is usually accomplished by compiling against the headers provided by the ABI provider.

Since the provider of the ABI and the user of the ABI may be compiled at different times with different versions of the compiler, a portion of the responsibility for ensuring ABI compatibility lies with the compiler. Different versions of the compiler, perhaps provided by different vendors, must all produce the same ABI from a header file with a certain content, and must produce code for the application using the ABI that accesses the API described in a given header according to the conventions of the ABI resulting from the description in the header. Modern compilers have a fairly good track record of not breaking the ABI compatibility of the applications they compile.

The remaining responsibility for ensuring ABI compatibility lies with the team maintaining the header files which provide the API that results, upon compilation, in the ABI that is to remain stable. Changes to the header files can be made, but the nature of the changes has to be closely tracked to ensure that, upon compilation, the ABI does not change in a way that will render existing users of the ABI incompatible with the new version.

ABI Stability in Node.js

Node.js provides header files maintained by several independent teams. For example, header files such as node.h and node_buffer.h are maintained by the Node.js team. v8.h is maintained by the V8 team, which, although in close co-operation with the Node.js team, is independent, and with its own schedule and priorities. Thus, the Node.js team has only partial control over the changes that are introduced in the headers the project provides. As a result, the Node.js project has adopted semantic versioning. This ensures that the APIs provided by the project will result in a stable ABI for all minor and patch versions of Node.js released within one major version. In practice, this means that the Node.js project has committed itself to ensuring that a Node.js native addon compiled against a given major version of Node.js will load successfully when loaded by any Node.js minor or patch version within the major version against which it was compiled.

N-API

Demand has arisen for equipping Node.js with an API that results in an ABI that remains stable across multiple Node.js major versions. The motivation for creating such an API is as follows:

To these ends Node.js has introduced N-API in version 8.6.0 and marked it as a stable component of the project as of Node.js 8.12.0. The API is defined in the headers node_api.h and node_api_types.h, and provides a forward- compatibility guarantee that crosses the Node.js major version boundary. The guarantee can be stated as follows:

A given version n of N-API will be available in the major version of Node.js in which it was published, and in all subsequent versions of Node.js, including subsequent major versions.

A native addon author can take advantage of the N-API forward compatibility guarantee by ensuring that the addon makes use only of APIs defined innode_api.h and data structures and constants defined in node_api_types.h. By doing so, the author facilitates adoption of their addon by indicating to production users that the maintenance burden for their application will increase no more by the addition of the native addon to their project than it would by the addition of a package written purely in JavaScript.

N-API is versioned because new APIs are added from time to time. Unlike semantic versioning, N-API versioning is cumulative. That is, each version of N-API conveys the same meaning as a minor version in the semver system, meaning that all changes made to N-API will be backwards compatible. Additionally, new N-APIs are added under an experimental flag to give the community an opportunity to vet them in a production environment. Experimental status means that, although care has been taken to ensure that the new API will not have to be modified in an ABI-incompatible way in the future, it has not yet been sufficiently proven in production to be correct and useful as designed and, as such, may undergo ABI-incompatible changes before it is finally incorporated into a forthcoming version of N-API. That is, an experimental N-API is not yet covered by the forward compatibility guarantee.

  1. Modules
  2. ABI Stability