locally installed node.js cli call does not behave like global

scenario:

I have written a cli script. It lives in directory mycli and is called mycli.js and is shebanged as #!/usr/bin/env node. In the project's package.json I have included "name": "mycli", "bin": "mycli.js".

At this point I can call mycli from the project root two ways, either as $ node mycli or simply $ mycli.js.

After publishing to npm and installing this package globally, I can now call $ mycli or $ node mycli from anywhere, however, a local install doesn't exhibit the same behavior from its own project root; I have to call the script using the more qualified name, either as $ node_modules/mycli/mycli.js, or $ node node_modules/mycli/mycli.

Why doesn't $ node mycli work in the local scenario?

Check out the following answer on: How to use package installed locally in node_modules?

Basically, when you install a package globally, the executable will be found because it's in your PATH. The node_modules directory isn't in your PATH by default. Adding every node_modules directory on your system to your PATH would get quite messy.

You can check your current PATH with echo $PATH. You can add your local node_modules directory (for the lifetime of your session) with PATH=$(npm bin):$PATH. The linked answer also has an alternative using aliases.