It has never been easier to make software that works on the first try. Describe what you want, accept the suggestions, and by the evening there's a dashboard with a login screen and a database behind it. For a demo or an internal experiment, that's genuinely wonderful. The trouble starts when the experiment quietly becomes the system the business runs on.
“Vibe coding” — building by prompting and accepting whatever works, without really reading the result — is not a bad idea. It's a tool with a particular cost curve: almost free at the start, increasingly expensive over time. This article follows that curve across three years, because that's roughly how long it takes for the bill to arrive in full.
The afternoon demo is real
Let's be fair to the tools: the speed is not an illusion. AI-assisted coding is excellent at the first 80% of an application — screens, forms, basic data storage, the happy path where every customer behaves and every input is valid. If your goal is to test an idea with five friendly users, it may be exactly the right call. You learn whether anyone wants the thing before spending real money on it.
The question isn't whether it works today. It's what it costs to keep working once real customers, real data and real money flow through it — and whether anyone on your team actually understands how it works.
Year one: the gaps appear
The first year is usually fine on the surface. The cracks appear in the places a prompt rarely mentions, because the person writing the prompt was thinking about features, not failure.
- Permissions — who can see which records was never really designed, so it's patched one complaint at a time. A sales rep can see every customer; a contractor can export the whole database.
- Edge cases — refunds, partial orders, time zones, duplicate sign-ups and customers with two accounts arrive with real usage, and each is handled differently in different places.
- Validation — data that should never exist starts appearing in the database: negative quantities, missing emails, dates in the wrong format. Reports stop matching what people see on screen.
- Security — API keys in the code, missing rate limits on the login form, and dependencies nobody is tracking for known vulnerabilities.
None of these are exotic. They're the unglamorous 20% that experienced engineers build in by habit — and that generated code only includes when someone knew to ask.
Year two: change gets expensive
Generated code tends to solve each request in isolation. Ask for a discount feature and you get one; ask for a second kind of discount three months later and you often get a second, slightly different implementation next to the first. Without a consistent structure, the same business rule ends up living in several places, each a little different.
Without tests, nobody can say with confidence what a change will break. So every release needs someone to click through the whole app by hand. Small changes start taking days. The software still works — it has just become slow and nervous to change, and the people who depend on it learn to stop asking for improvements.
The cheapest software to build is rarely the cheapest software to own.
Year three: the rebuild conversation
Eventually someone asks whether it would be faster to start again. Sometimes it is. But by now the system holds years of business data and habits, so a rebuild means migrating messy data, retraining staff and often running two systems side by side for a while. The afternoon of speed has turned into a quarter of careful untangling — and a rebuild done in a hurry can repeat the same mistakes.
Signs your app has outgrown its prototype
- Nobody can explain how a core feature works without opening the code and guessing.
- The same bug has been “fixed” more than once.
- You avoid upgrading packages because something always breaks.
- Customer data, payments or health information pass through it.
- Releases happen less often than they used to, and each one feels risky.
Rescue before you rewrite
A full rewrite is rarely the first step. A steadier path is to make the existing system safe to change, then replace the weakest parts one at a time. In practice that means:
- Write tests around the journeys that make money — sign-up, checkout, invoicing — before touching anything else.
- Document the real data model and permissions, then fix the most dangerous gaps first.
- Run a security review: secrets, authentication, access rules and dependency updates.
- Set up a deployment pipeline, so every change is built, tested and released the same way.
- Replace modules incrementally behind stable interfaces, instead of switching everything over in one weekend.
How to use AI coding well
None of this is an argument against AI-assisted development. Used well, it makes good engineers noticeably faster. The difference is who stays in charge of the design.
- Prototype with it freely — then decide deliberately what graduates to production.
- Keep a human who understands the architecture accountable for every merge.
- Ask for tests alongside features, and actually run them in a pipeline.
- Write down the data model and permissions before generating screens.
- Review generated code the way you'd review a new colleague's: kindly, but properly.