Why does running my globally npm linked package simply open the bin file?

node.js, npm

Solution

The solution is to add `#!/usr/bin/env node` at the beginning of your `bin` script. I have no idea why though. I found out by comparing my script to others that worked.

Problem

If I'm developing the npm package `foo` and I want it to be globally installed as a command-line application, I can do this simply by adding to my package.json: ``` "bin": { "foo": "./bin/foo.js" } ``` Somebody who installs my package globally via npm will have the appropriate batch file and shell script added to their global npm prefix directory. However, suppose I want to be able to launch my package from the shell (or, in the case of Windows, the command prompt). I could do this by creating a batch file/shell script somewhere in one of my PATH directories that simply directly runs my package e.g. `@node C:\my\package\directory\bin\foo %*`. This is a fairly simple and obvious solution, but I felt that `npm link` was better suited, as it feels less hacky and is theoretically designed to do this exact thing. I run `npm link` in my package directory, then test it by running `foo` from the command line. Rather than executing my script, though, `foo.js` is actually opened in my default editor. Investigating in the prefix directory, it turns out that the `foo.cmd` file (the contents of the `foo` shell script are similar) that npm created contains this: ``` "%~dp0\node_modules\foo\bin\foo.js" %* ``` Compare with the batch file created by `npm install -g`: ``` @IF EXIST "%~dp0\node.exe" ( "%~dp0\node.exe" "%~dp0\node_modules\npm\bin\npm-cli.js" %* ) ELSE ( @SETLOCAL @SET PATHEXT=%PATHEXT:;.JS;=;% node "%~dp0\node_modules\npm\bin\npm-cli.js" %* ) ``` Why does `npm link` produce script files that launch a package's bin file instead of launching node with the bin file as an argument? How can I fix this behavior?

Original source