Adding a library is priced as a one-time decision — an afternoon saved. It's really a subscription: upgrades, CVEs, breaking changes, and the day it's abandoned. The install is the cheapest moment you'll ever have with it.
Whether a dependency is cheap or ruinous mostly comes down to one thing decided at integration time: can you leave? That's not a property of the vendor. It's a property of how far its concepts spread into your code.
A library is an obligation you carry. A service you call at runtime is stronger than that: you've adopted its availability as a ceiling on your own, and the arithmetic of that compounds faster than anyone expects.
Code persists perfectly; the reasoning behind it evaporates. Which is why so much of a mature codebase is lines nobody dares touch — not because they're wrong, but because nobody remembers what they were for.
Rewriting feels like replacing bad code with good code. It's really replacing accumulated knowledge with a fresh guess — and the ugliness you're removing is often where that knowledge is stored.
Documentation transfers facts. It doesn't transfer the model that makes those facts usable — the sense of how the system moves. That's why the person who's been there three years still answers questions the wiki technically already answers.
Checking for invalid states at runtime means remembering to check everywhere. Shaping your data so the invalid state can't be expressed at all means you only have to be right once — at the type, not at every call site.
Computation is mostly easy; the hard part of software is state — the accumulated memory of everything that happened before. Most bugs aren't wrong logic, they're the system being in a combination of states nobody pictured.
The moment a fact lives in two places, you've taken on a job you'll eventually fail at: keeping them equal. Most 'impossible' bugs are just two copies of something that were supposed to agree and quietly stopped.
A module boundary is a bet about what will change together. Draw it along the axis of change and edits stay local; draw it along surface resemblance and every change cuts across every module.