Skip to content

[New] add prune command - #3792

Open
esguerrag wants to merge 3 commits into
nvm-sh:masterfrom
esguerrag:prune-outdated-versions
Open

esguerrag wants to merge 3 commits into
nvm-sh:masterfrom
esguerrag:prune-outdated-versions

Conversation

@esguerrag

@esguerrag esguerrag commented Feb 23, 2026 •

Copy link
Copy Markdown

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

ljharb commented Feb 23, 2026

Copy link
Copy Markdown
Member

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

ljharb commented Feb 23, 2026

Copy link
Copy Markdown
Member

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
Copy Markdown
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

ljharb commented Feb 23, 2026

Copy link
Copy Markdown
Member

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
Copy Markdown
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.

@ljharb
ljharb force-pushed the prune-outdated-versions branch from b0f5986 to cc9ff83 Compare March 24, 2026 22:00
@ljharb

ljharb commented Mar 24, 2026

Copy link
Copy Markdown
Member

The dry-run output could use some polish - i don't mind the debug output if NVM_DEBUG is set, but it shouldn't be shown by default.

@ljharb
ljharb marked this pull request as draft March 24, 2026 22:01
@esguerrag
esguerrag marked this pull request as ready for review March 25, 2026 20:42
@esguerrag

Copy link
Copy Markdown
Author

The output was fixed to make sense and adding the flag for NVM_DEBUG to show the debbuging steps only when is set.

@esguerrag
esguerrag force-pushed the prune-outdated-versions branch from 57eda06 to 22f15d0 Compare April 6, 2026 16:41
@esguerrag
esguerrag force-pushed the prune-outdated-versions branch from 22f15d0 to 2e51789 Compare April 30, 2026 00:03
@slow6r

This comment was marked as spam.

@esguerrag esguerrag closed this Oct 1, 2026
@esguerrag
esguerrag deleted the prune-outdated-versions branch October 1, 2026 18:50
@ljharb

ljharb commented Oct 5, 2026

Copy link
Copy Markdown
Member

@esguerrag are you no longer interested in adding this feature?

@schnare22

This comment was marked as spam.

@esguerrag

Copy link
Copy Markdown
Author

@ljharb Yes, I'm still interested in landing this feature. Since this branch got a bit stale, I'll go ahead and open a fresh PR with an updated implementation shortly.

@ljharb

ljharb commented Oct 5, 2026

Copy link
Copy Markdown
Member

I would vastly prefer you restore the branch and reopen the PR, and then force push whatever changes you want to that branch.

@esguerrag
esguerrag restored the prune-outdated-versions branch October 5, 2026 17:08
@esguerrag esguerrag reopened this Oct 5, 2026
@esguerrag
esguerrag force-pushed the prune-outdated-versions branch 2 times, most recently from 2c0b952 to ebd9b6f Compare October 5, 2026 19:16
@esguerrag

Copy link
Copy Markdown
Author

@ljharb Understood. The PR is open again and rebased with one change. Thanks!

schnare22

This comment was marked as spam.

@ljharb ljharb changed the title Add nvm prune command to clean up old versions [New] add prune command Oct 9, 2026
@ljharb
ljharb force-pushed the prune-outdated-versions branch from ebd9b6f to 1122a76 Compare October 9, 2026 20:04

@ljharb ljharb left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for working on this - pruning old versions is a nice feature to have. There are some problems that need fixing before it can land, though (inline below); the most important is that it currently deletes aliased versions, including default, and the aliases themselves.

A couple of broader things:

  • Since this is a bulk, irreversible delete, I'd like it to show what it's going to remove and ask for confirmation (with a flag to skip the prompt for scripts), rather than requiring --dry-run to see that ahead of time. Note that it also can't know which versions projects' .nvmrc files pin.
  • The help text should say what's kept: the newest per group, the current version, and (once fixed) anything an alias points to.
  • Progress messages are only shown under NVM_DEBUG=1; the "Pruning…"/"Dry run" lines seem worth showing normally.

Comment thread nvm.sh
Comment thread nvm.sh Outdated
Comment thread nvm.sh Outdated
Comment thread nvm.sh Outdated
Comment thread nvm.sh Outdated
Comment thread test/fast/Running 'nvm prune' should remove old versions Outdated
@ljharb
ljharb marked this pull request as draft October 9, 2026 20:17
@schnare22

This comment was marked as spam.

@schnare22

This comment was marked as spam.

@esguerrag
esguerrag marked this pull request as ready for review October 12, 2026 03:37
@esguerrag
esguerrag requested a review from ljharb October 12, 2026 03:37
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.

4 participants