Dependency Management
Date: 2026-08-17
Deciding what to depend on, and keeping it current. Most of your codebase is code you didn’t write, and the two failure modes are opposite — never upgrading until an upgrade is impossible, or adding a dependency for something you could have written in twenty lines.
Dependency management covers choosing dependencies, updating them, and understanding what they bring with them.
Transitive dependencies are the bulk
you declare 12 packages
you actually get 1,100+
You review the twelve and inherit the rest. Every one runs in your build, some run install scripts, and any of them can be compromised or abandoned — Supply Chain Risk.
npm ls --all | wc -l # the real count
npm explain some-package # why is this here?Before adding one
The questions worth asking, because the cost is permanent and the benefit is immediate:
- Could I write this in an afternoon? A date-formatting helper, a debounce, a slug generator. Small utility packages are usually a bad trade — you inherit a maintenance relationship to save twenty lines
- How many dependencies does it bring? Check before, not after
- Is it maintained? Last release, open issue count, whether the maintainer responds
- What’s the bundle cost? For anything client-side — Bundle Analysis
- How hard is it to remove? A dependency touching every file is a decision you can’t revisit
- Is there a platform equivalent?
Intl,fetch,crypto,URLandstructuredClonehave replaced a lot of what packages used to do
The honest default is scepticism for small packages and openness for large ones. Nobody should write their own date library or framework; plenty of people should stop installing a package to pad a string.
Update cadence
The two failure modes:
NEVER UPGRADE
→ security exposure accumulates
→ the eventual upgrade crosses
several majors at once
→ it becomes a project nobody
schedules
UPGRADE EVERYTHING IMMEDIATELY
→ churn, and occasional breakage
from a bad release
The workable middle:
- Patch and minor: automated, weekly, with tests as the gate. Batched into one pull request per week rather than one per package
- Major: deliberate, scheduled, one at a time, with the changelog read
- Security advisories: promptly, on their own
Automation is what makes this survivable. Dependabot, Renovate or equivalent, configured to group and to raise pull requests rather than to merge.
Audit noise
npm audit
# 47 vulnerabilities (12 moderate, 30 high, 5 critical)Most of these will not affect you, and the ratio is bad enough that teams learn to ignore the output entirely — which is the actual risk.
The questions that matter:
- Is the vulnerable code path reachable from your application?
- Is it a dev dependency? A vulnerability in a build tool is a different risk from one in shipped code
- Is it exploitable in your context? A denial-of-service in a parser you run on trusted input is not urgent
A prototype-pollution advisory in a transitive dependency of a test runner is not the same as an RCE in your HTTP framework, and treating them identically means treating both as noise.
npm audit --omit=dev # production only
npm audit fix # auto-fixableTriage rather than dismiss. A standing list of accepted, documented exceptions beats a wall of red nobody reads.
Reducing the surface
- Remove what you don’t use.
depcheckand similar find unused declarations - Prefer fewer, larger, well-maintained dependencies to many small ones
- Move build-only packages to
devDependencies, so they never ship - Question anything with a
postinstallscript — Package Managers - Vendor genuinely tiny utilities. Twenty lines in your repo, with a comment saying where it came from, is a better trade than a package
The abandoned dependency
A package with no releases for three years isn’t necessarily bad — some things are finished. The question is what happens when it breaks:
IS THERE A PLAN?
can we fork and patch it?
is the API small enough to replace?
how many files import it?
Track how deeply each dependency is embedded, not just whether it’s current. The one imported in two files is replaceable; the one imported in two hundred is a decision you’ve already made permanently — Coupling and Cohesion.