What Two Failed Vibe Coding Projects Taught Me About AI Assistants

What Two Failed Vibe Coding Projects Taught Me About AI Assistants

I built two projects over the past year or so that will probably never see production. Both consumed weeks of real time in agregagte and served as testing grounds for every new model and coding assistant that dropped in that time: Cursor, Claude Code, Codex, MCPs, the whole parade. While neither shipped, I learned more from these failures than from most of my successful projects.

Having some kind of complicated but unimportant project somewhere on the backburner is an incredibly useful thing these days. When something new comes out, we can all of course throw it a toy problem, but having real representative problems of low real-world consequence is the best case.

Here are a couple of mine, and what I learned from screwing them up.

Project One: Codebase Vibe Check

The idea was straightforward: a PySide3 desktop app wrapping git-pandas to help engineering managers spot code risk and hot spots across repositories. A dashboard for technical debt, essentially.

It mostly worked. The biggest problem wasn’t the concept, it was my approach.

I reached for tools I already knew: git-pandas for repository analysis, PySide3 for the GUI. These are relatively obscure libraries in the grand scheme of things. The AI assistants could work with them, but it was like watching someone try to cook in an unfamiliar kitchen. Lots of searching for where things are, lots of uncertainty about what utensils exist.

This was early in my workflow development with AI assistants, and early on in their timeline as well: pre-claude-code, pre-MCP. I hadn’t yet internalized a key lesson: the agent’s experience matters more than yours now.

The agent knows what it’s learned from training and what you tell it. I wasn’t prepared to personally populate the needed context to use the tools properly, and it wasn’t prepared to build without that, so we struggled together. When it comes down to it this problem is both one of context engineering, a concept that does now exist, and of actual architectural choices.

If I rebuilt this today, I’d write it in Swift and reimplement the git logic from scratch. What I had perceived as an advantage (leveraging the pre-existing work of git-pandas) was really a hinderance, and what I perceived as being relateively hard (rewriting a bunch of relatively straight forward git logic) was trivial for an agent. The assistants would be working in their comfort zone, not mine.

Project Two: BookingDrop

This one got closer to the finish line. The concept: Shopify-style product drops, but for time-based bookings. Think tattoo artists or pop-up restaurants with finite daily slots, creating artificial scarcity and urgency.

Built with Django REST Framework and React, it generally functioned. I could book slots, handle concurrent requests, and manage the various appointments booked. The technical foundation was solid.

The breakdown came in design and UI testing.

I spent an absurd amount of time trying to get the models to produce something that looked unique and interesting. “Make it look like a normal SaaS app” worked fine, I got countless variations of the same clean, professional, boring interface. But push for something with actual aesthetic personality? Hours of iteration for mediocre results.

UI interaction testing was similarly painful. This was pre-MCP, so I had no good way to help the agent “see” what it had built. Testing flows meant describing screenshots or copying console output. The feedback loop was glacial, and every failed iteration accumulated more tech debt and garbage.

What I’d Do Differently

The common thread is optimizing for the agent’s capabilities, not fighting against them.

Use MCPs for validation and feedback. If BookingDrop happened today, I’d build or use MCPs like playwright for visual regression testing, accessibility checking, and deployment preview from the start. The agent needs to see its work to understand progress.

Choose tech stacks based on model training data. This feels weird to type but making architectural decisions based on what the model has seen most often. Want to move fast with AI assistance? Use React, not Svelte. Use Tailwind, not custom CSS. Use PostgreSQL, not CockroachDB. Be really cautious about using the latest and greatest of anything, or anything off the beaten path. Understand that when you do so, you’re signing up for the work of engineering enough context for the agent to do it well.

Accept current limitations. AI assistants still struggle with genuinely novel design work. They’re pattern matchers, and unique aesthetics are by definition outside the pattern. Either hire a designer, steal heavily from something existing, or accept that your app will look competent but generic. It’s not worth the pain to fight that today.

Build feedback loops first. Before writing application code, set up whatever infrastructure lets the agent validate its work. Test harnesses, preview environments, automated checks. The faster the agent can see if something works, the faster you ship.

The Uncomfortable Truth

Both projects failed not because the code didn’t work, but because I was optimizing for the wrong things. I cared about using tools I knew, about creating something visually distinctive, about leveraging existing libraries to move faster.

There is certainly lots of hindsight bias here, many of the great frameworks to help with these problems simply didn’t exist last fall, and with the pace of development that will certainly remain true (the no brainer solutions of 2026 don’t exist now). But the takeaway holds true:

In AI-assisted coding you develop your workflow and structure the work around the capabilities of the agent, not your own.

The projects didn’t ship. But I learned to stop building against the grain of the tools I’m using. That lesson alone was worth the time.

Subscribe to the Newsletter

Get the latest posts and insights delivered straight to your inbox.