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 theprefix
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
- Command removed