npm.tax
Theme

Model the risk of a supply-chain compromise in an npm dependency tree, explore scenarios, and share a report to convince your boss that you're sitting ducks.

Package report fornuxtAssessed Medium

nuxt has a 23.2% modeled chance of at least one package compromise in 1 year.

Modeled surface
512
packages
Daily breach prob / package
1.41e-6
scenario assumption
Time period
1 year
Expected time to breach
3.8 years

Every modeled package

Visualization of 512 marks, one per modeled package: 1 for the package itself, 59 direct dependencies, 452 transitive dependencies.
Self
1
Direct deps
59
Transitive deps
452

Cumulative breach probability

1 year horizon
Line chart of cumulative breach probability over time for all modeled packages, half of the transitive tree, and the root package plus its direct dependencies0%50%100%0d183d365d
All 512 packages
23.20%
Half transitive (286)
13.71%
Self + direct (60)
3.05%

Model notes

Click to expand

Each package has a daily breach probability p. With n total modeled packages, including the package itself, the chance that none are breached on a given day is (1 - p)^n.

Over d days, the chance of staying breach-free is (1 - p)^(n x d). The model treats package-days as independent events, a flawed but useful simplification.

p is really two things multiplied: pbreach, the likelihood that a package gets compromised, and pimpacted, the likelihood that a compromise affects you directly. You can only control the latter.

Formula

P(breach) = 1 - (1 - p)n x d

p = pbreach x pimpacted

What can I do about it?

You can't prevent breaches (decrease pbreach). Focus on what you can control:

  • Reduce the surface area by removing dependencies (decrease n).
  • Reduce the blast radius by defending against common breach patterns (decrease pimpacted).
  • Reduce the time window you stay exposed by acting sooner (decrease d).

Fewer packages

Every in the visualization is a package that can be compromised, and most of them are below the iceberg.

  • Remove what you don't use. knip finds and removes unused dependencies (and more) adding dead weight and risk. Remove cruft now. Run knip in CI to keep it that way. Donate to sustain it.
  • Slim what you do use. A dependency that drags in a huge tree adds more risk than one that doesn't. e18e works with maintainers to cut down those trees and foster lean alternatives. Check out their docs, linter, CI reports, CLI, MCP, and more. Upgrade regularly to benefit for free. Donate to sustain the work.

Fewer open doors

A compromised package only matters if it can actually reach you and do damage.

  • Turn off install scripts. Most recent npm attacks fire during install, not at runtime. pnpm 10+, npm 12+, yarn 4.14+, deno, and bun block these by default (yarn 2+ can also opt in); use one of these. Otherwise, prioritize upgrading your package manager.
  • Lock down GitHub Actions. There are too many footguns to list here, and that's the point. zizmor performs static analysis of your GitHub Actions workflows and bans insecure usage. Run it once and fix what it flags. Add it to CI to keep it that way. Donate to sustain it.
Two more actionsClick to expand
  • Let releases age. Malicious versions are usually pulled within hours, so holding new releases back a short while is a cheap way to reduce risk. pnpm 11+, yarn 4.15+, and deno 2.9+ do this by default; use one of these. With pnpm 10.16+, npm 11.10+, and bun 1.3+ you can opt in. Otherwise, prioritize upgrading your package manager. Renovate and Dependabot can also be configured to delay updates.
  • Block flagged packages ASAP. Security researchers like Socket and Snyk typically flag malicious releases within 5 minutes. Socket provides a free CLI that wraps your package manager and blocks flagged packages at install time. Use it in CI and locally.

Act sooner

You decide how much time you spend at your current risk level. Every day adds cumulative risk.

  • Take these actions today. Everything in the other two columns only starts paying off the day you do it. Putting them off doesn't hold your risk steady; it keeps accruing for every day of d you spend delaying.