Vibe Coding as a Software Engineer (Spotify Exporter App)
I decided to vibe code an app as a senior software engineer. Here's how it went.
I keep seeing people rave about vibe coding and how it can churn out CRUD apps like nobody's business. I do use LLMs to boost my productivity, but know I need to get with the times, so, I decided to give the hip new things a shot myself by fully vibe coding a fullstack app.
I wrote a script a while back to get my spotify playlists and songs and export them to a csv for a research project that hasn't quite come to fruition yet. I decided that was a good candidate for expansion into a full app so others can use it, and add a few extra features like:
- Ability to select/deselect everything at once, individual playlists all at once, or individual songs
- .csv, .txt, and .json export options
- Error feedback for when tracks can't be processed (I found this was a problem with How to Be An Antiracist specifically. Or maybe audiobooks generally? That was the only audiobook playlist I had saved for some reason)
- A google survey to see why people are using the app
- A tip jar because why not
My rules for myself were that I was allowed to use agentic coding and browser LLM chat only. I designed the app and the features I wanted, but the code was intended to be almost entirely hands off. I allowed myself ChatGPT as well as Claude to save my premium tokens. Suggestions that ChatGPT gave me, I mostly had Claude implement rather than doing it myself. I did make a decision where multiple options were offered, and didn't pick a random one or the first one or anything. Full disclosure, I did decide on Vite for the frontend before starting.
I did mostly run the deploy commands myself, although I guess I could have had Claude do it. And I set up the Vercel and Fly.io projects, although I did let ChatGPT suggest the infrastructure. It also suggested Vercel edge functions but felt that Fly.io would be cheaper. I hadn't actually heard of Fly, so that was a bonus.
If you're into that kind of thing, you can see the full git history for the frontend and the backend, and how it went.
The good: I did get a semi-servicable app pretty quickly. I see why people get excited. It took just a few minutes to get some kind of frontend and some kind of backend talking to each other. I also hadn't heard of Fly.io; that was an unexpected bonus. Overall, I do think it would have taken me much longer to get this app fully built and deployed on my own.
The bad: There were absolutely no security suggestions. Which on the one hand is fine and expected. The LLM also didn't suggest any good frontend features. They're not designers or architects. But on the other hand... how you want to handle song selection checkboxes is subjective, but not suggesting even basic rate limiting is like not suggesting locks on external doors.
There were also a few redundant pieces of code that caused errors, and for some reason Claude made a deploy.sh script early on that caused some problems.
A had to keep an eye on commits because the LLMs sometimes go pretty rogue with rewriting things. In the future I will add instructions to commit to a specific branch whenever a large feature is completed, and then I will review it before merging. That's not that bad, though, it's the same as any team work.
The ugly: I was curious to see how the LLM handled anything beyond basic CRUD operations and simple API endpoints, and ended up really deep in an oauth snarl. I burnt way too much time following Claude into .json-file-based sessions, which admittedly did kind of work as long as a user was already logged into Spotify elsewhere in the browser but choked on the first login attempt when in production only. To solve that, Claude went into popup-based flows which was a whole other thing. I did put some rails on when Claude and ChatGPT both tried to get me to relax some security features to bypass Content Security Policy around inline scripts. Eventually I ended up with a flow that opened a popup and redirected to a static html page, first on the backend, then on the frontend, which wasn't terrible but wouldn't authenticate when the user needed to log in. Then Claude suggested polling. Then localStorage checks with retries. Then ChatGPT realized I had redundant libraries, but that still didn't fix the issue. ChatGPT also suggested converting to Vercel functions to avoid CORS issues, which I really didn't want to do at that point, and I don't think would have solved the issue anyway. I am honestly not even 100% sure what caused it myself.
Eventually I just directed Claude to rip everything out and do a modern JWT exchange instead. That worked fine.
Ultimately it took 47 fly.io deployments and 22 Vercel deployments to get to a spot where I was satisfied. I'm sure that I could have cut this down quite a bit, but the authentication error was only happening in production and in the specific scenario of needing a full login, so I ended up debugging in deployment more than I would like.
I don't know if I will ever become a full vibe coder, but it was a cool experiment, and faster than doing the whole thing on my own. The future is an interesting place!