Dependencies that are only installed on on global installation

Can you add support to install some dependencies only when a package is installed globally so it has a binary file which can be used as a command program?

This would be useful.
For example, one package can be used as Node.js library and command program. In this case, some of the dependencies are needed for library and some additional dependencies are needed for command program (for example for some styling or handling inputs).
But when a package is used locally as a library, additional command program dependencies are not needed. They can also be very heavy so space will be used without need.
If my idea would be implemented, NPM or Yarn will install that additional command program dependencies only when a package is installed/used as a global package with command program. If a package is installed as a local library, only normal dependencies will be installed.

To implement this, there should be additional dependency section in package.json, called something like globalDependencies or binDependencies. They should be installed only when a package is installed globally (to use command program) or when a package is installed locally as dev dependency (in case if command program is needed for testing, linting, bundling…). In other cases, when a package is installed locally as a normal dependency, that section should be ignored.

For some packages there could be an install difference between being installed and used only as a library, and exposing a CLI. However, since packages with bin commands are routinely installed locally and called from npm scripts, I don’t think the distinction should be whether installed globally.

Have you got some specific packages in mind that would benefit from this level of control?

Aren’t packages which are used as local bin commands mostly devDependencies? If so, that global dependencies could also be installed when a package is installed as a dev dependency.

Also, there could be an additional flag when running installation which would specify if global/bin dependencies are needed.

Also, I currently don’t have any specific package in mind.

Making this change would violate a current design constraint, it seems like. But if I understand you correctly, we’d only link binaries and install binDependencies when installing globally, or as a dev dependency.

In order to do this safely, it seems like we’d have to evaluate the corpus of packages on the registry and make sure that there aren’t any that depend on calling their deps’ executables in normal operation. That could be tricky to get right.

This is already supported by npm. But it is not implemented. You would need to build your own setup script. Loop through the dependencies structure. And npm install only the packages which you detect are not globally installed.

The link above shows how you can loop through and install a set of global packages. You just need to take it one step further and do the same with “dependencies”.

It is probably big enough you would want to have this in a separate setup.js file instead of having it inline.

You could even include a configure.sh and configure.cmd that contains “npm run setup” that in turn invokes npm setup.js. I am suggesting using package.json + setup.js as a makefile if anyone remembers those ancient things.

What I miss is the features of emerge. It does signing, global and local package management. I mean. It is a true package management machine. Can’t wait for npm to catch up.