2, 3), which allows them to be used as commands in a terminal. For commands that aren’t tied to a project this might be all right, but otherwise they shouldn’t be installed globally.
A project might rely on a specific version of a command. If the command is required by another project you will have to reinstall the command every time you switch between projects.
Even if you use commands with a stable API you will have to specify them as a dependency. As npm doesn’t offer a way to specify a global dependency an additional configuration step has to be added, documented and maintained. This might seem like a small trade off, but as a project grows, a complex configuration will be more error prone.
A globally installed command has its advantages. It requires less effort to write its name than its full path and it takes up less space, because it is reused throughout your system.
To reduce the memory footprint of your local packages you could switch to the yarn package manager. It installs a specific module version in a global cache and links it into the local node_modules folder.
To make working with local commands as pleasant as with global ones you could reference them like global ones in the script section of the package.json file or add a command to your shell that executes locally installed commands of the nearest node project.