
Vibe coding vs knowing the vibe
Blog
If you've not come across the term, vibe coding is where you describe what you want to an AI and let it write the code for you. You don't really read what comes back; you check it runs, and you move on. And honestly, it's fine. It's here, it's not going anywhere, and I'm not going to sit here moaning about it like it's the end of the trade.
But there's a gap in it, and it's a quiet one. Vibe coding will happily build you something that works. What it won't do is tell you whether the thing it built was the right thing to build in the first place. It reaches for the obvious path, because that's what it's trained to do, and the obvious path runs and looks right. It's just not always the path you'd pick if you'd been doing this for twenty years and knew what was coming six months down the line.
So what does "knowing the vibe" actually mean?
Mostly it's a load of small judgement calls that happen before a line of code gets written. Let me give you a couple of real ones from a project I'm on at the moment.
It handles sensitive data, so I reached for Laravel. That's a framework: a big ready-made scaffold for the boring-but-critical plumbing every app needs, logins, form validation, blocking the obvious attacks. I reach for it because all that comes already built and already tested, so I'm not hand-rolling my own login system and quietly hoping I've not left a hole in it.
Now here's the bit a prompt won't tell you: Laravel is heavy. It's a lot of framework. For a five-page brochure site or some small internal tool it's overkill, and I wouldn't go near it. So the experienced call was never "always use Laravel"; it's knowing that sensitive data earns that weight, and a simple site doesn't. It's the same developer making the opposite call, because the job is different. That weighing-up is most of the work, and it's the part a prompt skips.
The same project threw up another one. My usual database is MySQL; it's my bread-and-butter, what I reach for without thinking. But this build was API-based with Vue on the front end, which in plain terms means JSON was getting passed around all over the place. (JSON is just a common format for shuffling structured data between systems.) So I went with Postgres instead, because Postgres handles JSON natively, as a proper type you can query and index directly. MySQL can store JSON too, but a vibe-coded version will usually just dump it in a text field and pick it apart in code later, which is slower and a pain to search. Choosing Postgres up front means none of that comes back to bite.
And while we're here: why vibe-generate any of that plumbing in the first place? Laravel will build the skeleton of it for me with a single command (artisan, its built-in helper), and it comes out correct and conventional, the way any other Laravel developer would expect to find it. Asking an AI to write it from scratch burns tokens and money, and what comes back is usually a slightly worse version of something the framework already hands you for free. Why muddy the waters?
When is it worth building it yourself, then?
This cuts the other way too, mind. A lot of the time the right call is to use what's already out there instead of reinventing it; no sense writing your own when a solid, well-maintained library does the job. But not always. Sometimes the package you'd reach for is some random thing one person wrote and then walked away from. Pull that in and you've taken on two problems at once: a security risk, because nobody's patching it when a hole turns up, and a maintenance headache, because the day it breaks against a newer version of something else, it's yours to fix. In those cases I'd rather write the bit myself, keep it small, and know exactly what's in it. Knowing which way to jump there, pull in a library or build it, is a feel you pick up over years. A prompt doesn't have it.
Then there's the quiet stuff that never shows up in a demo but absolutely shows up once you've got real users on it. Indexing, for one: telling the database how to find things quickly, so a lookup across a big table takes a few milliseconds instead of grinding through every row. A vibe-coded build will cheerfully run without a single useful index, and it'll seem perfectly fine right up until the data grows and the whole thing slows to a crawl. Same goes for actually tuning the database for the server it's sitting on, how much memory it's allowed to use, that sort of thing. (Anyone who's run a busy WordPress site on a box nobody ever configured properly knows the exact flavour of slow I mean.)
What does getting it wrong actually cost?
That's the part that ties all of this together, because none of these wrong calls cost you a thing on day one. The vibe-coded version runs, it demos well, everyone's pleased. The bill turns up later, and it turns up as refactoring: ripping out the foundation and redoing it properly once the thing has grown and the original choices won't stretch any further. That's dear, in time and money both, and it's the bit nobody budgeted for. Get the foundation right at the start and the opposite happens, adding to it later is a small, calm job, because you're building on something that was made to take the weight. Shoe-horn a new feature onto the wrong base and you're fighting it every single time.
I'm not telling you to avoid these tools. I use them myself; they're quite powerful once you know what you're pointing them at. The catch is that they'll build whatever you ask for without ever stopping to ask whether it's the right thing, and answering that question is most of what twenty years on the job actually teaches you. So I still make these calls myself. It works out cheaper for the client in the long run, and you end up with something built to last, rather than something that just looked good in a demo.
If you've got a project and you're not sure it's sitting on the right foundations, or you're about to start one and want those calls made right from the off, feel free to get in touch. Happy to have a chat.
Vibe Coding · No code