# How nvm Deactivate Restores Your Shell PATH: Implementation Deep Dive

> Learn how nvm deactivate restores your shell PATH by removing Node.js directories and unsetting environment variables, returning your shell to its original state.

- Repository: [nvm.sh/nvm](https://github.com/nvm-sh/nvm)
- Tags: internals
- Published: 2026-02-27

---

**The `nvm deactivate` command removes all nvm-managed Node.js directories from your `$PATH`, `$MANPATH`, and `$NODE_PATH`, then unsets the `NVM_BIN` and `NVM_INC` environment variables to return your shell to its pre-nvm state.**

When working with multiple Node.js versions in the **nvm-sh/nvm** repository, understanding how `nvm deactivate` cleans up your shell environment helps debug path conflicts and ensures clean version switching. This command is implemented as a sub-command within the main `nvm()` function in [`nvm.sh`](https://github.com/nvm-sh/nvm/blob/main/nvm.sh), utilizing a specialized path-stripping helper to surgically remove nvm-specific entries.

## How the nvm Deactivate Command Works

The `nvm deactivate` implementation resides in **[`nvm.sh`](https://github.com/nvm-sh/nvm/blob/main/nvm.sh)** around lines 3806–3852. When invoked, it executes a four-step cleanup process that systematically removes nvm's influence from your shell session.

### Parsing Command Flags

The command first checks for the optional **`--silent`** flag to suppress warning messages. If your `$PATH` does not contain any nvm-managed directories, `nvm deactivate` normally prints a warning indicating there is nothing to deactivate. The `--silent` flag prevents this output, making it ideal for use in automated scripts or shell profiles.

### Stripping nvm Paths from PATH

The core functionality relies on the **`nvm_strip_path`** helper function defined at lines 982–999 in [`nvm.sh`](https://github.com/nvm-sh/nvm/blob/main/nvm.sh). This function takes a colon-separated path list and a suffix pattern, then removes any entry that starts with `$NVM_DIR` and ends with the specified suffix.

When `nvm deactivate` runs, it executes:

```bash
NEWPATH="$(nvm_strip_path "${PATH}" "/bin")"
export PATH="${NEWPATH}"
\hash -r

```

The **`nvm_strip_path`** function scans through `$PATH`, identifies directories matching `$NVM_DIR/*/bin`, and reconstructs the path without those entries. The `\hash -r` command clears the shell's command hash table, ensuring that the `node` and `npm` binaries from the removed directories are no longer cached.

### Cleaning Auxiliary Environment Variables

Beyond `$PATH`, the command cleans two additional environment variables that may contain nvm-managed paths:

- **`$MANPATH`** – Strips entries ending with `/share/man` to remove nvm's manual pages
- **`$NODE_PATH`** – Strips entries ending with `/lib/node_modules` to remove nvm's global module paths

Both use the same `nvm_strip_path` helper with their respective suffixes, ensuring complete removal of nvm-specific directories from your shell's library and documentation search paths.

### Unsetting nvm Internal Variables

Finally, the command unsets the helper variables that `nvm use` creates to track the active Node.js version:

```bash
unset NVM_BIN
unset NVM_INC

```

**`NVM_BIN`** stores the path to the active Node.js binary directory, while **`NVM_INC`** stores the path to the Node.js include directory used for compiling native addons. Removing these variables ensures that build tools and scripts cannot accidentally reference the deactivated Node.js installation.

## Practical Examples of nvm Deactivate

### Basic Deactivation Workflow

```bash

# Check current Node version and path

$ nvm use 20
Now using node v20.11.0 (npm v10.2.4)
$ which node
/home/user/.nvm/versions/node/v20.11.0/bin/node

# Restore original PATH

$ nvm deactivate
/home/user/.nvm/versions/node/v20.11.0/bin removed from $PATH
$ which node
/usr/bin/node

```

### Silent Deactivation in Scripts

```bash
#!/bin/bash

# Ensure clean environment before running system node

nvm deactivate --silent

# Now use the system-installed node without nvm interference

/usr/bin/node --version

```

### Manual PATH Inspection

```bash

# Preview what nvm_strip_path would remove

$ nvm_strip_path "$PATH" "/bin"
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# Compare with current PATH

$ echo $PATH
/home/user/.nvm/versions/node/v18.19.0/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

```

## Summary

- **`nvm deactivate`** is implemented in [`nvm.sh`](https://github.com/nvm-sh/nvm/blob/main/nvm.sh) (lines 3806–3852) as a sub-command that reverses the environment changes made by `nvm use`.
- The **`nvm_strip_path`** helper function (lines 982–999) performs the core logic of removing nvm-specific directories from colon-separated path variables.
- The command cleans **`$PATH`** (removing `*/bin`), **`$MANPATH`** (removing `*/share/man`), and **`$NODE_PATH`** (removing `*/lib/node_modules`).
- It unsets the internal tracking variables **`NVM_BIN`** and **`NVM_INC`** to complete the deactivation process.
- The **`--silent`** flag suppresses warnings when no nvm paths are present in the current environment.

## Frequently Asked Questions

### What is the difference between `nvm deactivate` and `nvm unload`?

**`nvm deactivate`** only removes nvm-managed Node.js directories from your shell environment variables, returning you to the state before the last `nvm use` command. **`nvm unload`** goes further by removing the `nvm` function itself and all associated shell hooks, effectively uninstalling nvm from the current session. Use `deactivate` to switch to system Node.js temporarily; use `unload` when you need to completely remove nvm's presence from your shell.

### Why does `nvm deactivate` run `hash -r` after modifying PATH?

The **`hash -r`** command clears the shell's internal command hash table, which caches the locations of executables to avoid repeated PATH lookups. When `nvm deactivate` removes the nvm-managed `bin` directories from PATH, shells like bash would still remember the old locations of `node` and `npm` from their hash table. Running `hash -r` forces the shell to search PATH fresh on the next command invocation, ensuring it finds the correct binaries (or returns "command not found" if no system Node.js exists).

### Does `nvm deactivate` affect other shells or terminal sessions?

**No**, `nvm deactivate` only affects the current shell session where you run the command. Environment variables like `$PATH` are inherited by child processes but not shared with parent processes or sibling shells. If you open a new terminal tab or window, it will start with its own environment—either with nvm active (if your shell profile sources nvm) or without it. To permanently stop using nvm across sessions, you would need to remove the nvm initialization lines from your shell profile file (e.g., `~/.bashrc`, `~/.zshrc`).

### How can I verify that `nvm deactivate` worked correctly?

Run the **`which node`** command before and after deactivation. Before deactivation, it should return a path inside your `$NVM_DIR` (e.g., `/home/user/.nvm/versions/node/v20.11.0/bin/node`). After running `nvm deactivate`, it should either return the path to your system Node.js (e.g., `/usr/bin/node`) or display nothing if no system Node.js is installed. Additionally, you can check that the environment variables are unset by running **`echo $NVM_BIN`** and **`echo $NVM_INC`**, which should return empty strings after deactivation.