skip to content

Vibe Coding Finally Clicked — Once I Stopped Expecting the Wrong Things

I tried vibe coding multiple times and kept walking away disappointed. The problem wasn't the tools — it was that I was applying a production standard to projects that didn't need one.

7 min read
cover image

Image generated with ChatGPT

I’ve tried vibe coding multiple times with different tools like Cursor, Claude Code, and Jules. Each time, I went in expecting to come out the other side with something I was genuinely proud of. And each time, I walked away disappointed. The code mostly worked, but something always felt off. The database schema would be functional, yet clearly unable to support the features I could already see myself wanting later. The implementation would feel disorganised in ways that made me uneasy. I’d end up spending so much time correcting and restructuring things that vibe coding started to feel less like acceleration and more like generating slop that I had to continuously patch before letting the AI keep going.

Vibe coding kept failing me until I realised it wasn’t the tooling, I was applying a production standard to projects that didn’t need one.

My Engineering Brain Kept Getting in the Way

As an engineer, we’re wired in a certain way to think about code and systems. When I write something that’s going to production, there’s a mental checklist that runs automatically. I needed to understand why a decision was made, not just that it produces the right output. I needed the confidence that errors are handled in a way that won’t break production at 2am. I needed the assurance that the data model isn’t something I’m going to regret in eight months when requirements shift and someone needs to build on top of it.

That standard exists for good reason. It’s what separates software that lasts from software that quietly accrues tech debt until something breaks badly enough to notice.

The problem is I was applying that same standard to projects that didn’t need it. Every time the AI produced a database schema, I’d look at it and start thinking three features ahead. I’d find something that didn’t sit right, redesign it myself, get the AI to rewrite the application around my revised model — spending hours driving it toward something I’d actually trust. It was exhausting, and I walked away from each attempt wondering if vibe coding was just overhyped.

Turns out, I just hadn’t found the right use case yet.

The Project That Finally Made It Click

Recently, my fiancé brought up something that had been quietly bothering both of us. We had investments scattered across multiple platforms — no single place to see how everything was actually performing, no birds-eye view of the portfolio. He wanted a dashboard. Something simple, local, just for the two of us.

The catch: he’s non-technical. Whatever I built couldn’t require him to run commands or install dependencies. No npm, no Docker, no terminal. Just something he could open like a file and use.

I decided to try vibe coding again, this time using Claude’s web artifact builder — a skill that takes your requirements and outputs a single self-contained HTML file built with React, Vite, and Tailwind. The output is ready to open in a browser with no setup required, which was exactly what I needed.

No PRD. No RFC. No architecture review in my head before I’d even started. Just vibes — a prompt describing what I wanted and a willingness to see what came back. I didn’t need to bother about the code since Claude abstracted that out from me.

Investment dashboard screenshot
Disclaimer: Figures are not real, for illustration purposes only.
Investment dashboard screenshot
Disclaimer: Figures are not real, for illustration purposes only.

The first output genuinely had me in awe. The UI was polished in a way I wasn’t expecting. The layout made sense, the interactions felt right, and it actually did what I asked. I kept going, adding more integrations, more features, refining things as I went — and the best part was that I could do all of this from my phone whenever I had a spare moment like waiting for my Chagee order to be ready, or while commuting.

For a while, it felt almost magical.

Where the Ceiling Shows Up

Of course, it didn’t stay that way. The further I pushed, the more the cracks appeared.

As I prompted more features, the AI started making mistakes it hadn’t made before. It would fix one thing and quietly break something else. I suppose this is the result when you attempt to build something without any guardrails — no unit tests, no E2E coverage. There was no feedback loop, nothing to catch these regressions automatically. In a real engineering context, writing tests are non-negotiable.

The back-and-forth also started eating into my Pro plan session quota faster than I expected. When you’re giving the AI clear, directed instructions, it’s relatively efficient. But if you’re in a loop of “it’s still not working, try again” — which is what happens when neither of you can pinpoint the root cause — you burn through a lot of context for not much progress. An engineer who could look at the problem and say “here, this is the issue” would have been more token-efficient than the fog of iteration.

There were smaller annoyances too. At one point I asked it to build a loader and a success toast for the stock price API calls. It did — and then later, while adding something else, it quietly repositioned the loader and dropped the toast entirely. No instruction to do so. Just collateral drift.

I kept going anyway. The stakes were low enough that these frustrations were acceptable. But they clarified something important.

The Distinction I’d Been Missing

Here’s the thing I’d been getting wrong every time before: I was treating vibe coding like a shortcut to production-grade software, and then feeling let down when it didn’t clear that bar. But that’s not what it is.

I think of it now like cooking with an air fryer. An air fryer is genuinely useful — it lets anyone cook a decent meal without much skill or effort (yes I feel like I can cook anything with an air fryer). But if you need to feed 200 people every single day, without failures and without delays, while ensuring consistent quality, the air fryer isn’t the bottleneck. The process is. The systems are. The appliance was never designed for that scale, and blaming it for falling short would be missing the point entirely.

Vibe coding is the air fryer. For a personal investment dashboard that two people use locally, with no uptime requirements and a low cost of failure — it’s exactly the right tool. I finished something real. My fiancé can open it and use it without asking me anything. That’s a complete success even without it being production-grade quality.

What I understand now, having finally had a vibe coding experience that actually felt good, is just how easy it is to be swept up in it. The sudden ability to produce something that looks and works like a real application — without needing to know how to code — is genuinely compelling. I get why people get excited. I also get how easy it is to underestimate what engineering actually involves when you’ve never had to do it.

We’re Still the Gatekeepers

What I wish I knew earlier is that the mistake cuts both ways — over-engineering a project because your engineering brain assumes it needs to survive production for the next 5 years, or shipping something to real users because the output looked production-ready enough.

That excitement is real — but so are the responsibilities that come after it.

Our accountability as engineers doesn’t shrink just because AI wrote the code. Anything going to production, under our ownership, still has to meet the standard we’ve set — that hasn’t changed and shouldn’t.

For low-stakes tools, prototypes, internal dashboards, or personal projects, vibe coding can be exactly the right trade-off. But when software needs to survive changing requirements, scale, operational pressure, and real-world failures, generating code faster doesn’t remove the engineering work underneath it.

Vibe coding abstracts away the craft — and the craft is the part that matters when software needs to survive the real world.