Auto nvm use

I use nvm to manage my version of node which makes it easy to use the right version of node for specific projects. What has annoyed me with nvm is opening up a directory in terminal and running npm only to get:

-bash: npm: command not foundCode language: Shell Session (shell)

I’d have to remember to run nvm install after navigating to a project directory (where an .nvmrc is located). My annoyance finally spurred me to action today and I looked up if there was some way to do it automatically. Naturally, someone asked this exact question on Stackoverflow: run nvm use automatically every time there’s a .nvmrc file on the directory. The fifth answer points over to the nvm official docs on how to automatically call nvm use. The problem with that official answer is that it requires that you use its aliased cd command to navigate to a directory; it doesn’t work if you use something like autojump. So I modified it to incorporate the PROMPT_COMMAND injection approach from the higher-ranked answers. I’ve also improved performance by persisting the default version and local version in environment variables which avoid unnecessary subshells for nvm. Here’s what I’ve got in my .bashrc now:

autonvm() {
	nvm_path=$(nvm_find_up .nvmrc | tr -d '\n')

	# If there are no .nvmrc file, use the default nvm version
	if [[ ! $nvm_path = *[^[:space:]]* ]]; then

		if [[ -z $nvm_default_version ]]; then
			nvm_default_version=$(nvm version default);

		# If there is no default version, set it to `node`
		# This will use the latest version on your machine
		if [[ $nvm_default_version == "N/A" ]]; then
			nvm alias default node;
			nvm_default_version=$(nvm version default);

		# If the current version is not the default version, set it to use the default version
		if [[ $(nvm current) != $nvm_default_version ]]; then
			nvm use default;

	elif [[ -s $nvm_path/.nvmrc && -r $nvm_path/.nvmrc ]]; then

		# `nvm ls` will check all locally-available versions
		# If there are multiple matching versions, take the latest one
		# Remove the `->` and `*` characters and spaces
		# `nvm_local_version` will be `N/A` if no local versions are found
		if [[ -z $nvm_local_version ]]; then
			nvm_local_version=$(nvm ls --no-colors "$nvm_version" | tail -1 | tr -d '\->*' | tr -d '[:space:]')

		# If it is not already installed, install it
		# `nvm install` will implicitly use the newly-installed version
		if [[ "$nvm_local_version" == "N/A" ]]; then
			nvm install "$nvm_version";
		elif [[ $(nvm current) != "$nvm_local_version" ]]; then
			nvm use "$nvm_version";
export PROMPT_COMMAND="$PROMPT_COMMAND; autonvm"Code language: Bash (bash)

Now when I open a new tab in iTerm and I’m in my home directory, I see first:

Now using node v16.14.2 (npm v8.5.0)Code language: Shell Session (shell)

And if I then cd into a directory with an .nvmrc containing 14 (or a subdirectory of such a directory), I see:

Found '/Users/westonruter/foo/.nvmrc' with version <14>
Now using node v14.19.3 (npm v6.14.17)Code language: Shell Session (shell)

Much better!

Prior to seeing that official answer, I had improved upon the third answer as follows:

  • Prevent clobbering any existing COMMAND_PROMPT (e.g. from autojump).
  • Run when first starting a terminal session (when $PREV_PWD is empty).

Here’s what I previously added to my .bash_profile:

run_nvm_use_when_directory_changed() {
	if [[ $PWD == $NVM_PREV_PWD ]]; then

	# Do nothing if a previously-seen parent directory has an .nvmrc.
	if [[ $NVM_DIRTY = true ]] && [[ ! -z $NVM_PREV_PWD ]] && [[ $PWD =~ $NVM_PREV_PWD ]]; then

	if [[ -f ".nvmrc" ]]; then
		nvm use
	elif [[ $NVM_DIRTY = true ]] || [[ -z $NVM_PREV_PWD ]]; then
		nvm use stable

export PROMPT_COMMAND="$PROMPT_COMMAND; run_nvm_use_when_directory_changed"Code language: Bash (bash)

The problem with this version is that it doesn’t recognize the .nvmrc from an ancestor directory if you started a session in a subdirectory. The official answer from nvm addresses that problem by use of nvm_find_up to recursively search for the file in ancestor directories.

2 replies on “Auto nvm use”

Thanks for sharing this, great idea. Haven’t tried it yet but found the same issue, even though I only ever run nvm use --lts. Would be nice to not have to run that every time I open a new terminal.

Leave a Reply

Your email address will not be published. Required fields are marked *