← Patrick White

The Age of Dependencies Is Over

Or: why "don't reinvent the wheel" was always bad advice

"We are destroying software with an absurd chain of dependencies, making everything bloated and fragile. We are destroying software telling new programmers: 'Don't reinvent the wheel!' But, reinventing the wheel is how you learn how things work, and is the first step to make new, different wheels."
— Salvatore Sanfilippo (antirez), creator of Redis

The dependency explosion happened because humans hate tedium.

Writing your own string parser is boring. Implementing a date formatter is annoying. Building a toggle handler from scratch feels like a waste of time when someone already did it. So we learned to reach for packages. "Don't reinvent the wheel" became gospel. The npm ecosystem grew to millions of packages. A hello world app shipped with hundreds of transitive dependencies.

This made sense when humans were the ones writing all the code. Tedium has real costs for human programmers—it's slow, error-prone, and soul-crushing. Dependencies were a rational trade: accept invisible complexity in exchange for skipping the boring parts.

But the trade had a hidden cost. And the economics just changed.

* * *

Every dependency you add is code you can't see. Code you don't control. Code that might change underneath you. Code with its own dependencies, each carrying the same risks recursively.

A dependency is a liability disguised as an asset.

When something breaks, you're debugging code you didn't write, often code you've never read. When you need to modify behavior, you're either fighting the library's assumptions or forking it entirely. When the maintainer abandons the project, you inherit it whether you wanted to or not.

The convenience of not writing the code is paid for by the inconvenience of not understanding the code.

This was always true. But it was an acceptable trade when the alternative was writing everything yourself, slowly, painfully, one keystroke at a time.

* * *

Some people never accepted the trade.

Redis is written in C—a language without a package manager. Salvatore Sanfilippo built his own data structures: SDS for strings, Rax for radix trees, custom implementations of everything. When he needed HyperLogLog, he didn't embed an existing library. He read the papers, ran experiments, and wrote it from scratch.

Recently, Redis had a dependency on a C++ library called fast_float—3,800 lines of template code that required g++ to build. Sanfilippo replaced it with 260 lines of pure C. Why? "There is no reason to depend on C++ in a project written in C."

SQLite is the same school. D. Richard Hipp built a database that compiles to a single file with zero external dependencies. It's in your phone, your browser, your car, probably your airplane. There are more SQLite databases in the world than there are people.

Both projects:

This wasn't stubbornness. It was epistemic hygiene. They understood that dependencies are debt, and debt compounds.

* * *

Now consider what changes with AI.

The tedium that drove the dependency explosion—writing string parsers, date formatters, toggle handlers—that tedium is free now. Claude will write you a bespoke, dependency-free, perfectly legible implementation of whatever you need. It won't get bored. It won't make typos. It won't resent the repetition.

But there's a deeper shift that matters more than the economics of tedium: dependencies are code your AI collaborator can't see.

When I'm working with Claude on a codebase, it can read my files, understand my patterns, modify my logic. But the moment something touches a third-party library, Claude is reasoning about an interface without seeing the implementation. It's inferring behavior from documentation that might be incomplete, outdated, or wrong.

Dependencies create black boxes. Black boxes are where AI collaboration breaks down.

This is why the shift matters now, not just as perennial good-taste advice. When the primary reader and writer of your code is a linguistic intelligence that works by seeing and understanding text, opacity becomes a more severe tax than it used to be. Every dependency is a hole in Claude's vision.

Explicit code—even if longer, even if repetitive—is code that can be understood, modified, and regenerated. The "worse" choice of writing it yourself becomes the better choice when your collaborator thrives on transparency and chokes on black boxes.

Two hundred lines you can both read beats twenty thousand lines neither of you can.

* * *

The old wisdom said: use libraries for everything, only write custom code when you have to.

The new wisdom might be: write custom code by default, only use libraries when the implementation is genuinely complex and the interface is genuinely stable.

That means:

The bar for "worth depending on" just got much higher. Because the alternative—writing it yourself—just got much cheaper.

* * *

I think about Cloudflare Workers a lot in this context. The runtime deliberately constrains you: no filesystem, no native extensions, no Node ecosystem sprawl. Just V8, some APIs, and your code.

This felt like deprivation when I first encountered it. Now I see it as liberation. The constraints enforce the discipline that antirez and Hipp practiced voluntarily. You can't accumulate dependency debt because the environment won't let you.

And the result? Code that deploys everywhere, runs fast, costs almost nothing, and doesn't rot. Code that Claude can read end-to-end and modify confidently.

Constraints as gifts.

* * *

The age of dependencies was a response to human limitations: we're slow, we get bored, we make mistakes when we're tired. So we built ecosystems that let us skip the tedious parts.

Those ecosystems are now liabilities. The tedium they were built to avoid is no longer tedious. The complexity they accumulated is still complex.

The programmers who understood this all along—the antirez school, the SQLite school, the embedded systems school—they weren't being contrarian. They were just optimizing for different constraints. Constraints that now apply to everyone.

If I can write it myself in 200 obvious lines, why should I depend on 20,000 lines I don't control?

The answer used to be: because writing those 200 lines is slow and annoying.

That answer doesn't work anymore.