Run executables from local npm packages

Run project tools through npm scripts or npm exec, understand bin links, and avoid accidentally downloading a different command version.

Best practices
Illustration of files, modules, and their dependencies

When a locally installed npm package declares a bin entry, npm creates command links or shims, commonly in node_modules/.bin. Use an npm script for a repeatable project command, or npm exec for an explicit invocation.

Add the tool to the project

For a project using ESLint:

npm install --save-dev eslint

Configure ESLint for the project, then define a script:

{
  "scripts": {
    "lint": "eslint ."
  }
}
npm run lint

npm adds local dependency executables to the script's PATH. The script therefore uses the project's installed tool rather than requiring each developer to install it globally. Commit the manifest and lockfile, and use the agreed install process in CI.

Invoke a command directly

npm exec -- eslint .
npx eslint .
./node_modules/.bin/eslint .

The final form is a POSIX-style explicit path. Windows installations use command shims, including .cmd files; npm scripts hide much of that platform difference.

Modern npx is built on npm exec. If a requested package is missing, it may offer to install it into npm's cache and execute it. That is still downloading and running code, even though it does not add the package to the project's manifest. Use a declared dependency when reproducibility matters, and review the package before accepting a one-off download.

Specify the package and command separately

A package name does not always match its executable name. For example, TypeScript supplies tsc:

npm exec --package=typescript -- tsc --version

An explicit package version can be added to the package specifier when a particular release is required. With npx/npm exec, an explicit version must match a local dependency to reuse it; a different requested version can be fetched. The claim that the local version always wins is therefore incorrect.

Put npm exec options before -- and the command's options after it. npx has different option-parsing rules, so consult its documentation when moving between the two forms.

Inspect links and workspace behavior

Read the package's bin field to see which commands it provides. Listing .bin shows available links, but not necessarily which version or package owns a command; inspect the target when diagnosing a collision.

On POSIX systems these are usually symlinks. Windows uses shims. Reinstalling dependencies recreates them according to package metadata. Removing a shim manually does not remove the supplying dependency declaration.

Workspace layouts vary with package manager and hoisting settings. Do not assume every executable lives only in the repository root. Declare the tool in the workspace that needs it, then use the package manager's workspace-aware script or exec command. For example, npm run lint --workspace=web selects the actual workspace named web and its configured script.

References

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting