Vibe Coding Is Not Software Engineering

· by

A while back I spent a day vibe coding. The rule was that I wasn't allowed to write any code, only prompt. By the end of the day I had a working API and a working website. I'd also been given SHA-1 for hashing passwords, two markdown renderers doing the same job on two different pages, and a deployment config that was mostly nonsense. I wrote it all up at the time.

That's vibe coding. It's quick, it's good fun, and I wouldn't have put either of those projects in front of a customer as they were.

The rest of the job

Writing the code is the easy bit. Software engineering is getting that code into production without breaking anything, keeping it there, and putting it right fast when you do break something. Vibe coding covers the first part and stops.

Tests

Any team that's any good has a pipeline, and the pipeline runs the tests. Unit tests on every line, because they cost nothing to write and nothing when they fail. Integration tests that chain those units together and check they still agree with each other. End-to-end tests, where you put one input in at the front and check what comes out the back, through the UI, the API, the business logic and the database. And performance tests, because a button that takes five seconds to do anything is a bug whatever the unit tests say.

Most teams never got round to the end-to-end tests. They were slow to write, slower to run, and they broke every time someone moved a button. That reason has gone. An agent will click through every path in the UI for as long as you let it, and it doesn't get bored.

Pipeline first

If you want to vibe code something people are going to depend on, sort the pipeline out first. A test only counts if something runs it on every change and blocks the merge when it fails, whoever or whatever wrote the change.

The pipeline is also what gets you out of trouble. When something breaks in production, the fix goes out through the same checks as everything else, and you can ship it in the middle of an incident without wondering what else you've just broken.

Tests from the code

There's a catch, and it's the one I keep banging on about. Ask the agent that wrote the code to write the tests for it and you get tests that describe the code. They confirm the code does what the code does. Coverage goes up and nobody has asked whether any of it is right. I've written about this before.

Take the SHA-1 password hash from my day with Cursor. A unit test generated from that code checks the SHA-1 hash comes out as expected, and it passes. The code is still wrong, because nobody told the test that industry standard means bcrypt or Argon2.

So a test is only worth something if someone knew the right answer before the agent ran it, and that answer comes from what the feature is for. The agent will write the test and click the buttons. You have to tell it what the buttons are supposed to do.

The job

That last part is the job now, and it used to be a small piece of it.

An engineer used to drive the whole thing. You worked out the design, typed the code, debugged it and shipped it, and if you didn't understand something it didn't get done. Nobody had to check you understood your own code, because there was no other way for it to exist.

An agent will build things you don't understand at all, and build them fast. So the engineer has gone from driver to orchestrator. You point the agents at the work, you read what comes back, and you bring the vision, the judgement and the taste, because the agent has none of them. That means knowing what should exist before it's built, and knowing it's wrong when it comes back looking right.

Still yours

The agent doing the typing doesn't change who owns the result. If you ship it, it's yours, even if you never typed a line of it. You're the one who answers for it when it breaks, and "the agent wrote that bit" is no use to the customer or to whoever is on call.

The test I use is whether I could explain the change with the code closed. If I can, it's mine to vouch for. If I can't, I haven't finished, and a green pipeline doesn't finish it for me. The pipeline is there to catch what I miss, and what goes out is still on me.

That's the line between the two for me. Vibe coding accepts what comes back, and an engineer answers for it.

Juniors

I learnt all of that as a junior, and nobody taught it to me. I had to work things out for myself, I didn't ask anyone until I was stuck, and being stuck was most of the learning.

In the UK, LinkedIn's figures have hiring of entry-level software engineers down 27% in the year to April [1]. The government report they come from is careful to say that isn't proof AI did it, and hiring was down across the board. Whatever the cause, a lot fewer people are starting the job where I learnt mine.

The ones who do get in have an agent from the first day, and it will get them through a ticket without them understanding any of it. The old job made you understand the code because you had to write it, and the new one doesn't. I've already had a team come to me over one missing field, in code a model had written for them, without trying to debug it first.

So how do you turn a junior into a senior now, someone with vision, taste and judgement, when the work that used to build those is the work the agent does? I don't know, and I don't think the industry does either. At the end of that day with Cursor I worried that companies would hire seniors with agents in place of juniors, and that the supply of seniors would dry up. It was a thought experiment then.

To finish

An agent will write you as much code as you want. Until something checks it against what it was supposed to do, on every change, before a customer sees it, you've got a weekend project. Knowing what it was supposed to do, and owning it when it doesn't, is the engineering, and we're hiring fewer of the people who'd learn it.

Sources

  1. A snapshot of entry-level hiring in the UK (Department for Science, Innovation and Technology and LinkedIn)