Vibe-coding is all the rage, and I've been taking a crack at it lately using Bolt, one of the more popular platforms. I wanted to offer my reflections on the experience, including shortcomings, limitations, as well as things that excite me for the future. It's equal parts reflection and time-capsule of what it's like to work in this moment in time.
I've been building a golf scorecard app, because I found the ones out there to be overly-complicated, and ugly.
For the last year-and-change, I've been obsessed with golf. The game has grown quite a bit during that time, and I definitely feel as though I've 'hopped on the bandwagon' as a new golfer. Because I'm also a designer, I like surrounding myself with beautifully crafted software and noticed there isn't a beautiful, minimal scorekeeping app out there. I wanted to try to build one.
What I've observed
In your vibe-coding assistant, you have the ultimate 'do-er'. Usually when working or collaborating with humans, there's some balance between execution mindset, and strategy mindset. If I ask someone to do something, but it doesn't make sense, they usually ask why. If I'm skipping steps, they ask why. If there are other things that might make sense to design as well, we talk about it. Bolt just does. 90% of the time it does exactly what I ask. Sometimes It does more than I ask, but I'd say when that happens it's wrong about 50% of the time. This leads to a lot of stopping mid-ask, or rollbacks.
When it comes to doing, Bolt cannot usefully anticipate very much. This is especially a problem when designing things for human beings to use. Up until now, intelligence you could interact with was embodied. It lived in and experienced the world. LLM-based technology is disembodied. It only knows about the world second hand. For example: when building out the scorekeeping function of the app, I noticed that it 'reset' whenever my phone locked. This is a problem, because your phone locks after every single shot when you're keeping score during a golf round! There is just no way for an AI, especially one tuned for coding, to know this. AI has never walked. It's definitely never golfed. The only way to know this is a problem is to exist in the real world.
Examples like the one above give me confidence about the future of design, and the future of the design profession. The world isn't going anywhere anytime soon, and as long as we live in it, there will be a need to translate that experience into 1s and 0s.
Building the thing
'Keep my score for a round of golf' seemed simple enough. As it turns out, reality is surprisingly complex and full of detail. So far, I've implemented a laundry list of features, including:
Elegantly inputting scores for a hole
Saving scores for a hole
Adding up scores for 9 and 18 holes rounds (my local course only has 9 holes)
Show/hide score mid-round
Save round scores
Show saved round scores
Delete saved rounds (something I only needed to do because of the sheer amount of rounds I was adding during testing)
Configure a round before you play by selecting number of holes, naming the round
Searching for a golf-course for a particular round
Seeing par and hole length on each hole based on your course selection
Authentication so that scores can be saved and tied to account
Persisting the app even when the app screen locks, so when I unlock it I can continue scorekeeping. Useful when you're walking between shots.
This was enough to get MVP-level functionality up and running, but there is a long, growing list of additional functionality I want to build out.
As I built out this MVP, I realized I was being forced to design and consider every detail as I was creating the application. The downside of creating in high fidelity is it almost completely shortcuts the lower fidelity iterations you might create as part of a more traditional creative process. Immediately, I have to think about things like authentication, persisting data between locks/unlocks, API integrations, etc. - Code is becoming design and design is happening in code.
For years, the traditional UX design delivery toolkit has involved designing screens, systems, the connections between them. Rarely, if ever, have UX designers needed to think about questions like 'should I actually delete a saved round from the database when someone says 'delete'? Or should I flag it as deleted and not show it so that I can recover it later?' - exploring questions like this has been a fundamental part of my vibe-coding experience, for better and for worse.
There's also another big difference here: I'm designing 'in the tool' instead of declaring my design intent ahead of time and then using the tool to realize it. I think there are a few reasons for this:
This is a side project and I have a rough idea of where I want to go and am experimenting
There are a lot of unknown unknowns I'm expecting the AI to help me with. I don't know how to set up a database, or integrate with Oauth, or deploy a webapp. So I'm crossing bridges when I get to them. The disadvantage here is that I run into problems I could have elegantly solved if I had known about them and thought about them in advance (discovery!)
And when I run into a problem I didn’t anticipate, I then have to debug the problem.
Approaches to Debugging
First line of defense: Ask the app to fix itself - this worked reasonably well in many cases. However: It always thinks it fixed the problem even if it didn't, which means you always have to manually check if it fixed the problem. This is annoying for flows that require things like authentication, or working through an entire flow - the testing burden is tremendous.
And...Sometimes you have to ask it to fix the problem more than once
But...The more you have to consecutively ask it to fix the same problem, the less likely it is to know how to actually fix that problem, but the MORE likely it is to break something by trying
If that doesn't work, I have it Console.log what is going on as it does it, and then I (as a human in the loop) read those logs and suggest fixes. This seems to work well for data-based problems
If that doesn't work, or if the bug is visual I paste screenshots back into the tool, describe the issue I'm having, and ask the AI to fix it. This one had mixed results, but most of the time I'd say the more specific my ask, the less likely I was to make progress. So saying 'move this up' worked. Saying 'move this 40px up' did not work as well
Something I'd like to try, but haven't tried yet, is just asking it to show me the line in the code I'd need to edit to fix a problem, and doing it myself.
And finally:
Debugging usually gives me a better understanding of how my app works. As I build something, I gain an intuition for what might be breaking things because I know the entire codebase. However, it's not clear to me if the AI is actually gaining a better understanding of how my app works over time. As we go, I'd expect some bugs to be more solvable, but in fact it's been the opposite. Not to mention the fact that I might be fixing something on one page, only to return to a different page and discover components are missing and have been re-arranged!
On Fragility
It really does feel like vibe coding is stacking a house of cards. The more complex the thing is you've built, the less maintainable it is. You're going to have dependency management and maintenance issues. You need to upgrade NPM packages. You need to do all of these things as part of just… making a digital thing. Vibe coding, as far as I can tell, isn't doing these things automatically for you. As I get further into the build, it feels like I'm going to break something, even with the ability to roll-back changes, that will make the entire app just collapse on itself.
So, where do we go from here?
1 // I wonder what it'd be like to 'plan' with the AI, instead of just building right away
Some of this is on me, for sure, but I also know that most of the folks using Bolt, Bubble, and tools like it do not have the experience to plan and execute a thoughtful discovery process. What if we created an experience around this? It could be as simple as answering a set of 20 questions about features and functionality with the AI so that it has intent ahead of time.
2 // There is a huge opportunity to create an ai-first BaaS platform.
Once I've built the app, what if I want to launch it? I still need to buy a domain name, build a website, maybe buy some ads and place them on the right platforms in a targeted way, deploy analytics to understand usage, and stand up a customer service capability for triaging bugs. All of this could be automated as part of a suite of tools.
3 // Design is going to be pushed 'up' as well as 'down'
The 'middle' we've occupied for so long (translating a strategy into a set of screens to be built out) is quickly going to be filled by tools like Bolt and Bubble, at least in many contexts. However, the need for strategic thinking and foresight, as well as sweating the details during execution, will be higher than ever before.
