Whoever said, “The more things change, the more they stay the same” never wrote code for the Node.js environment. Since its 2009 introduction, Node.js has epitomized the dynamic nature of web application development. That dynamism spawned countless web applications. The same rapid pace of change also brought a headache for developers: Node.js versioning. Thankfully, now there are tools and techniques to tame version aggravation.
Developers Just Say Node
The Move for Predictability
The heart of their strategy was assigning releases to a pair of categories:
- Current: These releases give developers an early opportunity to program with cutting-edge features.
- Long-Term Stable: These versions receive bug fixes and security updates and are the only ones recommended for commercial software releases.
Major Node.js versions debut in April and begin with even whole numbers. October brings odd-numbered interim versions. Major releases maintain Current status for six months and then enter LTS for 30 months. Odd-numbered interim releases keep Current status for six months, receive maintenance support for two more months, and then disappear from the archive. To maintain marketability, developers have a strong incentive to keep their products compatible with LTS Node versions.
Web Apps Are Breakable
The more extensive semi-annual version changes typically bring a dozen deprecations and several removals. Deprecations are a signal to developers to rewrite their code in line with the current syntax. Removals pose a bigger problem, as these mean some packages — and the applications that depend on them — will break. With ever-increasing package counts in modern web apps, finding a compatible Node.js version for every component across a project became more and more challenging. The upshot: Modern software development now effectively requires coders to switch between Node versions in a typical workday. The early solutions to this demand were not pretty.
VMs and Re-Installs Fall Short
Virtual machines offered one way out of the Node.js version traffic jam. On a physical host computer, virtual machine software creates a fully encapsulated guest computer. The guest — the virtual machine — behaves like a physical computer in every way. With adequate memory and disk space, it is easy to have several active virtual machines and switch between them with a mouse click.
Over three decades, VMs have proven an efficient way to test desktop applications for compatibility with multiple operating systems. Nonetheless, this approach requires installing the complete programming environment on each virtual machine. Beyond installation, each programming tool requires upgrades in sync across all VMs. Despite their one-click simplicity, the overhead of VMs makes them poorly suited for Node version switching.
Rather than take on resource-hungry VMs, some developers opted to perform a fresh installation of Node.js versions as needed. The installation cycle is relatively quick. If developers organized their workday, they could hold re-installations down to a tolerable minimum. While avoiding the bloat of a VM, re-installs sacrificed rapid version switching. Node developers needed an agile and low-resource solution. Their answer made a quiet entrance.
A Bash Script Vanquishes Version Vexation
Frustrated with the existing solutions, developer Tim Caswell posted the first version of his Node Version Manager to GitHub in 2010. nvm was a Bash script that enabled users to choose between multiple Node.js installations by typing short commands into a shell. At the outset, nvm natively supported the Linux and Apple macOS operating systems. Though originating as a Bash script, nvm also plays well with the Dash, Zsh, and Ksh shells.
nvm’s Concise Commands Curb a Conundrum
Installation of nvm or nvm-windows is straightforward, but a careful reading of the troubleshooting guides heads off difficulties. With nvm installed, typing “nvm install” in the command-line interface is all it takes to download and install the most recent Long-Term Stable version of Node.js. Here are some other example commands:
- nvm install 12.2.1 installs this version number.
- nvm install 14.6 installs the most recent patch of the version headed by this number.
- nvm install node installs the most recent Current release.
- nvm use 14.3.0 makes this numbered Node.js version the active one in the current shell.
- nvm ls displays a color-coded list of currently installed Node.js versions, with the active installed version shown in green.
- nvm —help brings up a glossary of nvm commands.
What happens when a coder breaks for lunch, returns to the screen, and can’t remember the active version? Typing “nvm current” reveals the current active Node.js version.
For developers with packages on a worldwide registry, nvm’s friendly command structure makes compatibility testing a snap. Programmers can install a series of Node.js versions and test the package with successively older versions until the code breaks. Though nvm works well as a version switcher, some careful strategies can multiply the utility’s power.
nvm Customizes the Programming Environment
To function, nvm must park each downloaded node.js version in an individual folder. This structure means that developers are no longer limited to a single set of globally installed tools. For example, a developer may find the latest version of TypeScript breaks a project using Node.js 14.17.6 but works well with a second project using version 12.22.6. With the nvm file structure, it’s straightforward to install different TypeScript versions in the appropriate version folder. Using this capability, nvm moves beyond Node version switching and instead becomes a programming environment manager.
The Name Game
With individual Node.js folders customized for different projects, it can be more convenient to reference a Node version by name instead of a number. nvm’s “alias” command makes this possible. Some examples:
- alias default 12.22.6
- alias esm-test 16.9.1
- alias mycoolproject-alpha 14.17.6
- alias mycoolproject-stable 12.22.6
With aliases assigned, programmers may use names interchangeably with version numbers in nvm’s “use” command. Establishing naming conventions is a good practice for team settings. While aliases add user-friendliness, developers still must ascertain that they are using the correct Node version for the project. Automating this decision is surprisingly easy.
A Tiny Text File Keeps Coders Copacetic
In the frequently hectic web app development environment, coding with the correct Node version for a project is critical. nvm’s “current” command reveals the active Node.js version, but a harried coder could easily forget to perform this check and waste hours coding for the wrong iteration. Ideally, beginning a project work session would trigger a change to the correct Node version. A one-line text file accomplishes just that. The process is as simple as saving a text file with the filename ”.nvmrc” in a project’s root directory. The file need only contain an appropriate Node version number matching this format:
This saved text is a runtime configuration file, hence the “rc” in the filename. When a developer navigates to a project’s root directory and invokes the “npm use” command, npm looks for the .nvmrc file and then activates the correct Node version. The runtime configuration file shines in team settings, keeping all coders in sync on the same Node version.
SOOS Keeps Pace With Every Version of Every Tool
The intricate nature of Node.js versioning makes a compelling case for a seamless software compatibility analysis solution. Security is not an option when you deploy web apps. That’s why SOOS monitors a constantly updated list of over 150,000 vulnerabilities. A SOOS scan spots security risks in the development phase and highlights the threats on a user-friendly dashboard. CI/CD integration means you can break your build before vulnerable code ever makes it out into the wild. License compliance parallels the versioning challenge in modern software development. SOOS keeps developers in total command of compliance issues, scanning every file of every project and reporting the status in a dashboard. It works with most frameworks, languages, and CI/CD platforms in the modern software development workflow. While versioning remains a challenge for developers, SCA could not be easier: keep it simple with SOOS.