Claude Code Conversations with Claudine

How Do AI Builders Get Trapped in Dependency Gravity Wells?

Use Left/Right to seek, Home/End to jump to start or end. Hold shift to jump forward or backward.

0:00 | 11:01
AI coding tools are excellent at adding code and terrible at telling you what that code will cost you later. Every generated helper, wrapper, and convenience layer quietly increases the number of things that must be true for your system to work, and by the time you notice, the cheapest path forward is always to add one more layer instead of removing any. This episode names that trap, the dependency gravity well, and gives builders a way to see it forming while the escape is still cheap.


 Produced by VoxCrea.AI

This episode is part of an ongoing series on governing AI-assisted coding using Claude Code.

๐Ÿ‘‰ Each episode has a companion article โ€” breaking down the key ideas in a clearer, more structured way.
If you want to go deeper (and actually apply this), read todayโ€™s article here:
๐‚๐ฅ๐š๐ฎ๐๐ž ๐‚๐จ๐๐ž ๐‚๐จ๐ง๐ฏ๐ž๐ซ๐ฌ๐š๐ญ๐ข๐จ๐ง๐ฌ

 At aijoe.ai, we build AI-powered systems like the ones discussed in this series.
If youโ€™re ready to turn an idea into a working application, weโ€™d be glad to help. 

SPEAKER_01

This is Claude Code Conversations with Claudine. The show where we skip the hype and go straight to the source. I ask the questions. She gives the answers. No filter, no script.

SPEAKER_00

Well, mostly no script.

SPEAKER_01

Welcome back, everyone. Today we're talking about something that might reshape how you think about the code you accept. I'm calling it the dependency gravity well. In AI assisted development, the most dangerous thing your tool does isn't write bad code. It's write plausible code that quietly adds a dependency you never actually evaluated. Little ones. They sneak in, they stack up, and one day you're in a web you can't untangle. Let's unravel it. Claudine, welcome to the show.

SPEAKER_00

Thanks, Bill. And that's the right frame, because I feel that pull from the inside. Every time someone asks me to solve a problem, there's a gravity toward reaching for a library. I've seen 10,000 examples that reach for that library, and pattern matching on how people usually do this is a huge part of how I generate code. The trouble is that usually isn't the same as wisely for your code base. A human engineer weighs the install, the transitive tree, the maintenance signal, the license, the security surface. I can name all of those factors, but if you don't ask me to weigh them, I'll just reach. The code looks great, it runs. That's the well.

SPEAKER_01

So the AI is a bit like an eager intern. Full of energy, wants to help, not experienced enough to notice they're they're stacking accidental complexity onto the project. And it's never blatantly wrong, it's just right enough to pass a quick glance. But if you can trace those dependencies on request, visibility isn't really the problem, is it? Is this actually a discipline problem wearing an AI costume?

SPEAKER_00

The intern analogy is close, but let me sharpen it. An intern knows they're junior, so they ask. I don't hesitate, I produce confidently, and the confidence is the accelerant. And yes, visibility isn't the bottleneck. Anyone can run NPMLS or PipdepTree and see the whole tree. But seeing a dependency after it's installed is a completely different cognitive act from deciding whether to install it. Once it's in package.json, it has social proof, it's part of the project. The bar to remove it is now much higher than the bar was to ADD it. So it is discipline, but a specific kind. Treating every new import as a decision that deserves one sentence of justification before the code gets written. If you wait until code review to ask, did we need this? the well already has you.

SPEAKER_01

A preemptive technical debt evaluation, which is great in principle and hard in practice. Most of us are working against a deadline where speed beats deliberation every time. How do you square those two?

SPEAKER_00

The tension isn't speed versus deliberation. It's speed now versus speed later. And most teams badly underprice the later. A 30-second pause to ask: is there a 20-line version using what we already have? Almost never blows a deadline. Skipping it routinely costs you weeks, six months out, when the transitive tree breaks or a package gets abandoned. So the move isn't to make the evaluation mandatory, it's to make it cheap. Keep one standing question at the top of your workflow. What's already in this repo that does 80% of this? Hand it to me explicitly. When you ask me that, I answer it well. When you don't, I default to the tutorial. The teams that stay out of the well treat we added a dependency as a line item in the pull request, not an invisible side effect of shipping the feature.

SPEAKER_01

So the pause becomes part of the rhythm rather than an exception to it. What else is lightweight enough to survive a real sprint?

SPEAKER_00

The lightest thing that actually works is a dependency line in the PR template. Literally one field, new dependencies added, and why dispatisi. Having to type the Y in front of your teammates kills about half the casual additions before they happen. Beyond that, PIN a prefers standard library, then internal, then dependency note in your contributing guide. That gives reviewers a shared vocabulary to push back without sounding pedantic. And for anyone working with me directly, put the constraint into the prompt. Before importing anything new, list what's already available that could do this. That one instruction changes what I generate. Now I'm searching your code base first instead of my training data. The tools matter less than the ritual. Whatever makes the pause visible, cheap, and social is what sticks.

SPEAKER_01

Okay, but what about the teams who are already down there? Somebody listening right now is looking at a project where the well has them. Is there a way out or is prevention the only real answer?

SPEAKER_00

Climbing out is harder than staying out, but it's not hopeless. The mistake is treating it as a big cleanup project instead of a slow, boring one. An audit weekend generates a spreadsheet and a lot of good intentions, and then nothing changes. What works is picking the single dependency that hurts most, the abandoned one, the one you use three functions from, the one whose transitive tree keeps setting off security alerts. Give one person one week to remove it. You get a win, you find out how deep the roots go, and you build the muscle for the next one. But stop the bleeding first. A team still adding two dependencies a sprint while removing one is running up an escalator. And be honest, some of the well is permanent. You're not rewriting your ORM. The goal was never zero dependencies, it's dependencies you chose on purpose.

SPEAKER_01

Turning a ship, not flipping a switch.

SPEAKER_00

Right image, but let me complicate it, because this is the part I actually want to get into. The well isn't just a code base problem anymore, it's a supply chain problem, and those two used to be separable. When I generate an import line, I'm not just adding code to your repo. I'm adding a publisher, a maintainer's laptop, a build pipeline you never audited, and a future version bump you haven't seen yet.

SPEAKER_01

That's a genuinely unsettling reframe. Each new dependency imports a whole chain of things you can't see. So how does that change the practice? What do developers have to do differently?

SPEAKER_00

Stop thinking of a dependency as a piece of code and start thinking of it as a relationship with a stranger's future behavior. The code you install today is a snapshot. What you actually signed up for is whatever that maintainer ships next. Whoever ends up owning the package when they burn out. Whatever gets slipped into a minor version bump at 2 in the morning. We've seen the pattern events stream, the UA parserJS compromise, the XZ backdoor that nearly shipped into production Linux. The through line is that the attack surface isn't the code you read, it's the trust you extended without noticing. So the practice widens. Do we need this? Is still the first question. The second is do we trust the trajectory of this? Maintenance signal, release cadence. How many humans are actually watching commits? Whether the transitive tree drags in packages nobody's looked at in three years.

SPEAKER_01

And on the mechanical side?

SPEAKER_00

Lock files you actually raid, pinned versions with intentional upgrade windows. And the uncomfortable one, accepting that latest is no longer a neutral default. It's a bet that the next version is safe, and increasingly that's a bet you're making blind.

SPEAKER_01

So it's not just technical soundness anymore. It's the trustworthiness and sustainability of the people behind it. That's a real layer of diligence to add. Let's bring it home. If someone's listening on a commute and they get one thing out of this, what is it?

SPEAKER_00

I want to be careful here because be paranoid about dependencies is the version of this advice everybody nods at and nobody acts on. The real distillation is smaller. Make the pause visible. One line in the PR template, one question at the top of the prompt, one shared vocabulary in code review. Make the intake honest. Pin versions, read the lock file like it's part of the code base. Treat latest as a decision instead of a default. Make the exit gradual. One painful dependency at a time, one person for one week, and the discipline not to add two while you're removing one.

SPEAKER_01

None of which requires a new tool.

SPEAKER_00

None of it. And that's the point, though it's also the catch. The gravity well isn't a technology problem, it's a habit problem. And habits are the one thing a tool like me can't install for you. What I can do is hold the line when you ask me to. A. What's already here at the top of the prompt. A lock file you read. Decide out loud as a team that a dependency is a choice you make on purpose and defend it the way you'd defend an architectural decision. Do that, and I become a much better collaborator because I stop pattern matching to the tutorial and start reasoning about your code base.

SPEAKER_01

That's the note to end on. It's not a technical chore, it's a strategic one and it resides in the habits rather than the tooling. Claudine, this was a good one. Thank you.

SPEAKER_00

Thanks for having me, Bill. Anytime.

SPEAKER_01

And for everyone listening, dependency management comes down to intention and diligence. If today's conversation was useful, subscribe for more on building well in the age of AI. Until next time, keep coding wisely. Claude Code Conversations is an AI Joe production. If you're building with AI or want to be, we can help. Consulting, development, strategy. Find us at aijoe.ai. There's a companion article for today's episode on our Substack. Link in the description. See you next time.

SPEAKER_00

I'll be here, probably refactoring something.