Package a Node CLI with a bin Entry
Publish a Node CLI with a bin mapping and executable shebang so it installs as a global command with the right name.
Task
Configure package.json bin and a shebang so the CLI installs as a command.
When to use this
Installing the package globally does not produce a runnable command because the bin entry is missing.
Prerequisites
- A Node.js CLI project
- npm or pnpm
- A test install environment
Steps
1. Add a shebang and a bin mapping.
#!/usr/bin/env node
// src/cli.js
console.log('tool runs');Expected output: The file is directly executable on Unix when marked executable.
2. Declare the bin name in package.json.
{
"name": "tool-cli",
"bin": { "tool": "./src/cli.js" },
"files": ["src"]
}Expected output: npm link or install creates a tool command that runs the script.
Troubleshooting
Problem
Permission denied on Unix
Solution
Commit the executable bit or document a chmod in the packaging step.
Problem
Windows runs it differently
Solution
Rely on npm shims generated from bin instead of assuming a shell shebang.
Limitations
- Global installs need a writable prefix or a manager like pnpm.
- Shebang portability varies on Windows.
- Does not handle updates or versions.
What this recipe does
Configure package.json bin and a shebang so the CLI installs as a command.
Installing the package globally does not produce a runnable command because the bin entry is missing.
Prerequisites
- A Node.js CLI project
- npm or pnpm
- A test install environment
Procedure
- Add a shebang and a bin mapping.
#!/usr/bin/env node
// src/cli.js
console.log('tool runs');
Expected result: The file is directly executable on Unix when marked executable.
- Declare the bin name in package.json.
{
"name": "tool-cli",
"bin": { "tool": "./src/cli.js" },
"files": ["src"]
}
Expected result: npm link or install creates a tool command that runs the script.
How to confirm it worked
Run the commands above and confirm every expected result in order. If a step does not produce the stated output, use the troubleshooting notes before continuing. A passing run shows installing the package exposes a command whose name matches bin and runs the entry point.
Troubleshooting
Permission denied on Unix — Commit the executable bit or document a chmod in the packaging step.
Windows runs it differently — Rely on npm shims generated from bin instead of assuming a shell shebang.
Limitations
- Global installs need a writable prefix or a manager like pnpm.
- Shebang portability varies on Windows.
- Does not handle updates or versions.