Here is a basic tip for using Node Version Manager (NVM) along with ZShell, the default shell editor.
NVM will let you switch between node versions. That means you can switch between projects and use different versions of Node. Normally, you’ll use nvm use
to change versions. However, it is preferable to use this simple shell script that will automatically switch for you.
Like your Ruby version, your Node version should be specified in the root of your project repository using a .node-versoin
file. This hidden file exists in your repository and gets checked into your codebase like the other hidden config files (.gitignore
, .ruby-version
, etc)

Now you will add this script to your .zshrc file. IN your .zshrc file, look for your existing NVM setup like this:
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && . "$NVM_DIR/bash_completion" # This loads nvm bash_completion
You will want to add this code to below this setup:
# NVM automatically switch to correct node version when switching directories
nvm_find_node_version_file() {
local dir
dir="$(nvm_find_up '.node-version')"
if [ -e "${dir}/.node-version" ]; then
nvm_echo "${dir}/.node-version"
fi
}
auto-switch-node-version() {
NODE_VERSION_PATH=$(nvm_find_node_version_file)
CURRENT_NODE_VERSION=$(nvm version)
if [[ ! -z "$NODE_VERSION_PATH" ]]; then
# .node-version file found!
# Read the file
REQUESTED_NODE_VERSION=$(cat $NODE_VERSION_PATH)
# Find an installed Node version that satisfies the .node-version
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 .node-version.
# Quit silently if we already just warned about this exact .node-version file, so you
# only get spammed once while navigating around within a single project.
if [[ $AUTOSWITCH_NODE_SUPPRESS_WARNING == $NODE_VERSION_PATH ]]; then
return
fi
# Convert the .node-version path to a relative one (if possible) for readability
RELATIVE_NODE_VERSION_PATH="$(realpath --relative-to=$(pwd) $NODE_VERSION_PATH 2> /dev/null || echo $NODE_VERSION_PATH)"
# Print a clear warning message
echo ""
echo "WARNING"
echo " Found file: $RELATIVE_NODE_VERSION_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 .node-version file
export AUTOSWITCH_NODE_SUPPRESS_WARNING=$NODE_VERSION_PATH
fi
else
# No .node-version file found.
echo "no .node-version file was 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
Now, when you switch between projects, your Node version will automatically switch. (All projects should have the standardized .node-version
file.) It will warn you if you do not have the needed node version, which you can then install.