# How the nvm default-packages mechanism works

> Discover how the nvm default-packages mechanism automatically installs global npm packages with new Node.js versions via a simple text file and npm install -g.

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

---

**The nvm default-packages mechanism automatically installs a set of global npm packages whenever you install a new Node.js version, reading package names from a plain-text file at `$NVM_DIR/default-packages` and executing `npm install -g` via the `nvm_install_default_packages()` function.**

The `default-packages` mechanism in nvm (Node Version Manager) streamlines development workflows by ensuring your essential global tools—like TypeScript, rimraf, or yarn—are present immediately after installing any new Node version. This feature, implemented in the main [`nvm.sh`](https://github.com/nvm-sh/nvm/blob/main/nvm.sh) script, eliminates the manual step of running `npm install -g` for your standard toolkit every time you switch Node versions.

## How nvm detects and parses the default-packages file

When an installation finishes, nvm looks for a file at `${NVM_DIR}/default-packages`. The path construction happens in the `nvm_get_default_packages()` function at lines 4571–4574 of [`nvm.sh`](https://github.com/nvm-sh/nvm/blob/main/nvm.sh):

```bash
NVM_DEFAULT_PACKAGE_FILE="${NVM_DIR}/default-packages"
if [ -f "${NVM_DEFAULT_PACKAGE_FILE}" ]; then
  # ...parsing logic...

fi

```

If the file exists, an `awk` script (lines 4575–4590) processes it with strict validation rules:

- **Comments** starting with `#` are ignored
- **Blank lines** are skipped
- **Multiple tokens** on one line cause an error
- Only **one package name per line** is permitted

The `awk` script concatenates valid package names into a single space-separated string printed to stdout.

## Installing packages via nvm_install_default_packages

The `nvm_install_default_packages()` function (lines 4592–4605) orchestrates the actual installation:

```bash
nvm_install_default_packages() {
  local DEFAULT_PACKAGES
  DEFAULT_PACKAGES="$(nvm_get_default_packages)"
  if [ -n "${DEFAULT_PACKAGES}" ]; then
    echo "Installing default global packages from ${NVM_DIR}/default-packages..."
    printf '%s\n' "${DEFAULT_PACKAGES}" | xargs -n 1 npm install -g --quiet
  fi
}

```

The function calls `nvm_get_default_packages()` to retrieve the list. If non-empty, it uses `xargs` to run `npm install -g --quiet` for each package. Any failure during this step aborts the installation and reports an error.

## Configuring your default-packages file

To use this mechanism, create a plain-text file at `$NVM_DIR/default-packages` with one package per line:

```bash
cat > "$NVM_DIR/default-packages" <<'EOF'

# Essential global tools

rimraf
object-inspect@1.0.2
stevemao/left-pad
typescript
EOF

```

Supported package name formats include:
- Simple names: `rimraf`
- Specific versions: `object-inspect@1.0.2`
- GitHub shorthand: `stevemao/left-pad`

The `.gitignore` file in the nvm repository explicitly excludes `default-packages`, ensuring your personal list remains private and is never committed.

## Skipping default packages during installation

You can bypass the default-packages mechanism by providing the `--skip-default-packages` flag:

```bash
nvm install 20.11.0 --skip-default-packages

```

When this flag is present, nvm sets `SKIP_DEFAULT_PACKAGES=true` during argument parsing (lines 666–672) and skips the call to `nvm_install_default_packages()` at the installation call site (lines 3600–3606).

## Edge cases and error handling

The implementation handles several edge cases:

- **Missing file**: If `$NVM_DIR/default-packages` does not exist, the mechanism silently skips without error
- **Empty file**: Treated identically to a missing file; no packages are installed
- **Malformed lines**: Lines containing spaces or multiple tokens trigger an error message to stderr and cause `nvm install` to exit with a non-zero status
- **Trailing newlines**: The parser handles these gracefully without creating spurious empty entries

The test suite at `test/installation_node/default-packages` verifies all these behaviors, including successful installation, skip flag functionality, and proper handling of malformed entries.

## Summary

- The **default-packages mechanism** automatically installs global npm packages whenever you install a new Node.js version through nvm
- Configuration resides in a plain-text file at **`$NVM_DIR/default-packages`**, with one package name per line and support for comments
- The **`nvm_get_default_packages()`** function parses the file using `awk`, while **`nvm_install_default_packages()`** executes `npm install -g` via `xargs`
- Use **`--skip-default-packages`** to bypass automatic installation when needed
- The mechanism includes robust error handling for missing files, empty lines, and malformed entries

## Frequently Asked Questions

### Where does nvm look for the default-packages file?

nvm looks for the file at `${NVM_DIR}/default-packages`, typically `~/.nvm/default-packages` on most systems. This path is constructed in the `nvm_get_default_packages()` function at lines 4571–4574 of [`nvm.sh`](https://github.com/nvm-sh/nvm/blob/main/nvm.sh). The file is not created by default; you must manually create it to enable the mechanism.

### What happens if a line in default-packages contains multiple words?

The `awk` parser in `nvm_get_default_packages()` validates that each line contains exactly one token. If a line contains spaces or multiple words, the parser prints an error message to stderr and `nvm install` exits with a non-zero status. This strict validation prevents accidental misconfiguration or malformed package names from causing unexpected behavior.

### Can I install specific versions of packages using default-packages?

Yes, the default-packages mechanism supports standard npm package specifiers. You can specify exact versions using the `package@version` syntax (e.g., `object-inspect@1.0.2`) or use GitHub shorthand references (e.g., `stevemao/left-pad`). The `nvm_install_default_packages()` function passes these specifiers directly to `npm install -g`, so any format npm supports will work.

### How do I prevent nvm from installing default packages?

You can bypass the default-packages mechanism by adding the `--skip-default-packages` flag to your install command, like `nvm install 20.11.0 --skip-default-packages`. This sets `SKIP_DEFAULT_PACKAGES=true` during argument parsing and prevents `nvm_install_default_packages()` from being called during the installation flow. This is particularly useful in CI environments where you want clean, minimal Node installations.