Skip to content

npm audit Says I Have Vulnerabilities, Do I Have to Fix Them Before Launch?

6 min read

npm audit printed a scary list of "47 vulnerabilities, 12 high" and now you are wondering if your launch is unsafe. Short answer: no, you do not have to fix all of them, and the number at the bottom is close to meaningless on its own. What matters is whether any of those vulnerabilities sit in code that actually runs and faces your users. Most of the time, a large share of them do not.

Why this happens

npm audit checks every package in your dependency tree against a database of known issues, then counts them. It does not know which packages your app really uses at runtime, whether the vulnerable code path is reachable, or whether the package only runs on your own laptop during a build. It counts everything the same way.

Your vibe-coded app has a deep tree because the agent pulled in a framework, a UI kit, a few helpers, and each of those pulled in dozens more. A single flagged package buried under a build tool can inflate the "high" count, even though it never touches a real request. The agent installed what got the feature working. Nobody pruned the tree, so the audit output looks alarming by volume, not by actual danger.

How to check

  1. Run the audit and read past the summary:

    npm audit
    

    For each finding, look at two things: the severity and the path. A devDependency (build tools, test runners, linters) does not ship to your users. A regular dependency might.

  2. Get the machine-readable version to sort quickly:

    npm audit --json
    

    or restrict to what ships in production:

    npm audit --omit=dev
    

    If --omit=dev drops your count to a handful, most of the noise was build tooling.

  3. For anything that survives, read the advisory. It tells you the attack: "only exploitable when parsing untrusted input", "denial of service via crafted regex", and so on. Ask whether your app actually does that thing with data a stranger controls.

The fix

  1. Run the safe auto-fix first. This bumps packages within their allowed version ranges and clears the easy ones:

    npm audit fix
    
  2. Re-run npm audit and re-read what remains. Prioritise high and critical findings that live in production dependencies and sit in a code path a user can reach.

  3. Update the parent, not the flagged package. Vulnerabilities usually live in a sub-dependency you never installed directly. Update the top-level package that pulls it in (npm update <name>, or bump it in package.json), which is safer than forcing a nested version.

  4. Only use --force deliberately. npm audit fix --force installs breaking major versions and can break your app. Run it, then start the app and click through the main flows before you trust it.

  5. Leave the rest documented, not ignored. For a low-severity, dev-only, or unreachable finding with no clean fix, it is reasonable to launch and revisit later. Note which ones and why.

The trap to avoid

Do not chase the count to zero by force-upgrading everything the night before launch. npm audit fix --force on a deep tree is one of the fastest ways to turn a working app into a pile of runtime errors, and you will not have time to debug it. The goal is not a clean audit screen. The goal is that nothing reachable by a user is genuinely exploitable. A quiet audit with a broken app is worse than a noisy audit with a working one.

Where this fits

Dependency warnings are one of those checks that look terrifying and are mostly noise, until the one that matters is hiding in the pile. The free Readiness Report runs the audit against your real project and separates the reachable, production, high-severity findings from the build-tool clutter, so you fix the few that count instead of all forty-seven. If you would rather have the safe upgrades applied and verified for you, that is what the Finishing Pass is for. It also pairs well with tightening the other basics, like making sure you did not push your API keys to GitHub and knowing whether your app is secure enough to launch at all.