# Can be installed and run globally

- **Pattern:** `ab-000662` (`cli-quality.config-distribution.npx-install`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-000662
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-000662)

## Why it matters

If `npx my-cli-tool` fails, ninety percent of prospective users never try the tool again. Missing `files` causes npm to publish test fixtures, node_modules snapshots, and local `.env` files — leaking secrets and bloating the package from 50KB to 50MB. Missing `engines` means a user on Node 14 runs `npx mytool` and sees a cryptic `SyntaxError: Unexpected token '?'` from optional chaining in your ES2020 code. Missing `bin` means there's no command to run at all.

## Severity rationale

High because distribution config errors block global installation and can leak secrets or fail on common runtime versions.

## Remediation

Configure `package.json` with `name`, `bin`, `files`, and `engines`, and test the full publish flow locally before pushing. Verify with `npm pack && npm install -g ./my-cli-tool-1.0.0.tgz && mytool --version`:

```json
{
  "name": "my-cli-tool",
  "bin": { "mytool": "./dist/cli.js" },
  "files": ["dist"],
  "engines": { "node": ">=18" }
}
```

## Detection

- **ID:** `npx-install`
- **Severity:** `high`
- **What to look for:** Count all installation methods documented. For each, verify the CLI can be run without cloning the repository:
  - **Node.js:** `npx my-cli-tool` must work — check that `package.json` has `name`, `bin`, and `files` fields configured correctly. Check that `files` or `.npmignore` includes the built entry point. Check that `engines` field specifies the minimum Node.js version.
  - **Python:** `pipx run my-tool` or `pip install my-tool && my-tool` — check that `pyproject.toml` or `setup.py` configures the package correctly for PyPI.
  - **Go:** `go install github.com/user/mytool@latest` — check that the module path and main package are correct.
  - **Rust:** `cargo install mytool` — check that `Cargo.toml` is configured for publishing.
- **Pass criteria:** The CLI can be installed globally and run by name via the standard mechanism for its language ecosystem. Package metadata (name, version, bin/entry point, files) is correctly configured for publishing — at least 2 installation methods documented (npx, global install, or package manager specific). Report: "X installation methods documented."
- **Fail criteria:** Missing `bin` field, missing `files` field (npm publishes everything including test fixtures), `engines` not set, or the package cannot be installed and run globally due to configuration errors.
- **Skip (N/A) when:** The CLI is internal-only (not intended for public distribution) — check for `"private": true` in `package.json` or equivalent. All checks skip when no CLI entry point is detected.
- **Detail on fail:** Quote the actual package.json showing the missing fields. Example: `"package.json has no 'files' field — npm will publish everything including tests, fixtures, and local config. Add 'files': ['dist'] to control what's published"` or `"No 'engines' field — users on Node.js 14 will get a confusing error since the CLI uses Node.js 18+ features"`
- **Remediation:** Make your CLI easy to try and install:

  ```json
  // package.json — complete distribution config
  {
    "name": "my-cli-tool",
    "version": "1.0.0",
    "bin": {
      "mytool": "./dist/cli.js"
    },
    "files": ["dist"],
    "engines": {
      "node": ">=18"
    },
    "scripts": {
      "build": "tsup src/cli.ts --format esm",
      "prepublishOnly": "npm run build"
    }
  }
  ```

  Test with `npm pack && npm install -g ./my-cli-tool-1.0.0.tgz && mytool --version` before publishing.

---

Taxons: operational-readiness

HTML version: https://auditbuffet.com/patterns/ab-000662
