Almost a decade ago, I wrote about Java Developer vs. Software Engineer. At the time, I didn’t realize how deeply people had tied their professional identity to Java. My goal was to distinguish between someone defined by a specific language and someone who thinks more broadly about solving problems.
The whole discourse started from one premise. Java had become the way. Many developers began thinking from Java outward. The tool became the lens through which every problem was viewed. And when a problem didn’t fit that lens, the problem was bent until it did.
I don't want to stretch that analogy too much, because AI is not just another programming language or framework. It changes the economics of writing software. Still, the old pattern is there. A tool becomes powerful, people wrap their identity around it, and then the craft gets reduced to the tool.
Now, the question is not whether AI can write code. It does. It does it better every day. The question is what kind of work comes out of that process and what happens when it enters a real codebase, with real users, real data, real compliance requirements, real incidents, and real people who have to maintain it.
That is where I see the difference between a vibe coder and a software engineer. A vibe coder is someone who wants to test an idea by generating software as a prototype. A software engineer is someone who thinks about the entire software development lifecycle. So the difference is not the tool. The difference is where the responsibility starts and where it ends.
Pretty please, can I merge?
The Wrong Metric
A lot of the discussion around vibe coding still measures the wrong thing. People show how quickly they went from idea to app. That has value, especially when the goal is to test an idea. In a software development team, someone has to review it. Someone has to understand the intention behind it. Someone has to decide whether the dependency belongs there. Someone has to check whether the test verifies behaviour. Someone has to apply schema changes. Someone has to coordinate the change between teams. Someone has to work on a rollback. Someone has to write a runbook. Someone has to answer to a page.
None of these are part of anyone's toy project. So I would measure AI-generated work by a different metric: time to safe merge. That includes reviewability, risk, test quality, ownership, rollback, and whether the author can explain the meaningful decisions in the change. If AI makes code generation cheaper but makes safe merge more expensive, the team has not gained as much as it thinks.
This is the first difference. A vibe coder measures time to first working version. A software engineer measures time to safe merge. Time to first working version is useful when the work is discovery. Time to safe merge is necessary when the work enters a shared codebase. It includes review cost, test cost, rollout cost, rollback cost, coordination cost, and future maintenance cost. That is why the demo is the wrong finish line. It only proves that something can be shown, not that it can be absorbed by a team.
Output Is Not Progress
AI-assisted code should be better, not bigger. If the tool lets you generate more, the human has to constrain more. Otherwise you are not saving work. You are moving it downstream, where maintenance becomes someone else's chore. AI-assisted code cannot be held to a different standard. It has to meet the same bar as code written by hand. So it should be narrow. It should have one reason to exist. It should not include unrelated cleanup. It should not reformat half the file because the model felt like it. It should not add a package without a clear explanation.
If the change is large because the model generated too much, split it. I've experienced this a lot. It happily creates so many boilerplate for a thing that you can write in ten lines. So, if the author cannot explain why each meaningful file changed, it is not ready. That is basic ownership.
The second difference is the unit of work. A vibe coder treats generated output as progress. A software engineer treats any change as the unit of responsibility. Generated output can be large, messy, and temporary. A real change management cannot be that casual. It has to be narrow enough to review, explainable enough to trust, and bounded enough to merge without dragging half the system with it. This is where speed either becomes useful or turns into review debt.
AI Cannot Take the Blame
Reviewing generated code is not the same as reviewing normal code. When a human writes code, there is usually a decision trail. It might be flawed, but at least there is a person who can explain the path. You can ask why they used that abstraction, why they put the rule there, why they chose that package, why they made the test look that way.
With AI-generated code, some of those decisions are not decisions. They are completions. If the author has not converted generated output into owned work, the reviewer is doing two jobs: review and authorship recovery.
Ownership is the third difference. A vibe coder can say the model generated it. A software engineer has to say, I own it. That means the author has to convert generated output into an engineering decision before asking for review. The code may have started with the model, but the accountability cannot stay there.
Context Is Not Just Files
A model can read a lot of code now. That does not mean it understands the system. Some context lives in code, but a lot of engineering context lives elsewhere. It lives in incidents, old migrations, customer behaviour, operational pain, team conventions, security requirements, compliance rules, and strange decisions of the past.
The model does not have that unless you give it. Even when you give it, it does not carry that context the way an engineer does. It works inside its context window. The larger the task, the easier it is for the model to optimize locally and damage something globally.
That is why "just ask it to fix the whole thing" is a bad habit but also does not work yet. I was lazy enough to do it multiple times. A better pattern is to reduce the decision space before asking for code. When I am more prescriptive, it does better work for me. But what does being prescriptive require? That I understand what the hell I'm trying to do. I think this is where experienced engineers will get most of the value from AI. Not by giving the model more freedom, but by giving it less. Freedom is useful for a weekend hacking. Production needs constraints.
This is the fourth difference. A vibe coder gives the model a goal, but a software engineer gives the model a bounded task. The bounded task is where the engineering happens. Use this interface. Do not touch this layer. And so on. A good prompt is not magic here. It is usually evidence that the engineer already understands the boundary.
Vibe Coding Belongs In The Delivery Process, But Not Everywhere
In a recent interview which I highly recommend watching, Andrew Kelley, who created Zig, said the project bans AI contributions and called them invariably garbage. I hear them. Maintainers are seeing large AI-generated pull requests with unrelated changes, broken legacy behaviour, strange dependency additions, and contributors who cannot explain the code they submitted.
But the mess they describe is not a verdict on AI. It is what vibe coding produces when it lands on the wrong side of a line. So I would not ban it. I would place it.
That line is the fifth difference: discovery vs delivery. The same pull request that takes a maintainer's afternoon is harmless when you're spiking a prototype. Nobody owns that throwaway code. Discovery can tolerate mess because the goal is learning or fast iteration on an idea. Delivery cannot tolerate unexplained mess because the goal is a real business outcome. You can't say we were 99.9% correct. Sometimes it just has to be correct. That is the practical line.
The honest caveat is that this line keeps moving. As tools get better at tests, rollback, and review, some of the safe merge cost will shrink. Shrinking is not vanishing. As long as someone has to own the outcome, there has to be some level of discipline. Use vibe coding where the cost of being wrong is low, and use engineering discipline where the cost of being wrong belongs to customers, teams, or the business.
The Apprenticeship Problem
Junior engineers are going to use AI. They should. Used well, it can explain code, compare approaches, generate examples, and make learning faster. But there is a bad version of this.
If a junior engineer uses AI to avoid understanding the system, they may deliver more while learning less. That is a poor trade. The first few years of engineering are where people build the mental model. They need to build that model in their own head, not borrow it from the machine.
You do not build that judgment by staying outside the system and asking the model to keep fixing it. This is one of the hardest parts for managers. AI can make juniors look more productive in the short term while weakening the learning loop that turns them into strong engineers. Kelley's deeper reason for the Zig ban connects here. He calls code review contributor poker, the way a project finds people worth growing into the core team. AI submissions break that because the contributor is not learning the codebase or absorbing the feedback.
And this is the last one. Engineering requires some level of apprenticeship. Vibe coding tempts you into working alone. People work and learn in teams. Software engineers improve their craft by working with others. The job is not just code. The job is judgment, not output. A software engineer has judgment about what's risky and what's not. That judgment is built through contact with the system and people.
The Difference
A vibe coder is useful when the main output is ideation. They can reduce the distance between an idea and something clickable. Many ideas deserve that treatment before anyone spends real engineering capacity on them.
A software engineer is needed when the main cost is ownership. They control what enters the system, how it is reviewed, how it is secured, how it is tested, how it is operated, and how it will be changed later. The distinction is operational. It is also not a fixed identity. The same person should vibe code in discovery and switch into engineering for delivery. The skill is knowing which mode you are in, and not letting the habits of one leak into the other. Vibe coding can help you learn faster. Software engineering helps you avoid paying for that learning forever.
