nanda mochammad
Applied AI

Vibe coding vs engineering: where is the line?

13 min read

Hello everyone. Today I want to talk about the line between vibe coding and engineering, and how to tell which side of it a task belongs on.

By the end of this article, you will be able to place any coding task on a five-level spectrum, use a simple stakes-and-lifespan grid to decide how much of the code you need to understand, and apply one rule before you accept code unread: you can vibe what you could verify.

A learner I mentor demoed a feature last month that impressed me. It was a working search-as-you-type screen, debounced, with a tidy empty state. Then I asked the question I always ask: “Walk me through what happens when the network is slow.” Silence. Not shy silence, blank silence. They had not really written that code. They had talked it into existence, prompt by prompt, accepting each diff without reading it. It ran and it looked right, and they could not tell me what it did.

That is vibe coding, and my first reaction was split. Part of me wanted to celebrate. A beginner shipped something real in an afternoon that would have taken me a week when I started. Part of me wanted to worry. They had a feature and no mental model of it. That means they have a problem they cannot see. This article is my attempt to turn that split into a line between vibing and engineering that I can teach, one that holds up when the stakes are real.

What it actually is

Vibe coding is a real thing, and it works

The term comes from Andrej Karpathy. He described it in a widely shared tweet in February 2025: you “fully give in to the vibes,” you talk to the model, you accept the diffs without reading them, and when something breaks you paste the error back and accept whatever it suggests. His framing was playful and honest. He was describing throwaway weekend projects, not a banking core. Plenty of careful engineers use AI all day. What defines vibe coding is that you stop reading the code. The model is the author and you are the user.

It also works. For a prototype, vibing is effective. I have built a throwaway script to reshape a messy CSV, a quick SwiftUI screen to check a layout idea, and a one-meeting chart, all by vibe. All of it was faster than I could have done by hand. None of it was regretted. When the goal is to find out whether an idea is worth building, the speed is the point. Reading every line would be waste.

So the question for any task is how much do I need to understand what I’m shipping? That turns out to be a spectrum, not a switch.

The spectrum

Five levels, defined by your relationship with the code

“Vibe coding versus engineering” sounds like two options. In practice there are degrees. What changes between them is how deeply you are connected to the code, not how it was written. I find it useful to name five levels. Each one is a deeper question you can answer about the code in front of you.

Diagram: a five-level spectrum from pure vibe coding to disciplined engineering, where each step adds a deeper relationship with the code: from never reading the diff, to reading it, to being able to debug it, to being able to rewrite it, to owning the design. LEVEL 0 Pure vibes talk, accept, never read it "it runs" LEVEL 1 You read it skim the diff, roughly follow "looks right" LEVEL 2 You can debug it find the bug when it breaks the line LEVEL 3 You could rewrite it redo it by hand if you had to no AI needed LEVEL 4 You own the design you chose the shape; AI typed engineering vibe coding · you trust it engineering · you understand it each step deepens your relationship with the code
The spectrum is not about whether you used AI. It is about how far you can stand behind the result. Each step to the right answers a harder question: do you read it, can you debug it, could you rewrite it, did you design it?
  • Level 0, Pure vibes. You describe, you accept, you never read the diff. Your only test is “it runs.” Fine for a spike, a time bomb for anything else.
  • Level 1, You read it. You skim the generated diff and roughly follow what it does. You would catch something obviously wrong, but not something subtly wrong.
  • Level 2, You can debug it. When it breaks at 2am, you can open the file and find the actual line. You understand the control flow well enough to reason about it.
  • Level 3, You could rewrite it. Take the AI away and you could build this by hand. The model saved you typing, not thinking.
  • Level 4, You own the design. You chose the architecture, the boundaries, the data flow. The AI filled in the implementation inside a shape you decided. This is engineering with a faster keyboard.

Notice that Levels 3 and 4 still use AI heavily. They are not a rejection of it. The difference is that understanding lives in your head, not only in the chat history. Robert C. Martin’s line in Clean Code is the reason for caring about this at all. He estimates that the ratio of time spent reading code versus writing it is well over ten to one. If that is true, code you cannot read is a debt you have to repay every time you come back to it.

Stakes and lifespan

What level a task deserves: a risk matrix

Knowing the spectrum does not tell you where to be. A Level-0 spike and a Level-4 payment flow are both correct, for different tasks. Two things decide the right level. Stakes: what happens if this is wrong? Lifespan: how long will this code live and who maintains it? Plot them and the advice falls out of the grid.

Diagram: a risk matrix with stakes on the vertical axis and lifespan on the horizontal axis. Low-stakes throwaway work is safe to vibe; low-stakes long-lived work is mostly fine; high-stakes throwaway work needs a review; high-stakes long-lived work must be engineered. STAKES LIFESPAN high · money, data, users low · just you short · throwaway long · you maintain it Vibe a draft, then review a quick migration script, a one-off data backfill short life, but it touches prod: read every line before you run it Engineer it auth, payments, anything with user data, core flows AI may draft, you must own: understand, test, review every line Vibe away prototypes, spikes, a chart for one meeting, scratch tools nothing breaks if it's wrong; speed is the whole point Vibe, but skim it a personal tool you'll reopen, internal dashboard, side project low blast radius, but future-you has to read it, keep it legible
Stakes ask what breaks if the code is wrong; lifespan asks how long you have to live with it. Low-and-short is pure vibe territory. High-and-long is engineering you cannot skip. The two off-diagonal corners are where people get burned by treating them like the corner they wish they were in.

Best for vibing: the bottom-left corner, low stakes, short life. Prototypes, exploratory spikes, a chart you need for one meeting, a script you will delete on Friday. Nothing breaks if it is wrong, and nobody inherits it. Vibe with a clear conscience. Reviewing it line by line would be the mistake.

Watch out: the two off-diagonal corners, because that is where good intentions go wrong. Low-stakes-but-long-lived code (a personal tool, an internal dashboard) is mostly fine to vibe. But future-you has to reopen it, so keep it readable. The dangerous corner is high-stakes-but-short-lived. A quick one-off migration script feels throwaway, so people vibe it and run it straight against production. Its life is measured in seconds. Its blast radius is your entire users table. Short life is not the same as low stakes.

The top-right corner (high stakes, long life) is the one place the spectrum has a hard floor. Authentication, payments, anything touching user data or money, anything in a core flow that ten other features depend on. Here AI can still draft, but you cannot ship below Level 4. You have to own it.


Vibe vs engineer, side by side

DimensionPure vibe (L0-1)In between (L2)Engineered (L3-4)
You read the codeNo / skimYes, to follow itYes, you own it
Can debug itOnly by re-promptingYes, find the lineYes, fluently
Could rewrite it without AINoSlowlyYes
Tests”It ran once”A few happy pathsEdge cases + failure modes
Speed to first resultMinutesFastSlower, deliberate
Right forSpikes, throwaways, demosInternal tools, side projectsProduction, money, user data
What it costs you laterNothing (you delete it)Some re-readingMaintainable on purpose

The last row decides everything. Martin Fowler’s idea of technical debt is the right lens. Shipping code you do not understand is borrowing against your future speed. You pay the interest every time you have to change it. For a prototype you will throw away, that loan never comes due, so vibe freely. For a production system, the interest grows, and “the AI wrote it” is not a payment plan. Simon Willison, one of the more balanced voices on AI-assisted programming, draws a line between careful work with these tools and “vibe coding.” The difference is whether you remain responsible for the output.

The mentor’s dilemma

AI can write your code. It can’t own your understanding.

Back to my learner with the search screen. The danger of vibing for a beginner is different from the danger for me, and worse. When I vibe a script, I am skipping work I already know how to do. My mental model exists. I am choosing not to spend it. When a beginner vibes a feature, the mental model never forms in the first place. They ship the artifact and skip the learning that was the point of the exercise. They are not standing on the shoulders of the tool. They are hanging from it. They will fall the moment it lets go, and it lets go the instant the bug is one the model cannot fix in one shot.

The struggle was the learning, not an obstacle to it. A debugger session where you finally understand why the request fired twice teaches you something a clean generated diff never will. Take that away and you get someone who can produce code and cannot reason about it. In a teammate, that is more dangerous than someone slower who understands their work, because the confident-but-hollow version passes review and reaches production.

So as a mentor I have stopped grading the demo. A working screen tells me almost nothing now. I grade the walkthrough: show me the failure path, change a requirement live, explain why it is structured this way. That is the only signal that survived the arrival of tools that make the artifact free.

The rule

You can vibe what you could verify

After all the nuance, here is one rule that fits in a sentence and survives a deadline: you can vibe what you could verify. If you are able to review the output, read it, judge whether it is correct, and catch the subtle bug, then accepting it without reading this time is a time-saving choice you are qualified to make. But if you couldn’t have caught the mistake, then you are gambling, not saving time. And “the AI wrote it” will not be a defense when it breaks.

This turns the whole thing into a question about you, not about the AI. The same generated diff might be safe for me to vibe and reckless for my mentee to vibe, because our ability to verify differs. It is also why the rule scales with stakes on its own. For a throwaway script, “verify” means “glance at it,” and almost anyone clears that bar. For a payments change, “verify” means “understand it well enough to defend it in a post-incident review,” and far fewer do. The bar rises where the risk does.

Run a task through these gates before you accept code unread:

Should I vibe this?

Throwaway, just me?low stakes, short life→ Vibe it, ship it
Touches money, data, or users?high stakes→ Engineer it (own every line)
Will someone maintain it?long life→ Read it, keep it legible
Could you catch the bug?if no→ Don’t ship it unread

The last gate is the universal one. If you couldn’t have reviewed it, you took a risk you couldn’t price.

Recap

The goal of this article was to give you a way to decide how much of your AI-generated code you need to understand. Here are the main points.

  • Vibe coding means accepting AI output without reading it. It works well for prototypes and throwaway work.
  • There are five levels, from pure vibes to owning the design. Your real level is the first question you answer “no” to: did I read it, can I debug it, could I rewrite it, did I design it?
  • Stakes and lifespan decide the level a task deserves. Low-and-short is vibe territory. High-and-long needs Level 4. Short life is not the same as low stakes.
  • For beginners, vibing skips the struggle that builds the mental model. Grade the walkthrough, not the demo.
  • One rule: you can vibe what you could verify. If you could not catch the bug, do not ship it unread.

Treating vibe coding as the enemy of engineering only makes you slower at the prototypes where it helps. They are two settings on one dial. The skill that matters now, the one I am trying to teach and still practising myself, is reading the task well enough to know which setting it deserves. Be generous with the vibes where nothing is at stake. Be strict about understanding where something is. Never confuse a thing that runs with a thing you can stand behind.

I hope this writing helps you. Thanks for reading.

Cited sources