Skip to content

Add nvm prune command to clean up old versions#3792

Open
esguerrag wants to merge 9 commits intonvm-sh:masterfrom
esguerrag:prune-outdated-versions
Open

Add nvm prune command to clean up old versions#3792
esguerrag wants to merge 9 commits intonvm-sh:masterfrom
esguerrag:prune-outdated-versions

Conversation

@esguerrag
Copy link

@esguerrag esguerrag commented Feb 23, 2026

Description

This PR introduces a new command, nvm prune, which allows users to easily clean up old, unused Node.js versions from their local installation while ensuring important versions are kept safe.

Motivation

Over time, users accumulate many patch versions of Node.js (e.g., v14.17.0, v14.17.1, v14.17.2). Manually finding and uninstalling these old versions is tedious. nvm prune automates this maintenance task by keeping only the latest version of each major release installed. This also was requested back in 2016

Behavior & Rules

When running nvm prune, it iterates through all installed versions and applies the following retention policy for each version group:

  1. Keep the Latest: The most recent version of a major release is always preserved (e.g., if you have v16.1.0 and v16.2.0, v16.2.0 is kept).
  2. Keep the Current: The currently active version (in use by the shell) is never deleted, even if it is not the latest in its group.
  3. Keep Minor (Optional): If the --minor flag is used, the command preserves the latest version of each minor group (e.g., keeps both the latest v18.19.x and v18.20.x).
  4. Prune the Rest: All other versions in that group are uninstalled.
  5. Best Effort: If uninstalling a specific version fails (e.g., permission error), the command logs the error and proceeds with the rest of the list.

Features

  • --dry-run support: Preview which versions would be removed without actually deleting anything.
  • Safety Warning: Detects and warns if a version to be pruned contains global npm modules (other than npm itself).
  • Resiliency: A failure to uninstall one version does not stop the process for others.
  • Comprehensive: Includes iojs versions in the pruning logic.

Implementation Details

  • POSIX Compliance:
    • Replaced grep -o (GNU extension) with standard awk.
    • Added a fallback for sort -V (GNU extension) to use standard sort with field keys (-k 1.2,1n ...) to ensure correct version ordering on all systems.
  • Added nvm_prune internal function and exposed it via the main nvm command switch.

Usage Examples

# Preview what would be removed
nvm prune --dry-run
# Run the cleanup (latest per major)
nvm prune
# Keep the latest of each minor version
nvm prune --minor

Test Plan

  • Verified nvm prune --dry-run lists candidates without uninstalling.
  • Verified nvm prune correctly identifies the "latest" version per major version group.
  • Verified nvm prune does not remove the currently active version.
  • Verified compatibility with bash and zsh.

@ljharb
Copy link
Member

ljharb commented Feb 23, 2026

To be clear, #1195 doesn't have a "PR wanted" label, so I'm still not convinced we should add this. The linked comment also says

i'd certainly prefer nvm prune to require a numeric version filter.

That said, why would iojs versions be excluded? Also, it should probably indicate which versions it's about to remove that have global npm modules installed, since that's the only info that'll really be "lost".

Personally, I want to have the latest version of every minor installed, not just every major. It would be nice to add a flag here to have that behavior.

@ljharb
Copy link
Member

ljharb commented Feb 23, 2026

Can you also clarify if you used any LLMs to write the code (which might make it uncopyrightable and potentially not viable to contribute to open source) or the OP?

@esguerrag
Copy link
Author

Got it, now I understand the hesitation and since it wasn't discussed for a long time now I see why it wasn't added.
To address your questions:

  • I thought that iojs it's tricky to maintain with the prefixes, so I consider that's safer not to touch it and skip it. But if you want to, I can add it too.
  • On the npm side, you are right but I would need to dig a little bit further to add that check.
  • For the minor versions we can have a keep-minor flag. Would you like that?
  • I did used some LLM help to ensure the posix compliance of my code since I'm mostly used to bash.

Thank you for your input and looking forward to solve any doubts.

@ljharb
Copy link
Member

ljharb commented Feb 23, 2026

There's helpers to add or remove the prefixes, so you can compare the versions as one single list.

How about --minor?

That level of LLM usage is perfectly fine; thanks for confirming.

@esguerrag
Copy link
Author

I've just pushed the updates. I added the --minor flag to keep minor versions, and updated the logic to include iojs. I also added the safety check for global npm packages when prune is going to run.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants