Software Engineering · Chapter 26 of 31
Vibe coding, spec-driven development, and which to use
Where both terms came from, what the evidence actually says about them, what each produces, and how to use them personally and in a company.
Two phrases you will meet in interviews and in planning meetings, usually with more heat than definition. Both name real practices, both are useful, and the interesting part is what the evidence says about the first one.
Where the words came from
Vibe coding was coined by Andrej Karpathy in February 2025 — a founding member of OpenAI and formerly head of AI at Tesla. His description was deliberately loose: you describe what you want, accept the diffs without really reading them, paste errors back when things break, and — his phrase — largely forget the code exists.
It was not a methodology proposal. It was an observation that for small throwaway projects, the model had got good enough that you could work this way at all. The name spread far beyond that scope, which is how it ended up in enterprise architecture meetings within a year.
Spec-driven development is the correction. Write a specification first — the behaviour, the constraints, the acceptance criteria — review that, and let the agent implement against it. The specification becomes the artefact of record, and the code becomes its output. GitHub shipped Spec Kit, AWS shipped the Kiro IDE around it, and Thoughtworks put the practice on its Technology Radar — three independent signals that it stopped being a blog-post idea.
Karpathy has since walked his own term back
By 2026 he was describing the vibe-coding era as ending, and the phase after it as agentic engineering — orchestrating agents against detailed specifications rather than hoping a prompt lands somewhere useful.
Worth knowing for two reasons. It is a useful thing to be able to say in an interview. And it is a reminder that the person who names a practice does not control what the industry does with the name.
What the evidence actually says
There is one well-known study, and handling it accurately is more useful than either quoting it as a slam dunk or dismissing it.
METR's randomised trial, published July 2025. Experienced open-source developers completed real tasks 19% slower when allowed to use AI tools.
The finding that makes it interesting is not the slowdown. It is the perception gap. The same developers predicted AI would make them 24% faster. Afterwards — having actually been 19% slower — they estimated they had been 20% faster.
Now the honest caveats, all of which matter. The sample was 16 developers and 246 issues. They were experienced contributors working in codebases they knew well — close to the worst case for AI assistance, and nothing like a newcomer to an unfamiliar repository. The tools were those available between February and June 2025. METR itself now labels the result historical, and its 2026 follow-up found some evidence of speedup but with selection effects that made the estimate unreliable enough that it changed the study design.
So the defensible claim is not ‘AI makes developers slower’. It is: self-reported productivity gains from AI tooling are not reliable evidence, because the one time somebody measured both, they pointed in opposite directions by nearly forty points. That claim survives every caveat above, and it is the one worth carrying into a room where someone is presenting a satisfaction survey as an outcome.
What each is actually good at
| Vibe coding | Spec-driven | |
|---|---|---|
| Best for | Prototypes, scripts, throwaway tools, exploring an unfamiliar library, one-off data work, anything you would happily delete | Shared services, anything a second person will maintain, regulated or audited work, anything touching money, identity or personal data |
| Speed to first working thing | Very fast. This is the genuine benefit and it is not small | Slower to start — you write the spec first |
| Speed to something correct | Unpredictable. Fast when it works; the debugging tail is brutal when it does not | More consistent, because the disagreement surfaced before the code existed |
| What you get | Working software | Working software, a spec, tests derived from it, and a plan |
| Review burden | Falls entirely at the end, on code nobody has a mental model of | Front-loaded onto a page of English, which is far cheaper to argue with |
| Handover | A chat log | A document |
| Fails by | Accumulating code nobody understands, including the author | The spec drifting from the code and nobody noticing |
What to expect — the outputs, concretely
Since this is what people are least clear on: a spec-driven workflow produces a small set of artefacts, and every tool that implements the practice produces roughly the same ones under different names.
- A specification — what the thing must do, in behavioural terms. Not implementation. ‘A user with an expired token receives 401 and a machine-readable reason’, not ‘add a middleware’.
- A plan — the implementation broken into steps, each reviewable. This is where you catch an agent about to rewrite something it should not touch, before it does.
- Tasks — the plan decomposed far enough that each piece is independently verifiable.
- Tests derived from the acceptance criteria, not written afterwards to match whatever the code happens to do. This inversion is most of the value: tests written after the fact test the implementation, and tests derived from a spec test the requirement.
- Then the code.
What to expect that people do not warn you about: the specification is now a thing that can go stale. A spec that no longer describes the system is worse than no spec, because it is trusted. Whatever you do, the spec has to be updated in the same pull request as the change, or the practice quietly degrades into documentation theatre within two quarters.
Personally
- Vibe freely on anything you would be happy to throw away. Scripts, prototypes, learning a library, one-off analysis. This is what the technique is for and it is genuinely excellent at it.
- The moment you would be upset to lose it, or somebody else will touch it, switch. That transition point is the whole skill.
- Read the code anyway, on anything that persists. Not to check syntax — to keep a mental model. The cost of vibe coding is not bad code; modern models write reasonable code. It is that you end up maintaining a system you never understood, and that debt is invisible until the day something breaks.
- Write a spec for anything you would struggle to explain to a colleague in two minutes. If you cannot write it down, the agent cannot build it, and discovering that on a page costs a paragraph rather than a weekend.
In a company
The organisational problem is not code quality. It is review capacity. Generation got roughly an order of magnitude faster; human review did not get faster at all. Every sensible policy here is really a policy about where the reviewing happens.
- Set the boundary by blast radius, not by seniority. Throwaway tooling, internal scripts and prototypes: vibe away. Anything in a production path, handling money, identity or personal data, or that another team depends on: spec first. Write the line down, because otherwise it gets drawn per-argument.
- Require the spec in the pull request. It is the only mechanism that keeps it current, and it gives the reviewer something to review against rather than just an opinion about the diff.
- Put the repository's rules in the file the tool actually reads — a
CLAUDE.md,AGENTS.mdor equivalent at the repo root, covering conventions, the test command, what not to touch. Reviewed like code, because it functions like configuration. See the next chapter. - Do not accept satisfaction surveys as evidence of productivity. See the METR perception gap above. Measure something outside the developer's own estimate: lead time, change failure rate, review turnaround.
- Expect the review bottleneck to move, not disappear. If generation is ten times faster and review is unchanged, review becomes the constraint — and the failure mode is not bad code merging, it is large changes merging with shallow review because the queue is long.
The interview answer, if you need one: vibe coding is fast, unstructured, conversation-driven work where you accept output without close reading — excellent for throwaway things and genuinely risky for anything shared. Spec-driven development front-loads the same work into a reviewable specification, which is what makes it usable in a team. The decision is per task and it is set by blast radius. And the honest evidence on productivity is thinner than either camp claims.
Check yourself