Automatic Node.js Version Switching via .nvmrc
The Problem
I’m currently working with several legacy projects that can’t just be upgraded to the latest Node.js version without breaking something. Each project uses its own version of Node — sometimes 14, sometimes 16 or 18. nvm already helps me switch between versions, but the process was still manual: nvm use and carefully checking for a .nvmrc file.
I wanted to eliminate this routine and set up my terminal to automatically activate the required Node version when entering a project directory. It was important that this mechanism be reliable and not require my attention.
How It Works
If there’s a .nvmrc file in the root of a project specifying the desired Node.js version, the terminal will automatically switch to that version when entering the folder. And if the required version isn’t installed yet, nvm will install it. If the file is missing, the default version is used.
How to Enable Automatic Switching
There are two ways to set it up — manually via a text editor or directly through the terminal.
1. Using a text editor
Open ~/.zshrc in VS Code:
code ~/.zshrc
Or use any other editor you prefer.
Add this to the end of the file:
# Automatically switch Node.js version using NVM
autoload -U add-zsh-hook
load-nvmrc() {
local node_version="$(nvm version)"
local nvmrc_path="$(nvm_find_nvmrc)"
if [ -n "$nvmrc_path" ]; then
local nvmrc_node_version=$(nvm version "$(cat \"${nvmrc_path}\")")
if [ "$nvmrc_node_version" = "N/A" ]; then
nvm install
elif [ "$nvmrc_node_version" != "$node_version" ]; then
nvm use
fi
elif [ "$node_version" != "$(nvm version default)" ]; then
echo "Reverting to nvm default version"
nvm use default
fi
}
add-zsh-hook chpwd load-nvmrc
load-nvmrc
Apply the changes:
source ~/.zshrc
2. Using the terminal
If you prefer a quicker method — inject the script directly from the terminal:
cat >> ~/.zshrc << 'EOF'
# Automatically switch Node.js version using NVM
autoload -U add-zsh-hook
load-nvmrc() {
local node_version="$(nvm version)"
local nvmrc_path="$(nvm_find_nvmrc)"
if [ -n "$nvmrc_path" ]; then
local nvmrc_node_version=$(nvm version "$(cat \"${nvmrc_path}\")")
if [ "$nvmrc_node_version" = "N/A" ]; then
nvm install
elif [ "$nvmrc_node_version" != "$node_version" ]; then
nvm use
fi
elif [ "$node_version" != "$(nvm version default)" ]; then
echo "Reverting to nvm default version"
nvm use default
fi
}
add-zsh-hook chpwd load-nvmrc
load-nvmrc
EOF
source ~/.zshrc
What Changed in Practice
Right now, I have four different projects, each using a different version of Node.js. I used to frequently forget to manually run nvm use, which led to build errors. Now everything works automatically, and I don’t even think about versions anymore.
This script just lives in .zshrc, and if a project has a .nvmrc, it does the job. If there’s no file — nothing happens. I recommend adding it once and never touching it again.
P.S. Yes, this isn’t the first article on the topic, but I wanted to write a short note for myself, so I don’t have to Google it again every time I set up a new computer.