Your Vibe-Coded Prototype is Broken. Here's How I Know.
I'm going to describe a codebase to you. Tell me if it sounds familiar.
Your Vibe-Coded Prototype is Broken. Here's How I Know.
I'm going to describe a codebase to you. Tell me if it sounds familiar.
Twenty-two database tables, half of which aren't used by anything. Components over a thousand lines long with business logic, API calls, and styling all tangled together. No tests. An email queue that's configured but never actually sends anything. A notifications system scattered across six different files with no consistent pattern. Dead code everywhere — files that were generated, half-finished, and abandoned.
Sound like your project? Yeah. I've seen this exact pattern three times in the last year alone. Welcome to the era of vibe coding.
What Vibe Coding Actually Produces
Let me be clear: I'm not anti-AI in development. I use Claude Code every single day. It's genuinely brilliant for productivity. But there's a massive difference between an experienced developer using AI as a tool and a non-developer prompting an AI to build an entire application.
The AI will absolutely give you something that works. You'll have a demo. You'll be able to click through flows, see data on screen, maybe even process a test payment. It looks like a product. The problem is that what you can see represents maybe 20% of what matters in production software.
Here's what the AI won't tell you:
Your database schema is a mess. AI generates tables reactively. You ask for a feature, it creates a table. You ask for another feature, it creates another table. There's no holistic data model — no one sat down and thought about how these entities actually relate to each other. You end up with redundant tables, inconsistent foreign keys, and data spread across places it shouldn't be.
In Rezzy, there was an event_performers table that was basically a worse version of what should have been an invitation workflow. There were venue-related tables for a feature that was never built. There were columns duplicated across tables because the AI didn't remember what it had already created.
Your components are doing too much. A React component should do one thing. Maybe two if you're feeling generous. AI-generated components tend to be God objects — they fetch data, transform it, handle all the user interactions, manage state, and render everything. When you need to change one thing, you're wading through a thousand lines of interleaved concerns.
This isn't a style preference. It's a maintenance nightmare. When your component handles authentication checks, data fetching, form validation, API submission, error handling, and rendering — all in one file — changing any one of those things risks breaking all the others.
There are no tests. This is the most consistent tell. Vibe-coded projects never have tests. Not "they have bad tests" — they have zero tests. The AI doesn't write tests unless you specifically ask, and even when it does, they're usually superficial.
No tests means no confidence. Every change is a gamble. Every deployment is a prayer. You can't refactor because you don't know what you'll break. You can't onboard another developer because there's no specification of what the code is supposed to do.
Dead code is everywhere. AI generates code, you try it, it doesn't quite work, you prompt again, the AI generates a different approach. But the old code is still there. Multiply this by a hundred interactions and you've got a codebase full of zombie code — files that exist but aren't referenced, functions that are defined but never called, imports that point to nothing.
In the Rezzy cleanup, we deleted 59,000 lines of code. Fifty-nine thousand. And the application worked better afterwards, because most of those lines were dead weight.
The Real Danger: False Confidence
The worst thing about a vibe-coded prototype isn't the messy code. It's that it gives you — the founder — false confidence that you're further along than you are.
You've got a working demo. Investors can see it. You can show it to potential users. It feels like you're 70% done and just need to "polish a few things." In reality, you're maybe 20% done, and the 80% remaining is the hard stuff: error handling, edge cases, security, performance, data integrity, testing, monitoring, deployment.
I've had founders come to me saying "we just need someone to finish this off" when what they actually need is a rebuild. That's a hard conversation. Nobody wants to hear that the thing they spent three months and several thousand pounds on needs to be thrown away. But building on a broken foundation doesn't make it less broken — it makes the eventual collapse more expensive.
The Rezzy Story
Jamie came to me with exactly this situation. He'd had a prototype built for Rezzy — a platform for the underground music scene connecting DJs, promoters, and venues. The demo looked good. The reality underneath was a disaster.
Here's what I found:
- 22 database tables where 10 would do the job properly
- 30+ dead code files that weren't referenced by anything
- Components over 1,000 lines with business logic mixed into the rendering
- An email notification system that was configured but broken
- No consistent error handling
- Zero tests
- Scattered authentication logic with security holes
Agencies quoted six figures to sort it out. Six figures. For what was fundamentally a relatively straightforward events platform.
Here's what I actually did: a 10-phase systematic rebuild. Phase one was understanding the actual domain — what does this product really need to do? Phase two was schema redesign — one atomic migration that took 22 tables down to 10 properly-structured entities. Then component rewrites, API restructuring, security hardening, and proper test coverage.
The numbers: 59,000 lines deleted. 59 tests added where there were none. 82 commits across the rebuild. The whole thing took three months and cost a fraction of those agency quotes.
How to Know If This Is You
Be honest with yourself about these questions:
- Was your prototype built primarily through AI prompting? Not "AI-assisted" — actually built by prompting an AI with feature requests?
- Can you deploy with confidence? Or does every deployment make you nervous?
- Has any developer looked at the codebase and gone quiet? That silence is diagnostic.
- Are bugs appearing in seemingly unrelated features? That's the tangled code showing itself.
- Is "it's almost done" a phrase you keep hearing? It's probably not almost done.
What To Do About It
First, get an honest assessment. Not from the person who built it — from someone independent. A senior developer spending a few hours reviewing the codebase can tell you whether you're dealing with cosmetic issues or structural ones.
If it's structural — and it usually is — you've got two choices:
Option A: Systematic rescue. Keep what works, rebuild what doesn't. This is what I did with Rezzy. It's cheaper than a full rewrite because you preserve the domain knowledge embedded in the existing code. But it requires someone who can read the mess and extract the intent.
Option B: Clean rebuild. Sometimes the existing code is so tangled that extracting value from it costs more than starting fresh. This is rare, but it happens. If there are no tests, no documentation, and the schema doesn't match the actual business domain, a rebuild might genuinely be faster.
Either way, the answer isn't "keep building on top of it and hope for the best." That's how you turn a £15k problem into a £150k problem.
The vibe-coded prototype served its purpose. It showed you the concept could work. Now it's time to build it properly.
If any of this resonates, I work with founders directly — from early MVP planning through to scaling. No fluff, just practical engineering.
Get the Friday email
What I shipped this week, what I learned, one useful thing.
No spam. Unsubscribe anytime. Privacy policy.