"Vibe coding" went from a single tweet to Collins Dictionary's Word of the Year in under a year. Along the way it lost its original meaning — which matters, because the thing Andrej Karpathy described and the thing most people now call vibe coding are different activities with very different risk profiles.
Where the term came from
Andrej Karpathy — OpenAI co-founder, former head of AI at Tesla — coined the term on 2 February 2025 in a post describing:
a new kind of coding I call "vibe coding", where you fully give in to the vibes, embrace exponentials, and forget that the code even exists.
Read that definition closely, because the important part is the last clause. Karpathy wasn't describing AI-assisted development in general. He was describing a specific, deliberately reckless mode: accepting diffs without reading them, pasting errors back in without understanding them, and treating the code as an artefact you never look at. In the original post he was explicit that this was for throwaway weekend projects — not production software.
The term escaped that context immediately. Merriam-Webster logged it as slang and trending in March 2025. Collins English Dictionary named it Word of the Year for 2025. Somewhere in that ascent, "vibe coding" broadened to mean any AI-assisted coding, and a term coined to describe a fun, low-stakes mode became a label people attach to shipping payment systems.
If vibe coding means "I don't read the code," it's a legitimate technique for prototypes and a terrible idea for production. If it means "I use AI to write code and then review it carefully," that's just... software development with a good tool. Conflating the two is how teams end up applying prototype-grade discipline to production systems. Be precise about which one you're doing.
How much code is actually AI-generated?
The most-cited data point is genuinely striking. In March 2025, YC managing partner Jared Friedman said that for a quarter of the startups in Y Combinator's Winter 2025 batch, 95% of their codebases were AI-generated.
That number deserves context rather than repetition:
- Friedman clarified the figure counted code typed by humans versus generated by AI, excluding things like imported libraries.
- He emphasised these were highly technical founders fully capable of building from scratch — not non-programmers.
- YC startups at Demo Day are early-stage products optimising for speed of validation. That's the population where vibe coding is most appropriate and least risky.
So it's a real signal about the leading edge of prototyping, not evidence that a quarter of all production software is now AI-written. Generalising it beyond early-stage startups is where the statistic gets abused.
The workflow
The practical loop looks like this:
- Describe the outcome in natural language: "add email/password auth with session cookies."
- Generate — the model writes across multiple files.
- Review the diff.
- Iterate: "add rate limiting to the login endpoint."
- Verify with tests and manual checks.
Steps 3 and 5 are where the pure form of vibe coding says you don't bother. That's exactly the choice that determines whether you're prototyping or accumulating liability.
Where it genuinely works
Boilerplate and well-trodden patterns
CRUD endpoints, form validation, config scaffolding, API clients. These have been written millions of times, they're well-represented in training data, and the correctness bar is easy to check. This is the strongest case.
Prototypes and spikes
When the goal is answering "is this idea worth building?", the code is disposable by design. Karpathy's original framing fits perfectly. Throwing away a bad prototype costs you nothing.
Unfamiliar territory
"Show me how to stream a response from this API" gets you a working example with explanations. As a learning accelerator it's excellent — provided you actually read the explanation.
Mechanical transformations
Converting data formats, migrating a test suite from one framework to another, applying a repetitive refactor across 40 files. Clear, tedious, verifiable.
Where it breaks
Code review debt is the real cost
Generated code arrives faster than humans can review it. This is the structural problem: the bottleneck moves from writing to reviewing, and reviewing unfamiliar code is harder and less pleasant than reviewing code you watched a colleague write. Teams that don't account for this ship faster for a few months and then slow down as nobody understands the system.
Security-sensitive code
Auth, session handling, cryptography, access control, anything touching untrusted input. Models produce code that looks right and passes the happy path while missing the adversarial case. Classic failure modes include missing authorization checks on endpoints that have correct authentication, and SQL built by string concatenation because the prompt didn't mention parameterisation.
Hallucinated dependencies
Models occasionally import packages that don't exist. This has produced a real supply-chain attack pattern — sometimes called slopsquatting — where attackers register plausible hallucinated package names and wait. Always check that a suggested dependency is a real, maintained package before installing it.
Novel problems
If a problem is genuinely unlike anything in the training data, models don't say "I don't know." They produce confident, plausible, wrong code. Novel algorithms and unusual domain constraints are where confident output is least correlated with correct output.
Architecture
"Should this be one service or three?" depends on team topology, deployment constraints, and organisational realities the model can't see. It'll answer anyway.
The single most dangerous property of AI-generated code is that its confidence looks identical whether it's right or wrong. Human juniors signal uncertainty — they hedge, they ask. Models produce the same fluent tone for a correct implementation and a fabricated API. Your review process cannot rely on tone as a signal.
Practices that make it safer
Keep diffs small
A 40-file change is unreviewable and you will rubber-stamp it. Ask for one concern at a time. Small diffs are the highest-leverage habit here.
Let types and tests carry the load
Static types catch a real class of AI error at the boundary — wrong shapes, missing fields, null handling. TypeScript, or Python with type hints and Pydantic, converts "looks plausible" into "actually type-checks."
// A schema at the boundary catches what review misses
import { z } from "zod";
const CreateUser = z.object({
email: z.string().email(),
age: z.number().int().min(13),
role: z.enum(["admin", "user"]),
});
export function createUser(input: unknown) {
const data = CreateUser.parse(input); // throws on bad shape
return db.users.insert(data);
}
Tests matter more than usual, with a caveat: if the model writes both the implementation and the tests, the tests encode the same misunderstanding. Write the test cases yourself, or at minimum read them adversarially and add the edge cases the model skipped.
Commit constantly
AI changes are sweeping. A clean commit history is your undo button. Commit before each significant generation so you can bisect and revert cleanly.
Review as if it came from a stranger
Not a junior developer — a stranger with no context on your system, no stake in its future, and unlimited confidence. That framing produces better reviews than "the AI probably got it right."
Never skip review on the sensitive paths
Auth, payments, permissions, data deletion, anything handling PII. Slow down where mistakes are expensive.
A concrete review checklist
Generic advice to "review the code" doesn't survive contact with a 300-line diff at 5pm. These are the questions worth asking specifically because they target where models fail rather than where humans fail:
- Does every endpoint check authorization, not just authentication? Knowing who a user is and checking whether they may do this are different, and models routinely deliver the first while omitting the second.
- Is every database query parameterised? Search the diff for string concatenation near SQL.
- Does every dependency in the diff actually exist, and is it the package you meant? Check the download count and the repository.
- What happens on the unhappy path? Empty arrays, null fields, network timeouts, duplicate submissions. Models write for the happy path by default.
- Are errors swallowed? A bare
catchthat logs and continues is a common generated pattern and a debugging nightmare later. - Does this silently widen scope? Loosened CORS, a permission broadened to make something work, a check commented out.
If you review nothing else, review the first two. They're the ones that turn into incidents rather than bugs.
Be clear about who owns it
The person who merged the code owns it. Not the model, not the tool vendor. This sounds obvious until an incident review asks why a vulnerability shipped and the answer is "the AI wrote that part" — which is not an answer. Teams that establish this norm early tend to review more carefully, because authorship and accountability stay attached.
The productivity gain is real and the risk is real, and they don't apply to the same code. Vibe coding freely on a prototype is smart. Vibe coding on your permission model is how you end up in an incident review. The skill worth developing is knowing which one you're touching.
The honest debate
The case for: it lowers the barrier to building software, removes genuine drudgery, and lets small teams move at a scale that used to require funding. For prototyping and validation, the speedup is not hype.
The case against: it produces codebases nobody deeply understands, and understanding is what you need when things break. It can erode the fundamentals juniors build by struggling through problems. And it makes technical debt cheap to create and no cheaper to service.
Both are true. The disagreement is usually about which code people are picturing.
When not to vibe code
- You can't evaluate the output. If you couldn't write it yourself, you can't tell whether it's right. Use AI to learn the domain first.
- The code will outlive the sprint. Long-lived code gets read far more than written. Optimise for the reader.
- Failure is expensive. Regulated domains, financial calculations, anything where a subtle bug is a headline.
- You're already lost. Generating more code into a system you don't understand deepens the hole.
What to do with this
Vibe coding isn't a replacement for engineering and it isn't a fad. It's a mode — an appropriate one for a specific class of work.
Use it deliberately: full speed on prototypes, boilerplate, and disposable code. Slow and careful on core logic, security boundaries, and anything you'll maintain for years. The developers getting the most out of this aren't the ones who accept every suggestion or the ones who refuse to try — they're the ones who know which mode they're in and can switch on purpose.
Karpathy was right that fully giving in to the vibes is fun and productive. He was also right that it was for weekend projects. Both halves of that sentence are the point.