Vibe coding is describing what you want in plain language and accepting whatever the model produces, without reading it closely. For a prototype, a script, a one-evening tool, it is a genuinely good way to work. I use it that way myself.
The trouble starts when the thing you vibe-coded goes into production and starts holding other people's data. Not because the code is bad — quite often it is tidy, idiomatic, well named. The trouble is what nobody wrote down.
A model answers the question you asked
Ask for a booking form and you get a booking form. It will validate the email. It will probably look better than the one I would have written by hand.
What it will not do is ask you the questions that decide whether the thing survives contact with real users. What happens when two people book the last slot in the same second? What happens when the payment provider times out after taking the money but before your code hears back? Who is allowed to see this booking — the customer, any logged-in user, anyone with the URL? When the customer asks you to delete their data, what else has to be deleted with it, and what must legally be kept?
Those are not coding questions. They are decisions about your business, and the model cannot make them because it has never been told the facts it would need. It produces something plausible for each one, silently, and moves on. The output compiles. The form works when you test it. The decision was still made by nobody.
The demo always works
This is the specific trap, and it catches experienced people too.
A vibe-coded feature is tested the way it was built: one person, one browser, one happy path, no load, no adversary. Under those conditions almost anything passes. The failures live entirely in conditions you did not think to create — concurrency, partial failure, hostile input, the second tenant, the tenth thousand row, the user who is no longer logged in but whose session token still works.
So the feedback loop lies to you. You ship, it works, you ship again faster. Confidence grows exactly while the unexamined surface grows. Nothing tells you otherwise until something does, publicly.
Six things that are consistently missing
Authorisation, as opposed to authentication. Models are good at login. They are much weaker at "this user may read this specific row." The most common vibe-coded vulnerability by a distance is an endpoint that checks you are logged in and never checks who you are.
Anything that has to be correct under concurrency. Stock counts, seat reservations, invoice numbers, balances. Code that is obviously right when read top to bottom is frequently wrong when two copies run at once.
The failure mode of every external call. Every third party you depend on will be unavailable at some point. Whether that should stop your customer is a business decision. Generated code makes it by accident, usually by crashing.
Data you cannot afford to lose. Migrations that drop columns, deletes without soft-delete, no backup you have actually restored from. Nobody notices until the day it matters, and on that day it is unrecoverable rather than inconvenient.
The back office. Vibe coding produces the screens you described. You described the customer-facing ones, because those are the ones you picture. Your staff then live for eight hours a day in whatever was left over.
Coherence across features. Each session starts fresh. Ten features built in ten sessions give you ten conventions, three ways of handling dates, two auth patterns and no shared vocabulary. Individually fine. As a system, unmaintainable — including by the next model you point at it.
What this actually costs
The pitch for vibe coding is speed, and the speed is real. What it defers is the cost of understanding, and that cost does not go away — it gets paid later, by whoever has to change the system.
Changing software safely requires someone who can predict what a change will break. That person builds their model of the system by having made the decisions. If nobody made the decisions, nobody has the model, and every subsequent change is a guess with a deploy attached.
I get called into these projects regularly. The rescue is almost never a rewrite — the code is usually salvageable. What takes the time is reconstructing intent: reading every path to work out what the system was supposed to do, because nobody can tell me, including the person who shipped it.
What I actually think
AI is the largest productivity gain my trade has seen, and I would not work without it. It is a superb instrument in the hands of someone who can read its output critically and knows which questions it failed to ask.
It does not replace that person. It makes that person faster. The judgement about what your system must never get wrong is not a coding task, and it is the part you are actually paying for.
Use it for prototypes, internal scripts, throwaways, the first draft of anything. For the system your business runs on, have someone who understands it end to end — whether they typed it or reviewed it line by line.