What I Wanted to Do
I wanted to run “npm ls --parseable” to list all installed packages in a folder. I have an app that uses this information to present a graphical interface to a user, so this command is being run without direct user interaction (that is, I’m running it programmatically in my app, not typing it into a Terminal.)
I expected this command to return a 0 exit code when it runs correctly.
What Happened Instead
When the command is run in a project that has a missing package or a missing peer dependency, this command returns an exit code of 1. Additionally, the error messages (“missing peer dependency…) are written to BOTH stdout and stderr.
This is not correct. The command should exit with status code 0, because it DID run successfully—it determined which packages are installed. A non-zero status code indicates that a process failed to run.
Additionally, the error messages about missing packages or peer dependencies should be written to stderr only. Adding them to the list of parseable paths that is written to stdout makes parsing that list harder.
The correct approach is to return a 0 status code (the ls command ran successfully) and write any issues about missing packages/deps to stderr ONLY. This way, integrators can check stderr to see if any issues arose, can more reliably parse the output on stdout, and can rely on a correct Unix-standard exit code to decide if the command actually failed, or ran correctly but just found a couple issues.
Run the command above in a project folder with missing packages or peer dependencies.
$ npm --versions <!-- paste output here --> $ node -p process.platform <!-- paste output here -->