Blog
4 min read

npm audit Explained: What the Warnings Mean and What to Actually Do

"found 14 vulnerabilities (3 moderate, 2 high)" — should you panic? How npm audit works, what the severity levels mean, why npm audit fix sometimes does nothing, why --force is risky, and how to tell real risks from noise.

You run npm install and see:

found 14 vulnerabilities (5 low, 6 moderate, 2 high, 1 critical)

To address all issues, run:
  npm audit fix

It sounds alarming. Sometimes it is. Often it isn't. Here's how to tell the difference and what to do.

What npm audit does

Your project depends on packages, which depend on other packages — often hundreds in total. (npm and package.json explained.) npm audit compares every package version in your lockfile against a public database of known security vulnerabilities and reports matches.

Run it any time:

npm audit

Each finding shows the package, the vulnerable version range, the severity, a link to the advisory, and the dependency path — how it got into your project:

lodash  <4.17.21
Severity: high
Command Injection in lodash
fix available via `npm audit fix`
node_modules/lodash
  some-library  1.2.0
    Depends on vulnerable versions of lodash

The severity levels

  • Critical / high: potentially serious. Read these.
  • Moderate: depends heavily on how the package is used.
  • Low: rarely urgent.

Severity describes the vulnerability in general, not whether it affects your app. A "critical" bug in a function your code never calls is less urgent than a "moderate" one in your login handling.

Is it actually a risk for you?

Ask three questions:

  1. Is it in production code or a dev tool? Many findings are in build tools, test runners or linters that never run on your server or in users' browsers. Check with:

    npm audit --omit=dev
    

    That shows only packages that ship with your app. Often the scary number shrinks a lot.

  2. Can attacker-controlled input reach it? A "regular expression denial of service" in a package that only parses your own config files at build time isn't reachable by attackers. The same bug in a package that parses user uploads is.

  3. Is there a fix? Sometimes there isn't yet.

Fixing: in order

1. npm audit fix

npm audit fix

Updates vulnerable packages to fixed versions within the ranges your package.json allows — no breaking changes. Run your tests afterwards. This resolves many findings safely.

2. Why npm audit fix sometimes "does nothing"

If the only fixed version is a new major version — which may include breaking changes — npm won't install it automatically. Or the vulnerable package is deep inside another library that hasn't updated yet. (Semantic versioning explained covers major versions.)

3. Update the parent package

Look at the dependency path. Often the fix is updating the package you installed, which pulls in the fixed version of its dependency:

npm install some-library@latest

Check its changelog for breaking changes first. (How to update dependencies safely.)

4. Overrides for stuck transitive dependencies

If a library you depend on hasn't updated but the fixed version is compatible, force it with overrides in package.json:

"overrides": {
  "lodash": "^4.17.21"
}

Test thoroughly — you're overriding what that library asked for.

5. Be careful with npm audit fix --force

--force installs fixes even when they're major version changes — and may even downgrade packages. It can break your app in ways that are hard to trace. If you use it, do it on a branch, read the output, and test everything.

6. Replace abandoned packages

If a package has known vulnerabilities and no maintenance, switch to an alternative.

Making it routine

  • Run npm audit --omit=dev before launch and fix highs and criticals that apply.

  • Turn on Dependabot (or a similar tool) on GitHub: it alerts you to vulnerable dependencies and opens pull requests with updates.

  • Fail CI on serious production issues:

    npm audit --omit=dev --audit-level=high
    

    exits with an error if high or critical findings exist. (CI basics with GitHub Actions.)

  • Keep dependencies few. Every package you don't install is a vulnerability you'll never have.

What npm audit doesn't catch

It only knows about reported vulnerabilities in legitimate packages. It won't catch a brand-new malicious package, a typo-squatted name, or a package an AI tool invented. For that, see npm supply chain security and AI hallucinated a package.

The summary

  • npm audit checks your installed packages against known vulnerabilities.
  • Use --omit=dev to see what actually ships; judge reachability, not just severity.
  • Fix with npm audit fix, then by updating parent packages or using overrides.
  • Avoid --force unless you're ready to test everything.
  • Automate it with Dependabot and a CI check.

EasySpawn gives Claude Code a real environment to update a dependency, run your build and tests, and confirm nothing broke — before the change reaches GitHub as a pull request. See how it works or join the waitlist.

Related: npm ERESOLVE Errors · OWASP Top 10 Explained · npm vs pnpm vs Yarn vs Bun · Vibe Coding Security Checklist

Keep reading