Real challege of vibe code as a developer

How it started

I used to have my own handy Bursa Whale tool for me to have a high-level glance of all the insider and institution purchases and selling in the Bursa market.

I have a script that will read the announcement from the Bursa website and then using the data that I have stored to visualize it on Looker Studio. Unfortunately, I don’t have the original screenshot, where is what it have become.

Is not that I don’t want to attempt to fix the connection. I have been trying to fix it for a couple of days to no avail. After many google search, it quite likely is the Looker studio MySQL connection library version mismatch with my webhosting MySQL version. So yeah, it is beyond my control to update the database version.

And, that lead me to look at the possibility of building my own dashboard. It is also an opportunity for me to give a full scale vibe coding to see how matured it has been. Let’s go!

Finish product

I managed to get all the core widget in place and making it to display like what I used to see on Looker studio. Except that is much better. I have full control of the looks and behaviors. Proud to say that, all of this took me roughly 10+ hours working with Cursor.

My journey

It wasn’t all that straight forward. I initially started with my go to AI tool (Cline) for the job. However, I find that I always got rate limited and aren’t able to proceed to vibe code smoothly. Also, it always tend to build without much direction, making it from an architecture point-of-view a nightmare.

Wearing the hat of Product Owner is also not easy at this point. Because, there is too many things to fix and you can’t tell the AI to fix everything in a single prompt or chat conversation.

Strategy to overcome

I knew that I am going nowhere with the straight-forward approach. Therefore, after watching a few Youtube tutorial, the first thing I need is a well structured PRD (Product Requirement Documentation).

Start by having a clear picture of the end goal, which I already have – to replace my existing Looker Studio. Carefully draft out the PRD. Use AI to guide you, the traditional ChatGPT works at this stage.

Next, just like how a Product Owner create a whole bunch of Jira backlogs when we start out a new project. In this world, you’ll create an instruction.md to describe the step by step approach of building the application. This is crucial, as you’ll be able to iterate one step at a time and testing it to make sure is correct before proceeding.

I think having the instruction file serve as a developer changelog, which I think is worth while to commit it as part of your code. I also make sure to have a numbering system in the instruction, as this help us to chat with the AI agent to build step by step. (eg. Let’s skip straight to step 3.1, build…). You can also reference back to any section of the PRD to make sure that the AI agent build according to your requirement.

Real challenge

Is true that, just the above can get us quite far, I mean just fully trying to vibe code. However, I am a professional developer afterall, and I can’t stand the whole much of messy and spegatti like code. The part where we keep on asking the agent to fix this or that. Most of the time, they can make the fix and it looks good. On the code level, is a whole messed creating state variables, single purpose function, etc, all in a single ui file.

Agent can’t fix the bug it created

In fact, the agent also start to get lose of the messy code they have created. As example, these 2 chart should match in terms of volume as you can see from the screenshot. I tried to fix the bug through vibe code, it failed. And, I decide to proceed by leaving this as tech-debt, and get back to it once the code has been clean up for me to debug.

It is a miracle after refactoring, the bug just disappeared. This also, prove that we need a senior engineer approach of guiding the agent when we build the application.

Ugly refactoring

Taking the lesson from the instruction numbering, here is the prompt I used to refactor the code.

## 4.1.1 Frontend data and state management
- Use React provider to load the raw record data.
- This helps to standardize the data filtering and retrival for all widget.
- Each of the widget will use the data loaded here to format the data according to display for their widget.

Guess what, it does the job well on the high-level this time. Splitting the major components into smaller files. But… the change is not complete as you can see.

You’ll need a good review to clean this up.

Once again, I have prove my point here, wearing a developer hat to vibe code helps to speed up my implementation. At the same time, you’ll need a good developer eye to suggest things that the agent could miss out to maintain a good software architecture. (Eg. Use React provider to load the raw record data.). And, I leave the rest of implementation for the agent to do it’s job – and it did it flawlessly with some minor follow up guidance.

Take away

As a developer, is not easy to forgo your developer root and just wear the PM hat to vibe code. The approach of the PM works (instructure file). But, that doesn’t guarantee the desired outcome. I often miss out on using the proper word/terms, and that get the agent to confuse with what I want. (Eg. using the word encapsulate, rather than refactor). Nevertheless, I still manage to get the outcome I need.

In a nutshell, I don’t think is easy to just vibe code as a perfectionist. I can’t really feel comfortable to use the software, because the code is a mess, and it will be difficult to maintain the software in the long run. If the functionally continue to grows, it will get harder and harder for the prompter and the AI agent to extend on the software.