Upgrade Node.js using NVM the right way
Using the Node Version Manager (NVM) is the common way to use many Node.js versions on the same computer. It helps install a specific Node.js version, switch between versions, uninstall a version, etc...
Updating Node.js to a higher version helps use the latest features and be safe from past or current security vulnerabilities of Node.js.
To upgrade the Node.js version using NVM, run the following commands:
nvm install <node-version>
nvm alias default <node-version>
The first command download and install the Node.js version, and the second set it as the system's default version.
To upgrade to Node.js 20.5.1, run the commands below:
nvm install v20.5.1
nvm alias default v20.5.1
The "v" before the Node.js version is necessary.
The problem with global Node modules
Upgrading to a higher version is simple by using NVM. However, there is an issue you will face when trying to use a Node.js package installed globally, such as ghost-cli, aws-cdk, zx, pm2, etc...
Once you upgrade your Node.js version, all these global packages will not be found anymore.
As you can see in the picture above, after installing the new Node.js version, the Node.js packages installed locally cannot be found anymore.
This is because the global Node.js packages are installed in each Node.js managed by NVM. When you install a Node.js package globally, it is available only for the current Node.js version.
The folder location can be found at $HOME/.nvm/versions/node/<node-version>/lib/node_modules
.
To fix this issue, you should always re-install all your global packages for the new Node.js version installed.
The command to upgrade the Node.js version is the following:
nvm install <node-version>
nvm alias default <node-version>
npm install -g <package-1> <package-2> <package-3> <package-4>, ...
You must go to the previous Node.js folder to view all the global packages installed. This method works, but we can make it easier by automating it.
Automate the whole upgrade process
We will use the Bash language to write the script file, which will do the following actions:
- Retrieve the current Node.js version.
- Find all the global packages installed for this current version.
- Install the new version and set it as the current.
- Install the global packages for the current version.
The Bash script takes the Node.js version to install as an argument:
./script.sh <node-version-to-install>
Let's create a file named upgrade-node.sh
and add the code below:
#!/bin/bash
# Load NVM command so that it is recognized in the script
. $HOME/.nvm/nvm.sh
if [ $# -eq 0 ]; then
echo "Error: You must pass the Node.js version to upgrade as an argument E.g.: v20.1.3"
exit 1
fi
current_version=$( node -v )
nvm_global_libs_folder="$HOME/.nvm/versions/node/$current_version/lib/node_modules"
global_lib_folders=()
for subfolder in "$nvm_global_libs_folder"/*; do
if [ -d "$subfolder" ]; then
subfolder_name=$(basename "$subfolder")
global_lib_folders+=("$subfolder_name")
fi
done
new_node_version=$1
echo "Upgrading from node $current_version to $new_node_version"
nvm install $new_node_version
if [ $? -ne 0 ]; then
exit 1
fi
nvm alias default $new_node_version
node -v
echo "Installing global node modules..."
npm install -g "${global_lib_folders[@]}"
echo "Node.js has been upgraded successfully!!!"
Before executing the Bash script, we must make the file executable by running the following command:
sudo chmod +x upgrade-node.sh
Let's upgrade the Node.js version to the version 20.5.1
using this script:
./upgrade-node.sh v20.5.1
This is what we get now:
If you check the Node.js version in the current terminal, it will still show the old version. Open a new terminal, and verify the Node.js version and the global dependencies version:
Going further
We have a script to upgrade the Node.js version using a single command, but there are still some improvements to make:
- Ask if we want to uninstall the old Node.js version.
- Create an alias so you can run the script from everywhere.
- Clean the NVM cache installation directory.
Follow me on Twitter or subscribe to my newsletter to avoid missing the upcoming posts and the tips and tricks I occasionally share.