What version of Node should we use?


by Derek Dunagan

d20 die styled as the Node.js hexagon that shows 12

12.

Yep. Y'all should just use 12.

As in Node Erbium:

.nvmrc
lts/erbium
.n-node-version
erbium
Dockerfile
FROM node:erbium
FROM node:erbium-alpine
etc

That is unless:

  • You are planning to launch in Q1 2021, in which case you will actually be launching in Q2 2021, so go ahead and use 14.
  • Or, if you know the specific Node feature you must have that is not in 12.
  • Or, if you are using GCloud functions, in which case you must use 10, for now.
  • Or, if your real question is "What version of Node should I use?", in which case, use whatever the fuck you want, but as soon as that "I" becomes "we", refer back.



Why 12?

Do you really care?

Okay here goes...

So you're probably reading this because, at any given time, there are 3-5 versions of Node being maintained. Yeah. So first things first. Let's eliminate the odd-numbered majors. They're not for you.

Node 13 died last month. Node 15 is due in October, but will die the following June, as did Node 13 this past June. By decree of the Node release schedule, odd majors enjoy an 8 month lifespan. Node 5, 7, 9, 11, and 13 were all born in an October and ceased to be [supported] the June thereafter. They do not enjoy the long-term support (LTS) the even majors do. It is the way.

This odd characteristic of the release schedule stems from the fact that every 6 months, the major version of Node is incremented, in April and in October (Hah! Ubuntu and Node bump together! See the inspiraysh y'all!?). In contrast to the odd majors' 2 short months of life after they are superseded, even majors are afforded an additional 30 months of life after their 6 months in the spotlight, which unfolds in total thusly:

  • 6 months of Current status, in which all Nodes discover themselves, try on new ideas, fashions, and risks
  • 12 months of Active LTS status, in which LTS Nodes leave behind the recklessnesses of their respective youths and settle down in search of stability
  • 18 months of Maintenance LTS status, in which LTS Nodes have lived a full life, hear no new tales, and don't give a fuck about nothin unless it's ab.so.lute.ly. critical

And then they die as all Nodes do. Leaving only their epitaphs to remind us of the long (umm, short) journey we've been on.



Now up until this point, this has just been facts. Weirdly personified facts. But still facts. So here's where it gets opinionated, and you can leave now and be your own guide, or you can follow me through the haunted "WHY ARE THERE SO MANY FUCKING VERSIONS OF NODE!?" forest to more fully satisfy the question that brought you here.

Let's define a general guideline

According to, umm, we'll call it a school of thought (how many people constitute a "school"?), the time to begin using an even major is when the following even major is released (in April as you know). So the preferred Node version, according to this school, went from 10 to 12 when 14 was released (and yes I know how confusing that sounds). As the priority of a Node "LTS line" shifts to stability, it's good to let the dust settle a bit, and for new backportable features in the subsequent odd major to finish being ported, and to also have time for those ports to prove their stability as well. So around April is when the preferred Node version makes the jump. It's important to note here that this timing is for the launching of software, not beginning development on projects, not bumping the default version of local development, not upgrading production systems (that's covered shortly). So, the general guideline is this:

Use the latest LTS line that has been out for at least one year on launch day

You can fudge a little on the one year bit. Maybe 11 months, maybe 10 months. But if it's less than that, you're asking the wrong question. It shouldn't be, "What version of Node should we use?" The question you should be asking is, "Why are we launching in December or January?"



There are always reasons to deviate from this or any other guideline. I will not enumerate or discuss them here. But this guideline has four attributes that foster nice dev and devops experiences to make it a compelling approach.

  1. With 6(-ish) months of stability-focused releases, it's a more comfortable proposition to "turn on automatic updates" to reduce devops time and effort (use the means defined at the beginning of this article to specify "automatic updates" according to your Node/Docker setup—that is, pinning to the LTS line (not a specific MAJOR.MINOR.PATCH version) like AWS, Google, Microsoft, and dojo4 all do, so just trust us ;)—of note, by using the "codename" (e.g. erbium) instead of the MAJOR.x branch, you literally cannot express a non-LTS Node release (i.e. Node 14 doesn't have a codename yet)
  2. You will likely have all or most of the Maintenance LTS cycle left after your team has dealt with post-launch madnesses. And are therefore well-positioned to isolate the time of year y'all are going to begin your new annual Node upgrade ritual, which will keep you in the latest Maintenance LTS line for the life of the project. You after all chose Node (or the market did for you). And this whole annual bit's a part of the deal.
  3. Timing your Node version choice like this will also keep your dev team in-line with managed Node environments without much planning or thought, or even any if we're lucky (*snap!* Google Cloud Functions! Quick dragging your feet and join the rest of the class!), as the [rest of the] field of cloud providers aligns with managed Node environments launching closer and closer to the date that lines enter LTS—of note, no managed Node environment for the big 3 (or the new young crop of Netlifys and ZEITs/Vercels) have ever supported odd majors or pre-LTS even majors)
  4. This approach is also a good compromise to not impose more legacier Node versions on the dev team in the name of security, as part of a more conservative strategy. But it's also not going too edge—potentially creating unnecessary devops churn, coordination, and headaches—trying to satiate your JavaScript team's hunger for the new and shiny, which you may or may not know is not a business case for making technology decisions.



A few notes about the notion of an annual upgrade that I can already hear you complaining about. This probably feels ridiculous if you've come from Ruby or Python where minor versions have 3½-ish years of support, or Java where, fuck, LTS support lasts longer than any JavaScript project has ever lived. Although in a sense, because Node majors auto-increment biannually, they are more analogous to minor releases in other languages. Except that they're truly SEMVER and backward-breaking, and never mind. Skipping only one annual upgrade means jumping 3 backward-breaking versions. This will often be more costly in pure development hours (depending on the app, of course, whatever, but probably not). And this is not to mention the lack of any future security fixes is taking the safeties off the guns aimed at your company, its operations, your data, your customers, their data, your users, their data, and on and on. The number and caliber of guns vary from company to company, but even if you block all IPs from Russia and China, that number is not 0. And do I need to make the business case for not wasting time and resources on cleaning up avoidable messes caused by a patten of poor security hygiene (which would extend beyond Node projects, if there is organizational reticence to upgrade live systems on a routine schedule)? No you're right I don't. You know to Keep. Your. Shit. Up. To. Date.



So go use Node Erbium now!

And when you're planning to launch a Node project in Q2 of next year when:

  • Node 16 is released
  • Node 15 is sunsetting
  • Node 14 is in Active LTS
  • Node 12 is in Maintenance LTS
  • Node 10 is in Maintenance LTS too, but sunsetting

You can say to your team:

Hey y'all.

Let's use Node Fluorine* or whatever.

Because reasons.



* Word on the street is it will be Fermium, but I like the flow of Node Fluo. Keep an eye here if you want to get wise to when it becomes official.

Attribution:
SVG form of a d20 die by HeadsOfBirds from The Noun Project