I liked Steve Krouse’s essay, “Vibe code is legacy code.” It helped crystalize some half-baked thoughts I have on vibe coding. Here’s an excerpt.
We already have a phrase for code that nobody understands: legacy code.
Legacy code is universally despised, and for good reason. But why? You have the code, right? Can't you figure it out from there?
Wrong. Code that nobody understands is tech debt. It takes a lot of time to understand unfamiliar code enough to debug it, let alone introduce new features without also introducing bugs. […]
When you vibe code, you are incurring tech debt as fast as the LLM can spit it out. Which is why vibe coding is perfect for prototypes and throwaway projects: It's only legacy code if you have to maintain it! […]
The worst possible situation is to have a non-programmer vibe code a large project that they intend to maintain. This would be the equivalent of giving a credit card to a child without first explaining the concept of debt. […]
If you don't understand the code, your only recourse is to ask AI to fix it for you, which is like paying off credit card debt with another credit card.
Maintainability and vibe are inversely correlated
I’ve been using GitHub copilot and chatbots for code for years, and I’ve written about them a lot here.
I’ve noticed that the more I rely on copilots and chatbots for helping me with code the harder it is to maintain that code, even when I deeply understand what it is I’m trying to accomplish.

I felt this acutely when I added medRxiv summaries to the biorecap package I originally wrote for summarizing bioRxiv preprints.
I only wrote about 25% of the code and outsourced the rest to LLMs. I resisted adding this really simple feature for weeks because of that feeling you get when you know you need to revisit legacy code you didn’t write and/or don’t fully understand.
Of course I can look at the code and run through examples, and even ask an LLM for an explanation if there’s something I don’t fully understand. But I felt the weight of the technical debt that vibe-coding this thing left me with, making it off-putting to return to the project for maintenance and upgrades. There’s some maintenance I need to do on that package, like making sure it’s working with the latest ellmer updates, but the thought of diving back into this codebase I didn’t write is too much friction.
Vibe is fine for throwaway prototypes
Steve makes a carve out for where vibe coding can be useful:
Vibe coding is perfect for prototypes and throwaway projects: It's only legacy code if you have to maintain it!
I did this a while back to create a throwaway Chrome extension to put a “Share with Bluesky” button on bioRxiv pages. I didn’t fully understand what the code was doing, but the important thing is that I was able to verify it did what it was supposed to do.
I started this with no intention to ever go back to maintain this code (I think bioRxiv is working on adding a Bluesky share button natively), making this a fine project to vibe code without any real understanding of the code or how to maintain it.
Be slow and defensive
Andrej Karpathy, who originally coined the term “vibe-coding” offers some advice:
[Keep] a very tight leash on this new over-eager junior intern savant with encyclopedic knowledge of software, but who also bullshits you all the time, has an over-abundance of courage and shows little to no taste for good code. And emphasis on being slow, defensive, careful, paranoid, and on always taking the inline learning opportunity, not delegating.