npm / npm/rfcs

[RRFC] Reintroduce global-only bin command

Open
#657 12 comments 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

discuss semver:minor
Dominant language
JavaScript
Stars
777
Forks
267
PR merge metrics
No merged PRs in 30d

Description

Motivation ("The Why")

With npm v9, the npm bin command was removed, which also removed the npm bin -g command. It displayed the path for globally-installed packages, and also checked to make sure that that path was included in the $PATH environment variable. For unix/mac, this is generally not an issue as global packages are installed to the same location as the node/npm binaries.

However, with Windows it's different as the global packages are installed in a completely separate directory from the node installation. Being able to run node does not necessarily mean that the user is also able to run the globally installed packages. Taken from the Windows installer, updating the $PATH variable is split into two different "features".

* Add to PATH
  * Node.js and npm - Add Node.js and npm (if installed) to the PATH environment variable
  * npm modules - Add modules that are installed globally by npm to the PATH environment variable. This option works for the current user only.

With a clean install of node on Windows with these two features selected, it will add two separate locations to the $PATH:

C:\Program Files\nodejs
C:\Users\<username>\AppData\Roaming\npm

This is because of the value of prefix decided by the builtin config, which is set to %APPDATA%\npm by default:

$ npm config ls
; "builtin" config from C:\Program Files\nodejs\node_modules\npm\npmrc

prefix = "C:\\Users\\<username>\\AppData\\Roaming\\npm"

If I then install a package (ex: typescript) with npm i -g typescript, this installs tsc to C:\Users\<username>\AppData\Roaming\npm\tsc which I'm only able to invoke successfully because of the second new entry in my PATH variable. This logic is entirely custom to npm, as it's derived from npm's prefix config value.

This all works seamlessly in the ideal case, but speaking as someone that handles troubleshooting for a large population of developers that are not always primarily doing Node/npm/JS development, incomplete or inaccurate $PATH variables have been an uncommon yet consistent issue. It was useful for us to have npm bin -g as that could prompt the user to add the global package location to their $PATH if it wasn't already set (as it would warn with (not in PATH env variable)).

Given the nature of Windows' two-location installation, this does seem like a Windows-only problem. As such, I'm not sure what the cleanest fix would be. For this use case we do not need any of the "non-global" functionality of npm bin without -g that allowed for the aforementioned bad behavior, so I'm not suggesting that this command be added back as it was. If the functionality to check the global install location (and also if that was in the $PATH variable) could be added to an existing command or even a new command, that would work well for us. I'd be happy to contribute such a feature (whatever it may look like) if that sounds like a good idea to all involved.

Example

This RFC would be for a new command, subcommand, or flag that reproduces the behavior of npm bin -g. Specifically, printing the location of globally installed executable packages and checking whether that location is available in the $PATH environment variable.

Potential suggestions:

  • Add this as a subcommand/flag to npm prefix -g as this path is derived from the prefix config value.
  • Make a new command that is responsible for $PATH-related logic
  • Something else entirely?
How
Current Behaviour

No platform-independent way to calculate location of globally installed packages.

Desired Behaviour
$ npm prefix bin -g
$ npm path
$ npm path bin
C:\Users\<username>\AppData\Roaming\npm
(not in PATH env variable)
References

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the removed npm bin -g behavior and the referenced npm/cli PR 5459, then compare the proposed npm prefix -g and npm path entry points. Done means agreeing on an implementation that prints the global executable location and reports whether it is present in PATH, including the Windows case.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
cli
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.