Skip to content
Back to Maintenance & LTS

Dependency Audit

Periodically inventory every dependency: what's used, what's unused, what's risky, what's outdated.

Why

Your dependency tree is a liability surface you didn't write — every package is code that runs with your privileges, maintained by someone you don't know, with bugs you can't see. An audit converts this opaque blob into a managed inventory: you learn you have 1200 transitive deps (not 40), that 3 are unmaintained, that 1 has a known CVE, that 12 are unused. Without periodic audits, node_modules grows monotonically — each addition is a one-way ratchet that's never removed, and the attack surface only grows. Audits are how you shrink it back.

When

Quarterly at minimum. Immediately when a high-severity CVE is announced in any dependency.

How

1. Generate the full tree: npm ls --all (or pnpm why) — capture direct + transitive counts
2. Find unused: npx depcheck (or knip) — lists deps in package.json but never imported
3. Find outdated: npm outdated — shows current vs wanted vs latest per package
4. Find vulnerabilities: npm audit (or pnpm audit, or Snyk/OSV-Scanner)
5. Find license issues: license-checker --production — flag GPL/incompatible licenses
6. Triage: remove unused, upgrade outdated with CVEs, file tickets for risky-but-needed
7. Record the audit in DEPS_AUDIT.md with date, counts, and actions taken

Example

# Full audit in one script
npm ls --all > deps-tree.txt
npx depcheck --json > unused.json
npm outdated > outdated.txt
npm audit --json > audit.json
npx license-checker --production --json > licenses.json

# Knip (finds unused files, exports, AND deps)
npx knip --include dependencies

# OSV-Scanner (Google's vuln DB, covers npm + pip + cargo)
npx @google/osv-scanner --lockfile package-lock.json

# Triage output:
# - 12 unused deps -> remove from package.json
# - 3 high CVEs     -> upgrade immediately
# - 2 GPL licenses  -> legal review (or replace with MIT alt)

Common Problems

  • ⚠Auditing only direct deps and ignoring the 1000+ transitive ones — that's where the CVEs and supply-chain attacks live.
  • ⚠Running npm audit once and ignoring the 47 low-severity findings — they compound, and a future minor turns one into critical.
  • ⚠Removing a dep that depcheck flagged as unused, but it's a peer dep or dynamically imported — production breaks.

Best Practices

  • ✓Automate the audit in CI on every PR and fail on high/critical CVEs — don't wait for a quarterly manual run.
  • ✓Use knip instead of depcheck — it understands dynamic imports, peer deps, and type-only imports, so fewer false positives.
  • ✓Record every audit in DEPS_AUDIT.md so you can see the trend: is node_modules growing or shrinking quarter over quarter?