IBM Developer Blog

Follow the latest happenings with IBM Developer and stay in the know.

In this blog post, learn what's new in 13 and why you should start thinking about migrating to Node.js 12.

Node.js 13 was released today, and Node.js 12 was promoted to Long Term Support (LTS). In this blog post, learn what’s new in 13 and why you should start thinking about migrating to Node.js 12.

Quick review of the LTS process

Every October, we see the results of the Node.js release process. Users can expect and plan for a new current release every April and October, with the latest even-numbered release being promoted to LTS in October.

Our customers seem to like the predictable timetable for quality releases. The adoption curves reflect that usage is shifting towards the next LTS release over time, so we’re excited to see that people appreciate this routine. For September, the download numbers by platform for the LTS versions were as follows:

  • 8.x (April 2017 – LTS ) : 12777685
  • 10.x (April 2018 – LTS ) : 17773295
  • 12.x (April 2019 – CURRENT) : 3916577

This confirms that people are shifting towards the most recent LTS versions along with advance use of the next LTS version.

At IBM, our strategy is to focus on aspects we believe are important to our customers, including:

  • Stable and predictable releases
  • Platform support
  • Security
  • Diagnostics
  • Performance
  • Code quality and safety net
  • Key features

The new Node.js releases continue to deliver in these areas. Let’s look at some of the most interesting aspects of the Node.js 12 and 13 releases.

Node.js 12 promoted to LTS and what it means for you

With the promotion of version 12 to LTS, it’s now suitable for use in production, and you should consider how it fits into your migration plan. Node.js 12.x brings with it improved diagnostics, security, and performance. For a reminder of what’s there you can check out:

What’s in Node.js 13 and why use it?

Node.js 13 is the next current release. Although it won’t be promoted to LTS and we don’t recommend its use in production, it’s still a good idea to test your applications and build your packages on this version periodically. Doing so ensures that you can experiment with the latest features — and when version 14 comes our, there will be less for you to catch up on in terms of what’s new.

A couple of the key features and changes in version 13 that I’d like to call out:

  • Updated version of V8 (Verion 7.8) – A new version of the V8 JavaScript engine brings improved performance and new language features.
  • Full ICU is enabled by default – Node.js now supports a larger set of languages by default. Curious abourt langauge support in Node? Watch this video wehre Steven Loomis and I talk about internationalization.

The Node.js approach for releases and backporting changes means that, many times, you don’t need to wait for a new major release to access new features. In fact, at the announce of a new release, there might not be as much that is truly “new”.

I still think that it’s a good time to call out some of the notable features that became available or were promoted to “stable” in the timeframe leading up to that release. For version 13, that includes:

  • Workers API is now stable. It is stable in both 12 and 13 (that was not the case when 12.x was released).

New features in action

Worker API example

Lets start out by trying out the Workers API. The following is a simple example of using the API;

const workers = require('worker_threads');

if (workers.isMainThread) {
  const worker = new workers.Worker(__filename, {
    workerData: 41
  worker.on('message', (response) => {
} else {
  workers.parentPort.postMessage(workers.workerData + 1 )

Running the example:

bash-4.2$ node test.js

This example uses the approach of a single file for both the parent and child which may be familiar if you have used fork. That is accomplished by passing __filename to the creation of the Worker. While convenient, this isn’t necessary. You can provide a different file that contains the code for the worker.

The example starts by checking if the code is running on the main thread with isMainThread. If so, it starts up the worker, passing it the number 41 and then waits for a response from the worker. The wait for the response is asynchronous, so the main thread can continue working without blocking the main thread.

When the worker starts it takes the value passed (41), increments it by 1 and sends a response message with the result. All of this computation takes place on the worker thread instead of the Node.js main event loop thread. In this case, the computation does not take long. But, if you have something more complex to do — for example, doing some kind of complex pattern matching or otherwise computationally intensive work — it could take much longer to execute.

Once the event triggered by the message sent by the worker is processed on the main thread, it simply prints out the result.

This is a very simple example to show how easily you can move work off the main thread. The worker API provides different ways that data can be exchanged between the main thread and the worker. They key thing to understand is that the main thread and each worker has it’s own enviroment including the Object heap so you can’t just reference objects between the two. Instead, you need to share data through one of the APIs provided.

I’ll also note that it it’s important to use workers in the right places. Node.js does a great job handling concurrent requests without Workers, so, most often, you should only introduce them where it helps you avoid blocking the main event loop.

Full ICU by default

The next feature I’d like to show is full ICU by default. Node.js has supported full ICU for some time, but there were extra steps you had to take to enable the data required for the full set of languages. In Node.js 13, full ICU support is bundled by default.

What this means is that the following code will return the requested values instead of defaulting to English:

console.log(new Intl.DateTimeFormat('es',{month:'long'}).format(new Date(9E8)));
console.log(new Date(0).toLocaleString("el",{month:"long"}));
console.log(new Date(157177E7).toLocaleString("zh",{year:"numeric",day:"numeric",month:"long"}));

where we are trying to work in the Spanish, Greek, and Chinese locales(es = spanish, el = greek, zh = chinese).

So, on Node.js 13, it would look like:

bash-4.2$ node test2.js

Whereas, Node.js 12 returns:

bash-4.2$ node test2.js
October 22, 2019

Including full ICU by default makes it easier for our customers who operate across 170 different countries to run and supports applications in their native locales.

Thanks to our great team

In closing I’d like to thank the release team including Michaël Zasso and IBMer Bethany Griggs for all of their hard work in getting 13.x out and 12.x promoted to LTS. Bethany was the releaser for 13.x and Michaël handled the promotion of 12.x to LTS. I’d also like to thank the supporting cast from the build working group and, of course, the individual contributors as well.

How you can contribute to Node.js

Committing code and participating in the work of the Node.js organization is not the only way to contribute to the continued sucess of Node.js. As a Node.js package developer or end user, I’d ask that you help out by testing early and often and provide feedback to the Node.js project.

The regular cycle of majors released as Current every 6 months (April and October) provides a good opportunity to test out releases in advance so that when a release is promoted to LTS, there are no surprises. We need your help in doing that testing. Once a release is in LTS, I ask that you consider testing your applications and packages regularly on the LTS versions in order to ensure a good experience for end users migrating to those versions.

Learn more

If you’d like to read more about this release, check out the blog post announcing the Node.js 13 release.

You can also:

Michael Dawson