← Back

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.