Node.js Removes Version Dependencies for Native Modules

17 Oct 2018 11:49am, by

Thanks to a collaborative open source effort across multiple companies, Node.js developers will no longer have to recompile their “native” modules each time Node is upgraded, which is the current headache-inducing practice.

The N-API project will bring more stability to the Node ecosystem, noted Arunesh Chandra Microsoft senior program manager for the Microsoft ChakraCore JavaScript engine, and one of the contributors to N-API, speaking at the Node + JS Interactive conference, held last week in Vancouver.

The Node.js ecosystem relies heavily external modules to extend the functionality of programs written for the serverside JavaScript runtime. Most of are written in JavaScript, but a good percent — as many as 20 percent — are written in other languages such as C (Node’s own core language) and C++. These “native modules,” as they are called provide a wealth of functionality to the Node ecosystem.

“Node.js growth depends on this ecosystem. The more reliable this ecosystem is, the more Node.js developers will be relying on this platform,” Chandra said.

To date, native modules have been difficult to maintain, both for those who maintain them and those who use them. Every time a new version of Node.js is released, all the native modules must be recompiled for that new version. As a result, package maintainers must keep different versions of their modules for each version of Node, and developers trying out a new module have been endlessly frustrated by a message that the module “was compiled against a different Node.js version.”

The issue is that native modules interact directly with the Google V8 JavaScript runtime engine that powers Node, explained Michael Dawson the IBM Node.js community lead and N-API contributor who helped with the presentation. So each time V8 is updated, it comes with a new set of function calls. JavaScript-based modules were safe from these changes, because they were written in JavaScript, but those modules that made direct calls to V8 itself potentially had to be revised.

“This is not how a mature platform should work,” Chandra said.

The N-API layer (often pronounced as “napi”) is designed to eliminate this fluctuation, by providing a stable API that developers can always write to, without worrying about the underlying version of Node. Module developers simply add the “node_api.h” header to their C code, and compile as usual against the methods provided. Every function returns a “NAPI” status, and state is captured within the module with a token provided as an argument.

As of last week, the LTS (long-term support) Node.js version 10, 8 and 6 (in “experimental mode”) all include the N-API layer.

Intel Software Engineer Gabriel Schulhof.

N-API only works for C applications, though a related project, node-addon-api, provides a set of C++ wrappers around the API, making C++ programs accessible to N-API as well, noted Intel Software Engineer Gabriel Schulhof, who helped on that project. Schulhof was also instrumental in adapting the N-API to the lightweight JerryScript JavaScript engine for Internet of Things, which he discussed in his own talk at the conference.

Much work now must be done to get port the native modules to N-API. Developers should encourage the owners of the modules they use to port their modules to this API, or perhaps the developers could even do so themselves. Both would be motivated by no longer having to worry about compiling modules to each version. Developers would also enjoy a faster testing process, now that modules are no longer version-specific. The API will also make it easier to use the modules across different Node implementations, such as Microsoft’s Chakracore.

Standardizing the API layer for native modules could not only make life easier for Node developers, but even enable a whole new class of applications, thanks to its ease of use, Dawson noted. For instance, one party was able to put together a logging application, which would have been prohibitively difficult to do before even. Writing the modules in C would the app sufficient performance, but maintaining modules for each version of Node would not have been feasible. The code became much easier to manage after moving to the API.

“Because you can potentially write a single binary, and have that binary run across different versions, people are going to start doing things they couldn’t do before,” Dawson said.

The Linux Foundation provided travel assistance for the reporter to attend this conference.

The Linux Foundation is a sponsor of The New Stack.

A newsletter digest of the week’s most important stories & analyses.