Auto switch Node.js version using NVM & ZSH hooks

I'm using Ghostty with ZSH + OhMyZsh as my terminal setup. In all my projects I add an .nvmrc file to pin the Node.js version in code. This allows me to use the same version in GitHub Actions and easily match the Node.js version used in the production Docker images.

Switching Node.js versions manually is as simple as running:

nvm install

However, it would be more convenient if this happened automatically when changing directories or opening a terminal in a specific project folder. This behavior can be achieved using ZSH hooks.

Add the following snippet to your .zshrc file:

# Auto-switch Node.js versions when .nvmrc is present
autoload -U add-zsh-hook

load_nvm_version() {
  if [[ -f .nvmrc ]]; then
    nvm use || nvm install
  fi
}

add-zsh-hook chpwd load_nvm_version
load_nvm_version

With this setup, your Node.js environment will always match the expected version without manual intervention. Bonus: this should work in the built-in terminal of your editor of choice as well.

Update 12/02/2025

Someone pointed out in the comments the existence of fnm. It's a drop-in replacement for nvm, written in rust. It's faster and changes nvm versions out of the box when going into a folder that contains an .nvmrc file. I caved and uninstalled nvm, and removed the custom ZSH hook... 😅

Installing fnm on macOS is easy, run brew install fnm and add the following to your .zshrc:

eval "$(fnm env --use-on-cd --shell zsh)"

Bonus: add an alias to prevent annoying typos alias nvm='fnm'

Comments

Join the conversation by replying on BlueskyBluesky

W

Auto switch Node.js version using NVM & ZSH hooks wouterds.com/blog/auto-sw...

M

But isn’t slow as molasses? FNM does it out of the box and doesn’t make the whole terminal prompt hang for seconds on each `cd` github.com/Schniz/fnm/b...

W

I wouldn't say it hangs seconds on each cd, but it does add some wait time *if* there’s an .nvmrc file found, I personally don’t mind. fnm looks cool!

M

I made the switch a while back on a 2018 Intel i5 processor and it went from unbearably slow to virtually instant. Glad to hear it’s not as bad nowadays. This was the script: gist.github.com/sndrs/5940e9...

A

Use modern tooling like asdf (mac/linux) or vfox (windows) to manage nodejs. All you need to do is install versions you need and add .tool-versions file in directories you need specific version. No need for typying any commands.

L

Well but tools typically recognize only node specific stuff, like .node-version file. I have saved a lot of config time by using exactly this file in every project.

Aranet4
Power
Car
NUC