Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
ZSH function to auto-switch to correct Node version
# ZSH function to auto-switch to correct Node version
# - Searches up your directory tree for the closest .nvmrc, just like `nvm use` does.
# - If you are already on the right Node version, IT DOES NOTHING, AND PRINTS NOTHING.
# - Works correctly if your .nvmrc file contains something relaxed/generic,
# like "4" or "v12.0" or "stable".
# - If an .nvmrc is found but you have no installed version that satisfies it, it
# prints a clear warning, so you can decide whether you want to run `nvm install`.
# - If no .nvmrc is found, it does `nvm use default`.
# Recommended: leave your default as something generic,
# e.g. do `nvm alias default stable`
auto-switch-node-version() {
if [[ ! -z "$NVMRC_PATH" ]]; then
# .nvmrc file found!
# Read the file
# Find an installed Node version that satisfies the .nvmrc
if [[ ! -z "$MATCHED_NODE_VERSION" && $MATCHED_NODE_VERSION != "N/A" ]]; then
# A suitable version is already installed.
# Clear any warning suppression
# Switch to the matched version ONLY if necessary
# No installed Node version satisfies the .nvmrc.
# Quit silently if we already just warned about this exact .nvmrc file, so you
# only get spammed once while navigating around within a single project.
# Convert the .nvmrc path to a relative one (if possible) for readability
RELATIVE_NVMRC_PATH="$(realpath --relative-to=$(pwd) $NVMRC_PATH 2> /dev/null || echo $NVMRC_PATH)"
# Print a clear warning message
echo ""
echo "WARNING"
echo " Found file: $RELATIVE_NVMRC_PATH"
echo " specifying: $REQUESTED_NODE_VERSION"
echo " ...but no installed Node version satisfies this."
echo " "
echo " Current node version: $CURRENT_NODE_VERSION"
echo " "
echo " You might want to run \"nvm install\""
# Record that we already warned about this unsatisfiable .nvmrc file
# No .nvmrc file found.
# Clear any warning suppression
# Revert to default version, unless that's already the current version.
if [[ $CURRENT_NODE_VERSION != $(nvm version default) ]]; then
nvm use default
# Run the above function in ZSH whenever you change directory
autoload -U add-zsh-hook
add-zsh-hook chpwd auto-switch-node-version
Copy link

polyglotdev commented Apr 12, 2020

Bro... Forgive me for cursing, but this is fucking dope. Awesome work, and thanks!!!

Copy link

polyglotdev commented Apr 12, 2020

Copy link

sshadmand commented Apr 15, 2020

Ditto @codefulDom. Thanks @callumlocke

Copy link

y-nk commented Jun 1, 2020

@callumlocke you're the Man.
Thanks a lot !

Copy link

maxjf1 commented Jul 1, 2020

Someone using it can say if it's lightweight? for usage on an low-end machine?

Copy link

callumlocke commented Aug 12, 2020

Just discovered others are using this! Thanks @polyglotdev and others for comments, made my day 😄

@maxjf1: while I haven't tried it on a super low-end machine, it's very fast for me, and performance was a main motivation for writing it. While nvm use does take a couple of seconds to run on my machine, this function adds no perceptible overhead for me (and it's designed to avoid calling nvm use unless really necessary).

Copy link

robertg042 commented Nov 16, 2020

@callumlocke Works like a charm! Thanks!

Copy link

kjwierenga commented Feb 1, 2021

Is anyone using the avn + avn-nvm packages? How does this compare? I think it supports .nvmrc too.

Copy link

joshuarule commented Mar 22, 2021

Thank you for this!

Copy link

y0n3r commented Apr 5, 2021

Very nicely done, but this function unfortunately creates a very noticeable lag in my shell when I switch directories...

Copy link

agjs commented Mar 16, 2022

Thanks a bunch for taking the time and making this. Cheers

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment