Skip to content
Epic Software Labs
All trends

Product Engineering

Vibe coding: what it is, where it works, and where it costs you

What vibe coding is, where it is genuinely the right call, and the measured risks — including package hallucination rates and slopsquatting attacks.

8 min readEpic Software Labs

Key takeaways

  • Vibe coding means accepting AI-generated code based on whether the result behaves correctly, without reading the implementation closely.
  • It is excellent for throwaway work: prototypes, internal tools, one-off scripts and exploring whether an idea is worth building properly.
  • It fails on anything you have to maintain, because the cost arrives later — as code nobody understands, in a system nobody can safely change.
  • The deciding question is not quality but lifespan. Ask how long this code has to live and who has to change it next.
  • The dangerous case is a vibe-coded prototype that quietly becomes production because it worked well enough to demo.
  • Dependency hallucination is measurable and still present: 4.62%-6.10% of imports on 2026 frontier models name packages that do not exist, which is the attack surface slopsquatting exploits.

The term arrived as a joke and stopped being one within about six months. Andrej Karpathy described a way of working where you "fully give in to the vibes" — prompt, run it, prompt again, and never really read what came back. It was self-deprecating. It also described what a lot of people had quietly started doing.

The interesting question is not whether vibe coding is good or bad. It is which category of work it belongs to, because the answer is unusually clear-cut.

What it actually is

Vibe coding is a review posture, not a tool. You are vibe coding when you accept generated code on the evidence of its behaviour rather than its content — it ran, the output looked right, ship it.

That is a real and legitimate mode. Every engineer has used a library without reading its source, and that is the same trade: trusting behaviour over inspection, because reading it is not worth the time.

The difference is that a library has been read by other people, has a maintainer, and has been battered by thousands of users. Freshly generated code has none of those. You are extending trust that nothing has earned.

Where it is straightforwardly right

For work with a short, known lifespan, reading every line is waste. Vibe coding is the correct engineering decision in all of these:

  • Prototypes that answer a question. Does this interaction feel right? Is this API usable? Build it, look at it, delete it.
  • Internal tools with one or two users. The migration script, the dashboard for the ops team, the thing that reconciles two spreadsheets once a quarter.
  • Exploration. Trying four approaches quickly to find out which is worth doing properly.
  • Learning a new library. Generating working examples is often faster than reading the documentation, particularly for badly documented libraries.
  • Anything you would otherwise not build at all. A lot of vibe-coded software exists in the place where nothing previously existed, and it is a clear improvement on nothing.

Where the cost lands

The failure modes are specific and worth naming, because they do not announce themselves at the time.

Nobody can debug it. The most expensive one. Production breaks, and the person on call is reading code for the first time under pressure, with no mental model of why it was built that way.

Security flaws that look like ordinary code. Missing authorisation checks, injection-prone string building, secrets in the wrong place, overly permissive defaults. These are not exotic — they are the OWASP list — and they are invisible if nobody reads the diff.

Unvetted dependencies, and a measured attack surface. This is the failure mode with the hardest numbers attached, so it is worth being precise.

A USENIX Security '25 study generated 2.23 million code samples across sixteen code-generating models in Python and JavaScript and measured how often the models imported packages that do not exist on PyPI or npm. Hallucination rates ran from 5.2% on commercial models to 21.7% on open-source models, and the invented names were not random: roughly 38% were conflations of two real packages, 13% typo-variants, and 51% outright fabrications (USENIX).

That predictability is the problem. A name a model reliably invents can be registered by someone else — the attack now known as slopsquatting. The victim is not a developer who mistyped; it is a developer who never typed at all.

A 2026 replication on five frontier models released between October 2025 and March 2026 found overall rates between 4.62% and 6.10% (arXiv:2605.17062). The range narrowed. It did not close, and at the volume of code now being generated a 5% rate is a large absolute number of opportunities.

Silent error handling. Generated code loves a catch that logs and continues. Failures stop failing loudly, which means you find out about them from customers.

Architecture by accumulation. Each prompt produces a locally reasonable change. Fifty prompts later the system has no coherent shape, because no one was holding one.

How to tell whether your team is vibe coding without having decided to

Almost nobody sets out to vibe code production software. It arrives by drift, and the drift is detectable if you look for it.

The honest test is not "do we use AI" — everyone does. It is whether anyone read the diff with enough attention to disagree with it. A few probes that surface the answer:

  • Pick a merged pull request from last week at random. Ask the approver to explain what it changed and why. Not as a gotcha — as a measurement.
  • Ask how many dependencies were added in the last month and who evaluated them.
  • Look at whether review comments are still being left. A team whose comment rate has fallen while merge volume has risen has stopped reviewing and started approving.
  • Ask what proportion of changes come with a test that would have failed before them.

None of these require you to read code. All of them distinguish a team using AI deliberately from one that has quietly stopped checking.

Guardrails that keep it useful

If you want the speed without the accumulation — and you should, because the speed is real — a small number of controls do most of the work. In rough order of return on effort:

Verify dependencies mechanically. Lockfiles committed. A registry allowlist or proxy. A CI check that fails the build if a package did not exist before your build ran. Given hallucination rates around one import in twenty, this is the highest-value control on the list and it takes an afternoon.

Require a human-authored failing test. For anything that will outlive the week. It closes the loop where generated code is validated by generated tests, and it forces the requirement to be pinned down before implementation.

Cap diff size. The pressure will be to raise the cap because generation is cheap. Review is not, and review is now your constraint.

Read the security-adjacent parts line by line. Authentication, authorisation, anything handling user input, anything touching money or personal data. Fluent, well-formatted code attracts less scrutiny than messy code doing the same wrong thing, which is precisely the problem.

Put an expiry on throwaway work. A comment at the top of the file, a ticket, a calendar reminder — anything that makes promotion to production a decision somebody takes rather than something that happens.

What it means for the people doing it

There is a second-order effect worth naming, because it does not show up in any codebase metric.

Reading and debugging unfamiliar code is a skill, and it atrophies without practice. It is also precisely the skill that agentic workflows demand more of — the job shifts from producing code to verifying it, and verification is exactly the muscle that vibe coding lets you stop using.

Teams that use AI heavily and stay strong tend to keep some deliberate practice in the loop: reading diffs properly rather than skimming, occasionally debugging without assistance, reviewing each other's work with real attention. Not out of nostalgia — because the capability is load-bearing, and by the time you notice it has gone, you need it.

A usable rule

Before you start, answer one question: how long does this code need to live, and who changes it next?

LifespanOwnerApproach
DaysYou, then nobodyVibe code freely
WeeksYouVibe code, add tests to the parts you will rely on
MonthsYour teamRead the diffs, normal review, real tests
YearsPeople who have not joined yetFull review, tests, documented decisions

Note what is not on that axis: how complicated the code is, how good the model is, or how confident you feel. Those are the variables people actually use, and they are the wrong ones.

Promoting a prototype properly

If a vibe-coded thing turns out to matter, the move is not to gradually clean it up in place. It is to treat it as a working specification.

  1. Write down what it does, from observed behaviour. You are producing the specification you skipped — see how to scope a software project for the format we use. You now have a requirements document you did not have to guess at — this is the genuine value the prototype created.
  2. Decide what actually needs to be kept. Prototypes accumulate features nobody uses.
  3. Rebuild the parts that carry risk with review and tests: auth, data handling, money, anything user-facing that fails visibly.
  4. Keep what survives inspection. Plenty of generated code is fine. The point is that somebody has now read it and is accountable for it.
  5. Delete the prototype. Two versions of the same thing is worse than either.

Got a prototype that became production?

One of the most common engagements we take. We rebuild the parts that carry risk — auth, data handling, anything that fails visibly — without throwing away the parts that work, and hand back something your team can own.

Start a project

Where vibe coding sits against the other shifts

It is easy to read this as a standalone phenomenon. It is better understood as one end of a spectrum that also contains the more disciplined practices, and the useful question is which end a given piece of work belongs at.

PracticeReview postureBest for
Vibe codingAccept on behaviourThrowaway work with a known short life
Agentic codingRead the diff, test-firstProduction work with a fast feedback signal
Spec-driven developmentSpecification is the artefactWell-understood work with clear acceptance criteria

All three use the same tools. What separates them is how much verification you attach, and the mistake is not picking the wrong one — it is picking without noticing you are picking.

The term will probably not survive

A prediction, offered with appropriate uncertainty: "vibe coding" is likely to stop being a useful label within a year or two.

Terms like this describe a transition rather than a stable state. They name the moment when a practice is novel enough to need a word and contested enough to argue about. Once the underlying capability becomes ordinary, the label dissolves into the general vocabulary — nobody says "using a compiler" as though it described a philosophy.

What will outlast the term is the underlying decision, which is not really about AI at all: how much verification does this code warrant, given how long it has to live and who has to change it next. That question predates language models by decades and will still be the right question long after this particular phrase stops being funny.

What this trend is really telling us

Vibe coding is a symptom of something structural: the cost of producing code fell dramatically and the cost of understanding it did not move at all. So the rational response is to produce more code and understand less of it — right up until the moment understanding is what you need.

The teams handling this sensibly have stopped treating "should we use AI" as the question. They have made lifespan an explicit, up-front decision, and they attach a review standard to it. Throwaway work gets thrown away. Permanent work gets read by a person.

That is a boring conclusion, and it is holding up better than the arguments on either side of it.

Frequently asked questions

What is vibe coding?

Vibe coding is building software by describing what you want to an AI model and judging the result by whether it appears to work, rather than by reading and understanding the code it produced. The term was popularised by Andrej Karpathy in early 2025 to describe a mode of working where you 'fully give in to the vibes' and stop reviewing the diffs.

Is vibe coding bad practice?

It depends entirely on the lifespan of the code. For a prototype that will be deleted next week, reading every line is wasted effort and vibe coding is straightforwardly the right choice. For a payments system that ten engineers will maintain for five years, it is negligence. The mistake is not vibe coding — it is vibe coding something that turns out to be permanent.

What are the risks of vibe coding in production?

The main ones are unreviewed security flaws, dependencies nobody vetted, error handling that silently swallows failures, and — most expensively — a codebase that no human on the team can reason about. When something breaks at 3am, the person on call cannot debug code they have never read and that no one can explain.

What is slopsquatting?

Slopsquatting is a supply-chain attack that registers malicious packages under names that AI models are known to hallucinate. It works because the hallucinations are predictable rather than random — a USENIX Security '25 analysis of 2.23 million generated code samples found non-existent package imports at rates of 5.2% on commercial models and 21.7% on open-source ones, with about half being consistent fabrications. A 2026 replication on frontier models measured 4.62% to 6.10%. The defence is mechanical: lockfiles, a registry allowlist or proxy, and a CI check that every dependency existed before your build ran.

How do you move vibe-coded work into production safely?

Treat it as a specification rather than an implementation. The prototype has told you what to build and proven the idea works; now rebuild the parts that matter with tests, review and someone who understands each decision. Some of the generated code will survive that process unchanged, which is fine — the point is that it has now been read by someone accountable for it.

Does vibe coding make engineers worse?

It can, in a specific way: skill in reading and debugging unfamiliar code atrophies if you never do it, and that is precisely the skill agentic workflows demand more of. Teams that use AI heavily and stay strong tend to keep deliberate practice in the loop — reading diffs properly, debugging without assistance sometimes, and reviewing each other's work carefully.

Can vibe coding be used for production software?

Not as a review posture, no — but the code it produces can end up in production perfectly safely, provided it goes through the same reading, testing and review as anything else first. The distinction is not where the code came from but whether anyone accountable has read it. Treat a vibe-coded prototype as a working specification, rebuild the parts that carry risk, and keep what survives inspection.

How do we stop prototypes from becoming production by accident?

Make promotion an explicit decision rather than a default. In practice: put a visible expiry on throwaway work, keep prototypes in a separate repository or branch that cannot deploy, and require the same review and test standard before anything moves. The failure is almost never someone deciding to ship unreviewed code; it is a demo that went well and was never formally promoted.

Does vibe coding save money?

On throwaway work, yes and substantially — reading code you are about to delete is pure waste. On anything you maintain, the saving is a loan. You are borrowing time from whoever debugs it later, at an interest rate set by how little of it anyone understands. That trade is sometimes worth making deliberately; it is rarely worth making accidentally.

Is vibe coding the same as using an AI coding assistant?

No, and conflating them causes most of the confusion around the term. Using an assistant describes a tool. Vibe coding describes a review posture — accepting output on the evidence of its behaviour rather than its content. You can use the most capable agent available and read every line, which is not vibe coding; you can use basic autocomplete and accept everything unread, which is.

What should a non-technical founder ask about this?

Ask whether anyone has read the code that runs your business, and whether dependencies are verified before they enter the build. Those two questions cover most of the exposure without requiring you to evaluate any code yourself. The governance framing is covered in more detail in our guide on whether AI-generated code is safe to ship.

References & further reading

  1. [1]
  2. [2]
  3. [3]
  4. [4]
  5. [5]
  6. [6]
  7. [7]