How to rescue a vibe-coded app
What's actually wrong with most vibe-coded apps, how to triage them, and the conversation you have to have about fixing it.
I get these conversations fairly regularly now. Someone has built something real with AI. It's running, people are using it, maybe there's even paying customers. And now they need something done that they can't do themselves, a new feature, or something broke, or they're starting to worry about things they read. So they come to a developer.
The app isn't the problem. The problem is everything around the app that nobody thought about while it was being built.
What the triage actually looks like
Before I read a single line of code, there are five things I want to know. The answers tell me most of what I need to understand about what I'm working with.
The first is whether I can run it locally. Not whether there's a README that claims I can, whether it actually works. A project that can't be stood up on a fresh machine without archaeology is telling you something important: the environment exists in one place, probably production, and the only way to develop against it is to develop in production. That's not a workflow problem. That's a structural one, and it means every change from here is carrying real risk.
The second is where the secrets are. API keys, database credentials, third-party service tokens. If they're in the repository, that's the first thing that stops everything else. Not because it's embarrassing, because depending on how long that repo has existed and whether it's ever been public or shared, you may have already lost control of those credentials and don't know it. Before anything else gets discussed, the credentials get rotated.
The third is what's happened to the database. Does the project have a migration history, a record of every change to the schema in the order it happened? Or did someone add columns by clicking around in a GUI? If it's the latter, there is no reliable way to know what the current schema actually is. You can look at production and see what's there, but you can't reproduce it, can't roll it back, can't confidently stand up a test environment that matches. Every future change to the schema is a guess that might work.
The fourth is whether authentication actually works at the data layer. It's surprisingly common to find an app where routes are protected by a login check, but the underlying data queries aren't scoped to the user who made the request. The route says "you must be logged in." The query says "give me all records of this type." If you understand how URLs are structured in the app, you can often pull other customers' data just by knowing what to ask for. This isn't a hypothetical. It's a pattern AI produces regularly, because the training data is full of examples that check auth at the route and then query without restriction.
The fifth is whether the data model makes sense. Not whether the code is clean or the naming is consistent, whether the shape of the data reflects how the business actually works. This is the question that determines almost everything about what comes next.
The data model is the whole conversation
When a vibe-coded app is worth saving versus when it should be rebuilt usually comes down to one thing: the data model. The business logic can often be refactored. The UI can often be kept, or at least used as a reference. But if the data model is wrong, you're rebuilding. Full stop.
A wrong data model means the tables don't reflect the actual entities and relationships in the business. It means fields are being overloaded to carry information they weren't designed to hold. It means things that should be linked aren't, and things that shouldn't be conflated are stored in the same row. When a data model like this is in production with real data in it, every new feature has to work around the model's limitations. Every workaround creates new limitations. The technical debt isn't accumulating linearly, it's compounding.
The good news is that AI tools are actually pretty decent at frontend code. React components, Next.js pages, Tailwind layouts, UI logic. It's the stuff with the most training data and the least systemic risk, and it usually shows. The frontend of a vibe-coded app is often genuinely usable. The business logic in isolated utility functions is often fine too. The data itself, the records customers have created, is almost always worth keeping regardless of what else happens. The schema might need restructuring, but the data can usually be migrated.
What almost never survives intact is the auth system. Not because AI can't write an auth flow that functions, it can. But auth is one of those areas where "functions" and "is correct" are different things. The failure modes are subtle, they don't show up in normal use, and the consequences when they do show up range from annoying to catastrophic. I've yet to look at a vibe-coded auth implementation that I'd leave in production without significant work.
Anything that touches money gets the same treatment. Payment processing, billing logic, financial calculations. These get rebuilt properly, because the cost of a bug in this area isn't a bad user experience. It's regulatory exposure, it's chargeback disputes, it's customers overcharged or undercharged and you finding out weeks later.
The conversation nobody wants to have
The hardest part of this work isn't technical. It's sitting with someone who built something they're proud of and explaining that significant parts of it need to be redone.
The thing to understand is that the app represents months of their time and, often, a real emotional investment. They watched it come together. They showed it to people. It works. Telling them "this needs to be rebuilt" lands very differently than it would to a developer. To a developer, "let's rebuild this the right way" is a reasonable professional conversation. To a founder, it can feel like being told their baby is ugly.
The frame I find more useful, and more honest, is this: the question isn't whether the code is good or bad. The question is whether we can work with it. Can we add what you need, safely, without making the underlying problems worse? Sometimes the answer is yes, with some foundational work first. Sometimes the answer is that the cost of working around what's there exceeds the cost of doing it cleanly from scratch. That's a practical calculation, not a judgement.
What makes that conversation easier is specifics. Not "the auth is bad," but "here's exactly what happens when someone guesses this URL." Not "the database is a mess," but "here's why we can't add the feature you want without first sorting out this relationship." Specifics give people something to reason about. Abstractions feel like criticism.
The founder who built the app isn't wrong to be attached to it. They built something real, which is genuinely hard, and most people don't do it. What they built got them here. The question now is whether it can take them further, and if so, what that requires.
What comes after triage
Assuming the decision is to salvage and build on rather than restart, the work proceeds in a specific order. Security issues are fixed before anything else, unconditionally. That means credentials, access controls, data exposure, database configuration. These aren't negotiable and they don't wait for the next sprint.
Once the app is actually secure, the foundational problems get addressed: migration tooling so the schema has a history, a proper development environment so changes can be tested before they reach production, logging so that when something breaks you have some chance of understanding what happened and when.
After that, you're in a position to actually build. Not before.
The founders who handle this best are the ones who come in already suspicious that something's wrong. They built fast, they know they cut corners, and they want to understand what those corners actually cost them. That's a productive conversation. The harder ones are the founders who are certain it's fine because it's been running for six months without incident. Six months of no reported incidents isn't the same as six months of nothing wrong. It often just means nobody's looked yet.