Node.js 10.x vs Node.js 8.x: A Version Comparison

Node.js is an open-source server-side runtime environment allowing developers to use JavaScript to create scalable, high-performance network applications. Unlike traditional web development, where JavaScript is primarily used on the client side, Node.js allows JavaScript code to be executed on the server.

Node.js has undergone numerous version releases since its initial launch. The two major releases, Node.js v8.x and Node.js v10.x brought significant changes and additions. Node.js 8.0.0 ships with V8 5.8, a significant update to the JavaScript runtime that includes major improvements in performance and developer-facing APIs. At the same time, Node.js v10.x is the sixth major Node.js release since the launch of the Node.js foundation. This release comes with a coordinated experimental release of Node-ChakraCore that fully supports N-API and advances the Time-Travel innovation.

This article aims to empower developers, project managers, and organizations to make informed decisions, ensure compatibility, enhance security, and leverage new features, ultimately contributing to the success and longevity of software projects. Some software updates may introduce breaking changes or deprecate certain functionalities. Understanding these changes allows developers to assess the risk and plan for any necessary modifications or updates to their code.

Node.js 8.x Release Highlights

Most significant changes and features that came with the Node.js 8.0.0 release:

N-API

In this release, Node.js introduces a new experimental API called N-API. N-API stands for Node-API and is designed to provide a more stable and consistent way for developers to work with native add-ons in Node.js applications.

One of the key benefits of N-API is that it allows native addons to be compiled once on a system and used across multiple versions of Node.js. This means developers can build native addons that work seamlessly with different Node.js versions without recompilation.

Async_hooks

The async hooks module serves as a diagnostics API. It allows developers to gain insights into the behavior of asynchronous operations within their Node.js applications. This can be particularly valuable for debugging, performance monitoring, and tracing the flow of asynchronous code.

It’s important to note that the async_hooks module is marked as experimental. This designation indicates that it is not yet considered stable and may undergo further changes or refinements in future Node.js releases. As a result, users are advised to exercise caution when using the experimental module.

Improved Support for Promises

The release of Node.js 8.0.0 introduced a notable feature: the util.promisify() API. This API provides a way to convert standard Node.js callback-style APIs into functions that return Promises.

In traditional Node.js programming, many functions use a callback pattern for handling asynchronous operations. These functions accept a callback function as an argument, invoked once the operation is complete or an error occurs. For example:

const fs = require('fs');

fs.readFile('file.txt', 'utf8', (err, data) => {
  if (err) {
    // Handle error
  } else {
    // Process data
  }
});

Node.js 8.0.0 introduced the util.promisify() function as part of the built-in util module. This function allows you to wrap callback-style functions and convert them into Promise-based functions. Here’s an example of how you might use it:

const util = require('util');
const fs = require('fs');

const readFileAsync = util.promisify(fs.readFile);

readFileAsync('file.txt', 'utf8')
  .then(data => {
    // Process data
  })
  .catch(err => {
    // Handle error
  });

Console Improvements

In Node.js 8.0.0, there were changes made to the behaviour of the console module, which includes methods like console.log() and console.error(). These changes have to do with how errors are handled when writing output to streams like stdout and stderr.

In earlier versions of Node.js, if an error occurred while attempting to write console output (e.g., using console.log() or console.error()) to the underlying stream (e.g., stdout, stderr, or pipes), it could potentially cause the entire Node.js application to crash.

Starting from Node.js 8.0.0, errors occurring while writing console output will be silently ignored. This means that if there’s an issue with writing to the stream, it won’t result in a crash of the Node.js process. Instead, the error will be ignored, and the application will continue running.

However, the legacy behaviour can be achieved by passing an ignoreErrors option to the Console constructor when creating a custom console instance. Setting ignoreErrors to false or not providing the option will restore the previous error-handling behaviour, where console errors could potentially crash the application.

Node.js 10.x Release Highlights

Some notable highlights that came with the Node.js 10.0.0 release:

Assert

This pertains to changes and improvements in the “Assert” module in Node.js. The Assert module is used for writing tests and performing assertions in your Node.js applications.

  • The assert.fail() function in the Assert module is used to generate an assertion error. In this release, calling with more than one argument is deprecated. This means using multiple arguments with assert.fail() will no longer be supported and may result in a deprecation warning.
  • Previously, assert.ifError() would throw an error for any truth value passed as an argument. In this release, it will only throw an error if the argument is not undefined or null. This change aligns it with its intended purpose: to check if a value is an error.
  • When you use objects in assertions and the assertion fails, this release will provide a “diff” display in the error message. This can be especially helpful for debugging and understanding the differences between expected and actual objects.
  • The assert.ok(expression) method, which checks if an expression is true, now includes the expression itself in the error message. This makes it easier to identify which expression caused the assertion to fail.

These changes and additions to the Assert module enhance the capabilities of Node.js for writing tests and performing assertions.

Async_hooks

The deprecated legacy async_hooks APIs have now been removed from Node.js. Developers are advised to stop using it because it will eventually be removed from the codebase.

Runtime Deprecation Warning for require()

In Node.js, the require() function is used to load modules and dependencies. Node.js is built on top of a set of internal modules and dependencies used to implement its core functionality. These internal modules are not typically intended for use by external applications and are considered part of Node.js’ internal implementation. When you use require() to access Node.js’ internal dependencies, you are accessing parts of Node.js that are not part of the public API. In many cases, this can be considered an anti-pattern, as it can lead to unpredictable behaviour and issues when Node.js is updated. Node.js emits a runtime deprecation warning when such usage is detected, using require() function, to discourage developers from using these internal dependencies.

File System Module

The release notes pertain to changes and improvements in the fs/promises module in Node.js. This module provides promisified versions of the functions from the fs (file system) module, allowing developers to work with files and directories using promises and asynchronous operations.

This means that you can now use asynchronous await and async syntax when working with file operations instead of using callbacks. In this release, invalid path errors are thrown synchronously. This change ensures that developers receive immediate feedback when accessing or manipulating files and directories with invalid paths.

Comparison Table: Node.js 8.x VS Node.js 10.x

Features Node.js 8.xNode.js 10.x
HTTPPrimarily supports HTTP/1.1, the previous version of the HTTP protocol. It provides basic support for HTTP/2 through external modules but does not natively implement it.Added support for ECMAScript Modules (ESM) in the HTTP module, enabling developers to use modern module syntax when building web servers.
File System (fs)Promisified fs modules are not available.Introduction of Promises for the fs module. The fs.promises API was added, allowing developers to perform file system operations using Promises and the async/await syntax.
async_hooksIntroduced the async_hooks module, providing basic support for monitoring asynchronous operations, such as tracking asynchronous resources and creating custom async resource instances.Added better support for tracking asynchronous operations involving Promises and the async/await syntax. This improvement made monitoring and tracing asynchronous code written with modern JavaScript patterns easier.
Assert ModuleNo class assert.AssertionError available in this release.Added a subclass of Error that indicates the failure of an assertion. All errors thrown by the assert module will be instances of the AssertionError class.
ErrorsThere were various missing system errors, which were later added with version 10.x.New system errors added were MessageError, DestError, and InfoError.

Choosing the Right Version

While choosing between Node.js versions 8.x and 10.x, or any two versions of Node.js, it’s essential to consider your specific project requirements, compatibility needs, and the features offered by each version.

Consider each version’s specific features or improvements and whether they align with your project’s needs. Node.js release notes often provide details about enhancements and changes. Check if there have been any performance improvements in the newer version that can benefit your application. Node.js releases often include optimizations and updates to the V8 engine, which can impact performance.

Assess the compatibility of your existing code and dependencies with the Node.js versions you are considering. Ensure that your libraries and frameworks work seamlessly with the chosen version. Consider the availability and compatibility of third-party libraries and modules you plan to use. Some libraries may be updated to work with the latest Node.js versions, while others may lag.

Think about your project’s lifecycle and duration. You might prioritise the latest features if it’s a short-term project or a proof of concept. For long-term or enterprise projects, stability and long-term support are crucial. Before deciding, thoroughly test your application on the target Node.js version to identify compatibility issues or unexpected behaviour.

Summary

The new changes introduced in Node.js versions 8 and 10.x bring important improvements and enhancements to the platform. In version 8.0.0, the introduction of the experimental N-API offers a stable and consistent way to develop native addons, facilitating compatibility with multiple versions of Node.js and different JavaScript runtimes. Additionally, an upgrade to the experimental async_hooks module enhances monitoring and tracing of asynchronous operations, aiding in debugging and performance optimization.

In version 10.x, the fs/promises module provides promisified versions of file system functions, making asynchronous file operations more straightforward. Error handling during console output operations is improved, preventing crashes due to console-related errors.

Reference

https://nodejs.org/en/download/releases

Khushi Soni
Khushi Soni
Articles: 3