Vibe Coding Isn't the Problem - It's Your Approvals Process

13 min read Original article ↗

Vibe coding is in the news these days, and for largely negative reasons. And in many cases, fair enough - vibe coding has been associated with severe lapses in security, both in terms of the products they create and the platforms used to develop them. For many, vibe coding is just not worth what you get from it - and it’s facing huge pushback in dev spaces.

Here’s the thing though - the problem was never the vibe coding. The problem is the approvals process that allows vibe coded content to proliferate unchecked. This may seem a bit of victim blaming, so let me set an expectation here - if you’re looking for a tech bro to tell you that vibe coding is the future and anyone against it is a luddite, that’s not what this article is about. I don’t think vibe coding is the best thing since sliced bread - but I also don’t think it’s the worst thing to happen in development.

What I do think it has done, however, is expose some critical flaws in the way that software - especially open-source software - gets built and released.

So let’s talk about that.

Let’s first talk about what vibe coding actually is. Put simply, vibe coding is perhaps one of the most impactful movements in recent years towards the democratisation of development.

For a long time, creating software - or really any kind of code, for that matter - was locked behind years of education or experience. And breaking into this space was difficult - you either had to hack away at your projects for months before you start to learn the cadence and standards of good development, or you had to go get an actual degree. It was heavy, difficult, and gated.

Vibe coding as a general term encompasses a lot of different development processes - but ultimately, the easiest definition is “coding done by those who aren’t necessarily coders”. Credit: Bernd Dittrich

Vibe coding flipped that entirely. Suddenly, you have huge groups of people who have never coded before able to create proofs of concept - and in some cases even MVPs. This was a monumental shift - it’s not just quicker time to value, it’s opening up a branch of value that was entirely unreachable for the average person.

And that’s a big reason why it’s so attractive for many users. The concept of just having an idea and creating it from nothing is attractive - and anyone who has been around online spaces for any amount of time can pull out a million “I have a great video game idea so I just need to find a developer” posts from their memory.

But that’s also part of the problem - vibe coding opens up access, but it doesn’t necessarily mean that the access it opens up comes with the talent, understanding, or experience needed to execute on it well.

Vibe coding is a “tool”, but calling it a “tool” is probably selling it short - it’s an enablement system in the way that the assembly line or rocket fuel was a “tool”. But for all the things it is, there’s quite a few things it isn’t.

First off, it’s a programming solution - not a solution for taste or experience. The average developer has been at the game for so long that they have a solid feel for what “right” is - and what standards or conventions actually do cumulatively. And this is how you can see vibe code at a glance - sections of code that do a simple function in an overly complex way, pointers that don’t point to what the in-line documentation claims, and issues of just bad taste.

Many vibe coders would look at this image and have their eyes almost immediately gloss over - and that’s part of the problem. Credit: Radowan Nakif Rehan

Vibe coding also isn’t some sort of shortcut to senior engineer level. One of the best values long-serving developers have is their knowledge of what the systems they’re working on actually do. Abstracting away the expertise on how to write code and the knowledge of what good code looks like, being able to explain how that code works and in what way is huge - and the lack of that understanding is often why vibe code works and then stops in its tracks.

A big issue here is also the fact that vibe coding isn’t a shortcut for maintenance. Code isn’t something you just build once and it’s good forever - it’s something you have to patch, refactor, maintain, update, debug, and continually improve. Attack vectors change as quickly as user needs, and code is a breathing artefact that needs altering. Vibe coding doesn’t shortcut that - and now you have a code base that needs to either be maintained by someone who doesn’t understand code or by a machine that already thought what it did the first time was good enough.

And finally, it’s not a tool that is self-describing. Vibe coders seem to think of vibe coding like the difference between a trowel and a shovel - but really, the difference is more akin to the one between an abacus and a MacBook Pro. In theory they can do the same things - they can both calculate numbers. But the reality of the tools are very different. You can get a number from an abacus and more or less understand what it means. Most people who own a MacBook Pro barely understand that programs run on binary, let alone the billions and trillions of calculations that happen constantly on their machine.

So here’s the reality of all of this. Considering everything I just wrote above, too often the real problem with vibe coding in production and open source projects is not just the vibe coders - it’s the maintainers who just accept and move on.

For a long time, maintainers balanced a variety of issues. Burnout from managing too many PRs, the reality that open source is seldom funded by the massive corporations which benefit from it, and a sort of communal trust that developed over time to solve these problems. We’re all in this boat together - so if I’m giving you development for free, you should trust that the effort I put into it was in good faith.

Open source maintainers already have a pretty full plate - but that doesn’t absolve them from dealing with this problem. Credit: Mohammad Rahmani

But that’s no longer the reality of open source and general production in the AI revolution - and the assumptions that we’ve made for so many years need to be fundamentally shifted. Just because code looks right doesn’t mean it is right - and while we could have trusted maintainers and PR writers to test their code in the past, we now have to take on that burden ourselves. It’s not fair - and I don’t like it as much as you don’t like it - but gone are the days where we can look at some code, see that it looks generally correct, and then run some basic unit tests and call it good.

So where do we go from here?

The honest answer here is that our entire review culture needs to be rethought from the ground up.

For decades, the implicit contract of open source and internal development has been that if a contributor submits code, they are either trying to do something malicious or genuinely trying to add to the codebase. And because of that, we’ve given it a general once-over, maybe a deeper once-over for quality, run it through some security checks, and if everything looks good on that front, started the process of merging. It was built on the assumption that anyone submitting code actually understood what they were submitting, and unless there was some glaring signal that the code was bad, we were generally ok with giving the benefit of the doubt (which is a broader and more insidious issue, but is one for a different article).

But today, that contract no longer holds. We can have massive codebases developed by seemingly experienced people with zero documentation and - worryingly - zero (or minute) understanding.

So here’s what needs to change.

As reviewers, we need to start asking contributors to walk through their changes in plain language. Don’t accept “this adds a caching function” - ask “how does this implement a cache, what happens when the cache is cold, what happens when it overflows, and what is your eviction strategy”. Better yet, force every PR to answer this proactively - if you provide the questions, AI can answer it, but demanding answers up front either makes the unknowledgeable author actually learn their code or surfaces those who understand it from the mire.

You don’t need to accuse anyone of vibe coding, either - if they can’t explain it, tell them to come back when they can, and just don’t merge it.

Vibe coding often results in a ton of files sprawling across different directories. In some cases, this is just style - I’m very guilty of this myself - but if you have something simple like “manages the colour of buttons on input”, and instead of a single JavaScript file you have ten or twenty files and dependencies, chances are you’re dealing with vibe coded content.

That’s not to say that sprawl is always indicative of vibe coding - but it’s very common, and unfortunately, it often exacerbates the problem by making the code that much more difficult and time-consuming to review.

The fix here is to just demand size limits for your PRs. A forty-line PR that one human can actually explain and read is worth ten four-hundred-line PRs that nobody understands. At scale, this is significant - and enforcing the standard of smaller units in development is a good habit anyhow.

Just validating that code works is no longer enough - we need to actively try and break it. Unit tests are fine and dandy, but we need to test code to its limit. Vibe coded solutions often deal with the first request fine but then fail when you introduce more complex queries and requests - especially if the code was meant to serve an MVP rather than a full code flow. Accordingly, you need to become adversarial and push each PR you’re considering merging. There’s a million security tools that will scan each commit - and you need to start using them.

And to be clear, this has been the advice for years - but with vibe coding, you need to be targeting different segments. In traditional security scanning, you’re looking for obvious malicious rerouting or dictionary attacks. In vibe coding, you’re looking for loop errors, plausible-looking code that fails with common edge cases, even structures that seem to reference each other but have simple errors that cause the entire house of cards to collapse.

The problem here is that much of our security and adversarial processes defend against purposeful failures with malicious intent - but rarely do they defend against accidental failures without awareness, and that is what we’re trying to solve against.

The fact is that AI is everywhere, and in many cases it’s a huge vulnerability for an engineer to not use it.

Here’s a disclosure for you - I use AI quite frequently. Do I want to? 50/50, if I’m being honest. Sometimes it creates more work than it solves. Sometimes it gives me a different perspective than I came into the process with. But always my code and the process of generating it is improved in some way. But even if I didn’t see benefit from it, the chances are that if I were an engineer in the industry with a team using AI, a choice of non-use would have career and code impacts.

So if AI is everywhere - and in many cases, engineers and maintainers can’t get away from using it to some degree - then we need to normalise disclosure. Noting something like “I used Claude for the initial boilerplate and functions then validated X, Y, and Z manually” is a huge step above our current process - but it’s a statement that is incentivised against actively by AI luddites and those who see “AI in code” as an auto-reject button.

The use of AI is no longer a dark secret - so we need to stop treating it like it is. Disclosure is the only path forward. Credit: Ben White

That doesn’t mean I’m advocating for more flexible adoption of AI vibe coded contributions - quite the opposite, actually. What I am advising is that if AI is part of the contribution, contributors must see disclosing it as a step towards acceptance of their code - and maintainers should see declaration of AI involvement as a requirement. To be clear, this is a cultural problem that’s hard to fully fix right off the bat - the people who should disclose are generally the ones least likely to do so - and as such, this is more about reshaping incentives for good-faith actors than trying to make disclosure a detection mechanism for bad-faith ones.

And to be clear here, I think AI is incredibly important in one area - accelerated time to value. Full disclosure here - I’m the Developer Relations Advocate over at FlowFuse, and I think our AI innovations are exactly what AI should be in the development space.

Of course I’m going to say that, right? Let me explain why:

  • The FlowFuse Expert connects to documentation via Retrieval Augmented Generation, meaning that flows and structures created using it are necessarily tied to understanding independent of the person using the tool. That sidesteps the understanding and style part slightly, but more than anything, it creates a deep contextual web of understanding that you just can’t value high enough.

  • The way the AI stack on FlowFuse is implemented is as a tool, not a replacement - meaning that you keep your human in the loop review cycles without losing velocity. That’s a good middle ground between accelerate to infinity through mass acceptance and locking down everything to only a small subset of knowledge-holders.

  • We develop everything in the open - and invite contributors and reviewers alike to look at each PR. Developing in the open with a culture of honesty and truth is a panacea of sorts for a lot of the issues we’ve discussed herein - and adopting this policy could get you 50% of the way to a good solve by itself.

Look, none of this is glamorous. But also, nothing short of an AI industry collapse will make vibe coding go away. But that’s also not the goal.

The goal here is to create an approvals process that results in code that is good and useful. And in many cases, vibe coded contributions are good and useful - if naive and incomplete. Accordingly, we need to understand that this AI revolution is as much part of the living, breathing codebase as the development of IDEs, state representation, and so forth.

The tooling has changed, and the review process has changed with them. That’s not a moral failing on anyone’s part - it’s just part of the new contract.

Discussion about this post

Ready for more?