Platform Engineering

Dependency Debt Is a Tax You Pay Without Noticing

Adding a dependency is a two-minute decision with a multi-year obligation attached, and almost no team accounts for the second part.

A dependency arrives to solve a problem this sprint. What comes with it is permanent: shipped code you do not own, a licence obligation, a security surface you must monitor, and a compatibility constraint on every future platform upgrade.

None of that appears in the decision. All of it appears in the bill, years later, when someone tries to move the platform forward and discovers what is holding it still.

What the audit turned up

We removed 22 third-party packages in a single programme. Almost none of them were removed because they were bad.

Duplicate capability was the biggest category — two libraries doing the same job, arrived via different features at different times, both shipping. Pure overhead in bundle size, risk surface and upgrade cost, and completely invisible until someone lists dependencies side by side and reads them.

Abandoned upstream. Working fine, last released years ago. These are the ones that block a platform upgrade at the worst possible moment, because the incompatibility only surfaces when you attempt the move.

Trivially replaceable. Packages wrapping a few lines of standard functionality, adopted when that was the fastest path.

Genuinely unused. Still in the manifest, no longer referenced anywhere.

The audit is not sophisticated work. Its value is that nobody's job description contains it, so it never happens without being deliberately scheduled.

The patch multiplier

The costliest form is a dependency you have modified. A patch is a hand-written change layered on library code you do not own, and it must be reapplied and reverified every time the library moves.

Ours included a substantial internal fork of a rendering library. Retiring it and moving to the official release cut patch code by 77% and was, by a distance, the most valuable single change in the programme — despite being entirely invisible to customers.

That kind of code sets a floor under the cost of every future upgrade. You do not pay it once; you pay it on every attempt, forever, until you remove it.

Cheap habits that compound

Ask what a package replaces before adding it. Audit for duplicate capability quarterly. Treat a patch as a tracked liability with a plan to remove it, never as a solution. And prefer the boring, maintained option over the elegant, quiet one.

Making it visible

The reason this debt accumulates is that it is unmeasured. We now track dependency count and patch line count on the per-release scorecard alongside everything else.

The number itself is not the point. Publishing it is. Once a count is visible and trending, adding to it becomes a decision someone might ask about — and that mild social friction does more to control growth than any policy document.

← All writing Next: Distributed Squads: Optimise for Handover, Not Overlap →