Skip to content

npm install -g keeps the bin link on the old version after the default Node.js changes #3279

Description

@mondaychen

Describe the bug

When Vite+ manages Node.js, npm install -g <pkg> installs the package into the prefix of the active Node.js version. Vite+ then links the package binary into ~/.vite-plus/bin/ and records the owner in ~/.vite-plus/bins/<bin>.json.

When the active Node.js version changes (for example, the latest LTS moves from 24 to 26), I run npm install -g <pkg> again to update the package. npm installs a new copy into the new Node.js prefix and reports success. But the link in ~/.vite-plus/bin/ still points to the copy in the old Node.js prefix. Vite+ shows no message. When I run the command, I get the old version.

Expected: the link points to the copy that npm just installed, or Vite+ tells me that it kept the old link.

Cause: in check_npm_global_install_result, Vite+ replaces an existing link only when a different npm package owns it. When the same package owns it, Vite+ skips it, and it does not compare the link target with the new npm bin directory:

false
};
if shim_exists {
if let Ok(Some(config)) = BinConfig::load_sync(&bin_name) {
if config.source == BinSource::Vp {
// Managed by vp install -g — warn about the conflict
managed_conflicts.push((bin_name, config.package.clone()));
} else if config.source == BinSource::Npm && config.package != package_name {
// Link exists from a different npm package — recreate link for new owner.
// The old symlink points at the previous package's binary; we must
// replace it so it resolves to the new package's binary in npm's bin dir.
#[cfg(unix)]
let source_path = npm_bin_dir.join(&bin_name);
#[cfg(windows)]
let source_path = npm_bin_dir.join(vt_str::format!("{bin_name}.cmd"));
if source_path.as_path().exists() {
let _ = std::fs::remove_file(shim_path.as_path());
create_bin_link(
&bin_dir,
&bin_name,
&source_path,
&package_name,
node_version,
);
}
}

Possible fix: also replace the link when the same package owns it but the link target is not in the current npm bin directory. Write the new nodeVersion to the bin config, and print a line such as Relinked 'agent-browser' to Node.js 26.13.0 (was 24.15.0).

I can submit a PR for this fix.

Related: #1986 (general discussion about npm install -g and Node.js version management).

Reproduction

No repository is necessary. This is global CLI behavior. See the steps below.

Steps to reproduce

# 1. Install a package with an older default Node.js version
vp env default 24
npm install -g cowsay          # Answer "Y" to create the link
ls -l ~/.vite-plus/bin/cowsay  # -> .../js_runtime/node/24.x.y/bin/cowsay

# 2. Change the default Node.js version, then install the package again
vp env default 26
npm install -g cowsay          # npm reports success; Vite+ prints nothing
ls -l ~/.vite-plus/bin/cowsay  # Still -> .../node/24.x.y/bin/cowsay
cat ~/.vite-plus/bins/cowsay.json   # "nodeVersion" is still 24.x.y

# The new copy exists, but the link does not use it
ls ~/.vite-plus/js_runtime/node/26.*/lib/node_modules/cowsay

Workaround: remove the link (rm ~/.vite-plus/bin/cowsay), then run npm install -g cowsay again; or run vp install -g instead of npm install -g.

On my machine, 7 links point to old Node.js versions (24.15.0, 24.18.0, 24.21.0), while the active version is 26.13.0.

System Info

$ vp env current
Environment:
  Version  26.13.0
  Source   lts

Tool Paths:
  node  /Users/user/.vite-plus/js_runtime/node/26.13.0/bin/node
  npm   /Users/user/.vite-plus/js_runtime/node/26.13.0/bin/npm
  npx   /Users/user/.vite-plus/js_runtime/node/26.13.0/bin/npx

$ vp --version
vp v0.2.1

Local vite-plus:
  vite-plus  Not found

Environment:
  Package manager  Not found
  Node.js          v26.13.0

macOS, npm 10.9.9. The code at the link above is from current main (7073d61), so the bug is also on main.

Used Package Manager

npm

Activity

  1. changed the title [-]`npm install -g` keeps the `~/.vite-plus/bin` link on the old Node.js version after the default Node.js changes[/-] [+]`npm install -g` keeps the `bin` link on the old version after the default Node.js changes[/+] on Oct 29, 2026
  2. voidzero-bot commented on Oct 29, 2026

    @voidzero-bot

    Triage failed unexpectedly (attempt 1 of 3).

    Run: https://github.com/voidzero-dev/vite-plus/actions/runs/40928614944

    I can retry if a new comment provides more information or asks me to try again.

    Error:

    [flue] skill("triage") failed: 429 status code (no body)
    
  3. added theissue type on Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

Fields

Priority

None yet

Effort

None yet

Target date

None yet

Start date

None yet

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions