Understanding npx How It Really Works
Source: Dev.to
Summary
This article explains npx in two layers:
- Brief overview with exact resolution steps
- Deep explanation of each step
Overview
npx searches for an executable and runs it.
If the executable is not available locally or globally, it downloads it temporarily and runs it.
Consider npx as an executable resolver, not a package manager.
Exact Resolution Order (Quick Scan)
What npx does?
Searches for a file and executes it.
Search Step-1
Searches for package.json in current working directory
Searches for name key in the json
Searches for bin key
Search Step-2
Searches for node_modules/.bin/hello in current working directory
And executes this file
Search Step-3
Searches for hello in global npm folder
And executes this file
Search Step-4
Searches for hello package in npx cache
And executes this file
Search Step-5
Searches for hello package in npm registry
Prompts to install the package if found
Downloads and installs
Execution stops immediately when a match is found.
Deep Explanation: How Each Step Works
Step 1: Project package.json — Project‑Scoped CLI
npx checks if the current directory contains a package.json and inspects the name and bin fields.
{
"name": "hello",
"bin": {
"hello": "./index.js"
}
}
If the command name matches the name and the bin field exposes the same command, npx runs the mapped file directly.
Why this matters
This allows for project‑level CLIs without requiring installation or depending on globally installed tools.
Step 2: Local node_modules/.bin (Preferred Execution)
If Step 1 fails, npx looks for the executable in the local binary folder:
./node_modules/.bin/hello
The folder is created automatically by npm when a dependency declares a bin field.
npm install hello-cli # creates node_modules/.bin/hello
npx hello # executes that file
Key rule
Executables for a local project always override the global ones.
Step 3: Global npm Binary Folder
If no local executable exists, npx checks the global npm binary directory:
npm bin -g # e.g., /usr/local/bin
If hello exists there, npx runs it.
Reason for lower priority
Global CLIs can cause version mismatches between projects; npx prefers local tools to avoid this.
Step 4: npx Cache — Fast Reuse
If still not found, npx falls back to its internal cache, which:
- Stores previously downloaded CLI packages
- Prevents multiple downloads
- Accelerates execution of repetitive tasks
The cache is managed by npm and shared with npm internals.
Step 5: npm Registry (Last Resort)
When all previous steps fail, npx queries the npm registry. If a package named hello exists:
- The package is downloaded.
- Its
binentry is resolved. - The executable is run immediately.
- The package is cached for future use.
Example:
npx create-react-app my-app
No global installation occurs, and nothing is saved to package.json.
Mental Model to Remember
npx = resolve an executable, not install a dependency.
Installation occurs only when resolution fails.
Final Takeaway
npx is a command runner:
- Local project tools always win
- Global tools are fallback
- Cache avoids re‑downloads
- Registry fetch is the last step
Use npx when you want:
- One‑off CLI usage
- Zero global installs
- Version‑safe tooling
- Clean developer environments
Questions to Think About
Q1: If no version is specified, how does npx know which version to download?
Q2: What if the same command exists locally and globally?
Q3: Why is node_modules/.bin preferred over global binaries in npx resolution?