Criticism of vibe coding is usually criticism of using it for the wrong thing.
Treated as a universal method it has obvious problems, and pointing them out is easy. But it is not a claim about all software, and the people getting good results from it are usually not making one. They are doing something specific, for which it works.
The useful question is not whether it is a legitimate way to build. It is what it defers, and when the deferral stops being free.
What the practice actually is
Describe roughly what you want. Look at what comes back. Say what is wrong with it, or what you now realise you would prefer. Repeat until it feels right, then stop.
Its defining feature is not informality — it is that the software itself is the only record of what was decided. There is no separate statement of what it should do, so "right" means "matches what I have in my head as I look at it now". Judgement is continuous, immediate and entirely dependent on the thing being in front of you.
That is a real method with real advantages. They deserve stating without qualification before any of the costs are raised.
Where it is straightforwardly the right choice
When you do not yet know what you want. This is the strongest case. Writing down behaviour you have not thought through produces confident nonsense, and committing to it early is worse than not writing it at all. Sometimes the fastest route to knowing what you want is to look at three wrong versions of it. Specifying first would be a way of pretending to a certainty you do not have.
Throwaway work. A script to reshape a file once. A quick check of whether an idea is even feasible. Anything you intend to delete. There is nothing to maintain, so there is nothing to defer.
Low-consequence personal tools. Software where you are the only user, failures are visible to you, and the cost of being wrong is a mild irritation. You are the entire quality process, and you are sufficient.
Learning what a technology can do. Exploration is not construction. Applying a process to it mostly slows down the part that was the point.
In all four, structure would be overhead spent against a cost that is never going to arrive. Adding it anyway is not rigour; it is ceremony.
The costs are deferred, not avoided
Nothing goes wrong at the time. That is the important thing to understand about vibe coding, and the reason it feels so effective while you are doing it.
What accumulates is absence. Every decision made implicitly — how duplicates are handled, what the empty case does, which fields are required, what happens on failure — is a decision that exists in the software but nowhere else. Every session's understanding leaves with the session. Every piece of behaviour that works does so without anyone having stated that it should, which means nothing records that it is supposed to keep working.
You do not feel any of this while building. You feel it later, and only if there is a later. That conditional is the whole argument: where there is no later, there is genuinely no cost.
Where the bill arrives
Five places, roughly in the order most people meet them.
Regression. Something that worked last week does not work now, and nobody can say when it stopped, because nobody wrote down that it was supposed to work. Undeclared behaviour cannot be protected. This is usually the first real cost, and it arrives as a feeling that the project has become unreliable rather than as an identifiable event.
Debugging. Diagnosis needs a gap between expected and observed. With no recorded expectation, you are left comparing the software against a memory, and memory adjusts itself to whatever is in front of it. "Was it always like that?" is a question with no answer available.
Continued development. New work has to fit with decisions made months ago that nobody remembers making. Contradictions appear — dates formatted two ways, two different rules for what counts as a duplicate — and each one is individually trivial and collectively corrosive. The mechanism, and how to interrupt it, is the way AI projects drift.
Handover. Someone else has to work on it, or you return after six months, which is much the same thing. The software is the only documentation, and it records what was built without recording what was intended — so it cannot distinguish a deliberate choice from an accident that nobody noticed.
Consequence. The software stops being only yours. Someone relies on it. Now the absence of stated behaviour is not an inconvenience but a genuine gap in your ability to answer "does this work", and the areas where that answer matters most are exactly the ones where someone else's judgement is worth involving.
The transition is real and almost never marked
Software rarely announces that it has become important. A tool you wrote for yourself gets shown to a colleague, who finds it useful, who mentions it to someone else. Nothing is decided. At no point does anyone say "this is now a system we depend on". But the risk profile has changed completely, and the working method has not.
This is the actual failure mode, and it is worth separating from the practice itself. The problem is not that someone vibe coded a prototype. It is that the prototype quietly became infrastructure while still being treated as a prototype.
The practical response is not to work formally from the beginning in case something becomes important. It is to notice the transition and change approach at that point — which mostly means writing down what the thing currently does, deciding which of that is behaviour you are committing to, and checking that it is actually true before building anything further on top of it.
What structure is actually for
Everything a more structured approach adds is a direct response to one of the costs above. Read them as answers to specific problems rather than as rules.
Stating behaviour before building gives you something to check against, which is what makes regression detectable and debugging possible. Recording decisions gives new work something to be consistent with. Working in pieces small enough to verify keeps the gap between "checked" and "current" narrow enough to close. Keeping a verified version to return to means a bad afternoon costs an afternoon.
Not one of those requires heavy process, and not one of them is virtuous in itself. Applied to a script you will delete tomorrow it is pure waste. The judgement is about which situation you are in, and that judgement is the skill — not the ability to follow either method.
It is also not a binary. Most useful work sits between the two: behaviour stated for the parts that matter, decisions recorded where they would otherwise be forgotten, and a good deal of loose conversational iteration inside those boundaries. Reaching for structure only where a specific cost is actually in prospect is not a compromise between two positions. It is the position.
The fuller version of that approach, set out as a repeatable cycle, is the PDAID method, and a repeatable workflow for building software with AI walks one change through it from start to finish.