Essential npm Commands Every Developer Should Know
You probably use npm install and npm run dev every day without thinking twice. But the npm CLI has a much deeper toolkit that can save you real time — whether you’re debugging a broken dependency tree, auditing for vulnerabilities, or running a one-off script. This guide covers the essential npm commands and modern workflow patterns that belong in every developer’s daily practice.
Key Takeaways
npm install,npm uninstall, andnpm outdatedform the core of everyday dependency management.- Use
npm ls,npm explain, andnpm queryto inspect and debug your dependency tree. npm audit,npm sbom, andnpm diffgive you practical tools for security and supply-chain transparency.- The
overridesfield inpackage.jsonlets you pin transitive dependencies without waiting on upstream fixes. - Passing flags through scripts with
--and running one-off binaries withnpm execstreamline common workflows.
Installing and Managing Dependencies
The workhorse of npm dependency management is npm install. Run it without arguments to sync your local node_modules with package-lock.json. Add a package name to install something new:
npm install react # runtime dependency
npm install vite --save-dev # dev-only dependency
To safely remove a package and clean up package.json at the same time:
npm uninstall lodash
For checking what’s outdated across your project:
npm outdated
This gives you a clear table of current, wanted, and latest versions — useful before deciding what to update and when.
Running Scripts and Passing Flags
npm run without any arguments lists every script defined in your package.json. Handy when you’re jumping into an unfamiliar project.
When you need to pass flags through to the underlying script, use -- to separate them:
npm run build -- --watch --mode=development
Everything after -- is forwarded directly to the script, so you can adjust behavior without touching package.json.
Inspecting the Dependency Tree
Two commands developers should know for debugging dependency issues are npm ls and npm explain (also aliased as npm why).
npm ls renders your full dependency tree. Pass a package name to filter:
npm ls ms
npm explain tells you why a specific package is installed — which direct dependency pulled it in:
npm explain ms@0.7.1
For more advanced filtering, npm query lets you search dependencies using a CSS-selector-style DSL. For example, finding all packages that define a postinstall script (a useful security check):
npm query ":attr(scripts, [postinstall])"
Discover how at OpenReplay.com.
Running Packages Without Installing Them
npm exec runs a package binary using your project’s local dependencies, or temporarily downloads the package if it is not already installed. In modern npm versions, the npx command delegates to npm exec under the hood.
npm exec -- create-react-app my-app
It respects your project’s local node_modules first, making behavior more predictable than reaching for a global install.
Security-Focused npm Commands
npm audit scans your dependency tree against known vulnerability databases and prints a severity-ranked report:
npm audit
npm audit fix # auto-fix safe updates
npm audit fix --force # apply breaking fixes (test thoroughly after)
For supply-chain transparency, npm sbom generates a Software Bill of Materials — a full inventory of your project’s dependencies in a machine-readable format:
npm sbom > sbom.json
This output can be fed directly into security tools like Snyk for deeper vulnerability scanning.
To compare what actually changed between two package versions before upgrading:
npm diff --diff=ms@2.1.2 --diff=ms@2.1.3
The output mirrors git diff, making it easy to spot unexpected changes before they land in your project.
Pinning Transitive Dependencies
When a vulnerability lives in a transitive dependency you don’t control directly, use the overrides field in package.json to force a specific version:
"overrides": {
"node-ipc": "9.2.1"
}
Note that overrides is supported in npm v8.3 and later. If you’re using Yarn, the equivalent feature is resolutions. This approach is one of the most practical ways to maintain a secure dependency tree without waiting on upstream maintainers.
Conclusion
Most developers only scratch the surface of what npm can do. The commands covered here — from npm explain and npm query to npm sbom and overrides — bridge the gap between basic usage and a genuinely efficient workflow. Start with the ones that match your current pain points, and build from there.
FAQs
npm exec is the built-in command introduced in npm v7 that runs package binaries, and it is what npx delegates to under the hood in modern npm versions. The key difference is that npm exec checks your local node_modules first, giving you more predictable behavior. For most everyday tasks, the two are interchangeable, but npm exec is the recommended approach going forward.
Run npm audit fix to automatically apply safe, semver-compatible updates. If a fix requires a major version bump, use npm audit fix --force, but test your application thoroughly afterward since breaking changes may be introduced. For transitive dependency issues outside your direct control, use the overrides field in package.json to pin a patched version.
Use overrides when a vulnerability or bug exists in a transitive dependency and the direct dependency that pulls it in has not yet released a fix. It forces npm to resolve a specific version of that nested package. This feature requires npm v8.3 or later. Always test after applying an override, as forcing a version can cause compatibility issues.
Run npm explain followed by the package name and version, for example npm explain ms@0.7.1. This prints the full chain of dependencies that caused the package to be installed. You can also use the shorthand npm why. For a broader view of your entire dependency tree, use npm ls with an optional package name filter.
Gain control over your UX
See how users are using your site as if you were sitting next to them, learn and iterate faster with OpenReplay. — the open-source session replay tool for developers. Self-host it in minutes, and have complete control over your customer data. Check our GitHub repo and join the thousands of developers in our community.