Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
ZSH function to auto-switch to correct Node version
####
# ZSH function to auto-switch to correct Node version
# https://gist.github.com/callumlocke/30990e247e52ab6ac1aa98e5f0e5bbf5
#
# - 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() {
NVMRC_PATH=$(nvm_find_nvmrc)
CURRENT_NODE_VERSION=$(nvm version)
if [[ ! -z "$NVMRC_PATH" ]]; then
# .nvmrc file found!
# Read the file
REQUESTED_NODE_VERSION=$(cat $NVMRC_PATH)
# Find an installed Node version that satisfies the .nvmrc
MATCHED_NODE_VERSION=$(nvm_match_version $REQUESTED_NODE_VERSION)
if [[ ! -z "$MATCHED_NODE_VERSION" && $MATCHED_NODE_VERSION != "N/A" ]]; then
# A suitable version is already installed.
# Clear any warning suppression
unset AUTOSWITCH_NODE_SUPPRESS_WARNING
# Switch to the matched version ONLY if necessary
if [[ $CURRENT_NODE_VERSION != $MATCHED_NODE_VERSION ]]; then
nvm use $REQUESTED_NODE_VERSION
fi
else
# 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.
if [[ $AUTOSWITCH_NODE_SUPPRESS_WARNING == $NVMRC_PATH ]]; then
return
fi
# 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
export AUTOSWITCH_NODE_SUPPRESS_WARNING=$NVMRC_PATH
fi
else
# No .nvmrc file found.
# Clear any warning suppression
unset AUTOSWITCH_NODE_SUPPRESS_WARNING
# Revert to default version, unless that's already the current version.
if [[ $CURRENT_NODE_VERSION != $(nvm version default) ]]; then
nvm use default
fi
fi
}
# Run the above function in ZSH whenever you change directory
autoload -U add-zsh-hook
add-zsh-hook chpwd auto-switch-node-version
auto-switch-node-version
@polyglotdev
Copy link

polyglotdev commented Apr 12, 2020

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

Loading

@polyglotdev
Copy link

polyglotdev commented Apr 12, 2020

Loading

@sshadmand
Copy link

sshadmand commented Apr 15, 2020

Ditto @codefulDom. Thanks @callumlocke

Loading

@y-nk
Copy link

y-nk commented Jun 1, 2020

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

Loading

@maxjf1
Copy link

maxjf1 commented Jul 1, 2020

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

Loading

@callumlocke
Copy link
Author

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).

Loading

@robertg042
Copy link

robertg042 commented Nov 16, 2020

@callumlocke Works like a charm! Thanks!

Loading

@kjwierenga
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.

Loading

@joshuarule
Copy link

joshuarule commented Mar 22, 2021

Thank you for this!

Loading

@y0n3r
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...

Loading

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