Skip to content

Instantly share code, notes, and snippets.

@peabnuts123
Created October 16, 2022 23:17
Show Gist options
  • Save peabnuts123/e784d4b0eb8d327850fa08ccd780369d to your computer and use it in GitHub Desktop.
Save peabnuts123/e784d4b0eb8d327850fa08ccd780369d to your computer and use it in GitHub Desktop.
Don't load nvm until its used, and automatically call `nvm use` when changing directories.

Lazy-load nvm and automatically call nvm use

There's some nice tooling around for managing nvm, such as zsh-nvm. However, I have found this tooling somewhat insufficient, or having poor performance.

For my needs, all I want is to increase the performance of my shell startup, and to run nvm use automatically whenever I navigate around the filesystem.

To these ends, I have written a very simple solution that one can include in their dotfiles. nvm is initially loaded as a shim that will load nvm when it is run, vastly decreasing my shell's initialisation time (from ~5 seconds to 0.2 seconds). For users of zsh, a chpwd hook is added which will check for a .nvmrc file in the new current directory, and run nvm use if one is found. If the specified version of node.js is not installed, nvm simply prints a message telling you to run nvm install instead - it will not do this for you. A check is also included to run on initialisation, if the shell is opened immediately into a folder containing an .nvmrc file.

Shell compatibility

Most of this functionality is cross-shell compatible. It's only the automatic calling of nvm use that depends on zsh. Other shells may have equivalent functionality to zsh hooks that you could port it to.

# ================================
# CROSS-SHELL COMPATIBLE FUNCTIONALITY
# The following functionality works without zsh. It should work in other shells like bash.
# - lazy-load nvm
# - `nvm use` on shell init
# - tab completion for nvm
# ================================
export NVM_DIR="${HOME}/.nvm"
# NVM
# Lazy-load NVM if it is installed
if [ -s "${NVM_DIR}/nvm.sh" ]; then
function nvm() {
# remove shim
unset -f nvm;
# load real nvm
echo "nvm being used for the first time, loading..."
source "${NVM_DIR}/nvm.sh";
nvm "$@";
}
fi
# Automatically call `nvm use` when opening a shell in a directory with `.nvmrc` in it
# (if nvm is installed)
if (declare -f nvm > /dev/null) && [ -s "$(pwd)/.nvmrc" ]; then
nvm use;
fi
# Completion for nvm (works in zsh too, despite the name)
if [ -s "${NVM_DIR}/bash_completion" ]; then
source "${NVM_DIR}/bash_completion";
fi
# ================================
# ZSH-ONLY FUNCTIONALITY
# The following functionality depends on zsh. You may be able to port it to other shells.
# - automatically call `nvm use` when changing directory
# ================================
# load functionality for zsh-hooks
autoload -U add-zsh-hook
# Register hook to run `nvm use` when changing to a directory that contains an .nvmrc file
# (if nvm is installed)
if (declare -f nvm > /dev/null); then
function __auto-nvm-use() {
if [ -s "$(pwd)/.nvmrc" ]; then
nvm use;
fi
}
add-zsh-hook chpwd __auto-nvm-use
fi
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment