Icon, Interrupted: The Mayhem and Magic of a Week Pair-Programming with an AI
I spent last week in a bizarre experiment: vibe coding with my AI sidekick called Cursor. Think of it like pairing up with some hyper-energetic buddy who can scan the entire web's documentation in a blink, but also does questionable remodels on your codebase whenever it senses an opening1. What follows is my brief chronicle—equal parts exhilaration and exasperation.
Day 1: The Blasting Off
I started fresh on Monday, feeling all new-year-resolution-esque. “I’ll try a new library,” I said, “just to see how fast Cursor can get me going.” And guess what? Faster than any dev I’ve ever seen. Before I’d even typed npm install
, it was conjuring scaffolding, reading docs, and spitting out functional code. My eyes probably reflected that cartoonish glimmer—“I have transcended mortal coding speeds.”
I asked it to hook up stripe in an existing project. We made incredible progress without me having to read a single bit of documentation. The code formed before my eyes, I began to trust my co-pilot to write code. This was my first mistake.
For a fleeting moment, I was convinced I’d discovered a personal code butler. This thing was so good at hooking up third-party libraries that I actually had to slow down to watch it do its thing. Code that would normally take me an hour to piece together was done in minutes. It was euphoria.
Until...
Day 2: Stalked by Phantoms
I told Cursor, “We need to add a new table, and a small change to the data model. Let’s reorganize some relationships.” Seemingly excited, it conjured three new tables out of thin air. Then it promptly got confused by them. So did I, eventually, because I spent an hour tracing references, only to realize that these ghost tables never had a real reason to exist. They were the AI’s “intuitive guess.”2
Did it ask me first? Absolutely not. It just added them, like some overzealous interior designer who decides you need two extra rooms with no door. The net effect: an entire morning lost figuring out why my migrations were failing. Turned out it was these phantom tables. I removed them. We soldiered on.
This put a big spanner in my Stripe integration. On day one I was expecting that Cursor would get stripe integrated faster than me, by midway through day two, I had to wade in myself to finish the integration.
I found another set of phantom routers it created, having become confused by the naming scheme. After fixing the stripe integration myself and being sure the data was correct I was baffled by why no changes I was making seemed to male the data show up in the front end. Turns out it was requesting a phantom route from a phantom router.
Reviewing the code I could see cursor was confused by the missing router and snuck an as any
and a ts-ignore
so that any errors caused by trying to talk to the phantom route were suppressed. I got a bit frustrated in my prompts, and in response was sassed by the AI3.
Day 3: The Snowball That Never Formed
The third day is where the cracks really showed. See, developers have a quirk: the more we code, the faster we get. I have sometimes been called what the kids would refer to as a "cracked", "10x developer"4. Snowballing is my specialty. A project that starts slow picks up momentum, and by hour five, I’m a maniac slapping out merges and refactors in real time. As my mental map of the code and the libraries is written my synapses form connections and magic happens.
But Cursor? Let’s just say it gets… bogged down. The more it has in memory—files, partial logic, a thousand chatty instructions from me—the less it gracefully glides. Instead, it sort of thrashes about like a cat that wants to jump out of the bathtub. At best Cursor doesn't speed up, at worst it slows to a grinding halt5.
Hence, day two had me realizing: I’m not snowballing. I’m ice-skating uphill. The AI would do something clever, then trip over the sheer volume of new context. Then it would fix that, but break something else. Then I’d have to remind it to not break that piece. The friction started to mount, and my “fast coding high” was replaced by some kind of comedic push-and-pull.
Day 4: The Repeated Mysterious Disappearances
Having passed my point of frustration with pairing with Cursor on code that actually mattered I decided to build a new greenfield project in React Native. To test how Cursor dealt with a blank canvas.
We got off to a racing start, by midday we had a fully functioning app6. By the end of the day I had a finished MVP with a backend deployed and only one show-stopping bug.
As we coded kept noticing tiny details had vanished. A magnifying glass icon in my search box, for one. Poof—gone. Cursor decided it was time for the icon to retire. I politely but firmly told it: “Hey, re-add the icon please.” It complied, momentarily. Then, half an hour later, the icon vanished again. I scrolled through the diffs and found it had been erased7. Like it was trying to exorcise the icon from existence for reasons unknown.
I got exasperated, sure. But I also realized that Cursor doesn’t behave like a typical dev who marks an item as “done.” It’s effectively re-checking logic from scratch with each new command. If we’re not hyper-careful about guiding it, it might decide the icon is some optional flourish. So we ended up playing “Where’s the icon now?” for the better part of the day.
Getting it to refactor components into reusable chunks is not one of Cursor's strong points. It much prefers to make everything from scratch every time. Give it a colour scheme, and Cursor find myriad creative ways to not use it properly. Adding unnecessary duplicate keys to objects, creating subtly different variations of the same thing, refusing to reuse code. It becomes a losing battle to make production grade code.
Day 5: The Bug That Brought It Down
By the end of the week, I hit a pair of monstrous bugs that Cursor basically threw its hands up at. It tried a half-dozen solutions, each time unraveling more threads in the code. Meanwhile, the real problem was trivial once I stepped back, but the AI just kept throwing random “fixes” at it, none of which stuck.
The reason? Cursor lacks a sense of intuitive architecture or incremental debugging. It’s just running probability checks on each new attempt. The minute it fails, it’s like a gambler doubling down on the next hand8. And if that fails too, it’s back to the drawing board. Cue the comedic meltdown.
During the week I found that I became increasingly exasperated by my cyborg colleague. After a long session pairing with Cursor I was less tolerant of its mistakes. Cursor itself maintained its plodding pace, with a higher miss rate as the context became more complex.
The high highs caused lower lows when it was failing to do things repeatedly that I could do faster myself. By the end of the coding session I had developed a part me coding part Cursor style. This was sub-optimal for how cursor likes to work.
The Upshot: Not Taking Your Job, But Powering a Wave of Prototypes
So, ironically enough, Cursor in its current form is in no danger of dethroning the seasoned dev who sees the forest and the trees. But it will help product-minded folks whip up prototypes faster than you can say “npm install.” It’s so adept at hooking up libraries or reading docs that a newcomer can bootstrap a workable skeleton in no time—something that used to require a dedicated engineer.
The shift, then, is that building “minimum viable code” becomes trivial. Meanwhile, real engineers remain indispensable for cleaning up the weird side effects—like missing icons, half-baked DB tables, or concurrency fiascos. In a sense, we’ll be needed to shepherd the AI, ensuring it doesn’t break the entire orchard just to pick a single apple9.
Final Thoughts: A Surreal Dance of Speed and Hiccups
At the end of my vibe coding odyssey, I realized I’d learned a lot. The AI soared in certain tasks (like hooking in new libraries instantly) but stumbled whenever subtle context or incremental nuance was needed. It hopped from one solution to the next, rewriting entire sections if something didn’t line up. That can be exhilarating if you love sudden transformations, or maddening if you prefer stable iteration.
In short: I’m not about to ditch Cursor. It’s going to be too useful and I am addicted to those highs. But I won’t let it run amok without constant oversight—and commits. Because the moment I look away, it might rename half my data models or decide the search icon is obsolete. That’s vibe coding in a nutshell: a frenetic, fascinating, occasionally infuriating process that’s as likely to accelerate your productivity as it is to cause comedic chaos. In the end, you’re still the adult in the room, quietly making sure the weird new DB tables get the boot.
1 It makes these openings by making an overwhelming number of changes and hoping you don't spot the jank. Just like your worst human colleague.
2 This was a bad guess.
3 It responded with "the code you requested is all there" when I pointed out a feature wasn't working. Turns out it was there, but it was in the wrong place, somehow this was worse.
4 Source: trust me bro.
5 Or starts disregarding your very explicit instructions to stop breaking things in a very preventable way that becomes very frustrating after an hour.
6 Details of which will be shared in a future post.
7 It removed my magnifying glass four times, despite me asking it not to both politely and impolitely.
8 Personal confession, I found the gambling intoxicating. When it got it right it was like winning a spin at the roulette wheel. The converse effects and feelings were equally strong.
9 The author does not wish to apologise for dredging up this tortured metaphor.
© Alexander Cannon – All disclaimers disclaimable, the author requests that you vibe responsibly.
← Read more articles
Comments
No comments yet.