leveiga.eu

Vibes 2 - From prototype to product

After 2 weeks it's incredible how positive the whole vibe experience has been.

I went from quickly iterating on what I wanted the overal app to be, to picking the framework that feels right, and now starting to dive deeper into Web Audio API and a few nuances of audio synthesis. Great!

Svelte is great

After the first HTML + embedded JavaScript one-shot app it was clear it wouldn't scale. Moreover, while vibing has been fun and addictive, it's still quicker and more satisfying to do some experiments by hand. Artisanal coding some might say.

A few examples in the following subsections.

The viber is stuck, this can't be that complex!

While describing things like "add a vertical separator every 8 bars" seems pretty easy, the truth is that in the middle of spaghetting HTML, CSS, and JavaScript, all the interactions are non obvious. By manually trying to exagerate changes I can (a) get a better grasp of element coupling and then either (b) provide a much better prompt or (c) apply the changes manually.

Colors and gradients

Unsurprisingly changing the entire color options with a full web app going on, leads to a few surprises. So bad that I stuck with Solarized, which was definitely a questionable idea from the start.

Solarized Dark/Light because... I am not sure.

The most satisfying approach I have found is to request simple HTML pages with variants and iterate on those. Not only it allows to agent to focus on the task itself without getting lost in the larger code base, but it also allows me to think deeper about it without distractions. In this particular project it allowed me to ditch completely the idea of maintaining a light and dark mode theme. No reason to do it.

Asking for WCAG compliant palettes. This is the way.

Furthermore, by having these simpler pages and set ups, one can easily play around with CSS and HTML by hand which is much more gratifying than writing a prompt, waiting for the answer and repeating many times. Then after settling on a new idea, it's easy to request the agent to read the file and create more variants based on it. chef's kiss.

Playing with textured gradients in a simple HTML page.

How I ended up sticking with Svelte

That's when searching for the right framework came into place. My previous experience with web was back in 2013-2015 when AngularJS was kicking jQuery out of the park. I definitely did not get into the React bandwagon and all small projects since then have been HTML5, plain JavaScript and CSS. Played once with TypeScript and that was it.

I did know that there must've been something simpler out there. Perfect for this use case. Lo and behold, Svelte was the suggestion. Their website is great. It reminded me of the first time I discoreved Django and its documentation. Looked around, and found two very good aspects that made me decide:

  1. It's very focused on components. For this project, that's all I wanted. No need for complex builds. No need for crazy interactions. I just wanted everything super tidy in components that I can then iterate over.
  2. The docs have specific design choices optimized for LLMs. That was news for me! One thing I definitely am taking to work. Plus their skills and tools are flawless.

After 2 calendar days of allowing vibe to refactor everything with Svelte, it was time to decide if I should migrate to new features and keep breaking the spaghetti. Maybe in the end all I wanted was lasagna — apologies, double dad jokes are allowed.

It was a good decision. Right now the project has grown to be fully TypeScripted and Svelted. With 13 components, 8231 lines of code, and still a few things to tweak, it has been way more satisfying than I anticipated.

Satisfying is the key word in all of this. It feels good to iterate on big chunks of code. It feels good to read and learn while playing with the result.

Testing in production

While iterating on the project I have been on the fence with unit tests. I have always felt that unless there is critical complex logic in a big app with convoluted UX and multiple user journeys, unit tests are pure overhead. It's much easier to launch and click to feel how it's working.

Thanks to being a standalone web app, it's dead easy to commit, push, publish as a static website on GitLab Pages and work it out.

Focusing on how it feels like to use, and less on how to code it has been one if not the most satisfying aspect of this project so far.

The slop is real

What could be going on? Where are the "one-stop-shops" for audio web apps? They must exist for sure. That's when I found Tone.js. In one word: underhwelming. Not the package itself. But its usage these days. If you go and look at their library of example projects you get a great list of dead links, domains for sale, at if you're lucky 100% vibe coded apps linked on reddit and then abandoned. Why? Is there a term for this? Vibe and forget maybe?

What is most frustrating to me is that whoever is creating these apps, does not seem to care for them. It reminded me of the great video essay by Adam Neely. Yes that one. The signs are there when the post has that LinkedIn vibe, and the replies feel like YouTube comments. Sad.

Web Audio shenanigans

One thing I want to highlight is that in the past week I have been struggling to understand why the app would not work on iOS or iPadOS. Asking in simple prompts would innevitably return the answer that on Apple devices there needs to be an explicit trigger such as a press of a button to allow sound. It would then do some changes that resulted in nothing.

Why is this a good example of vibe coding? Because while vibe was doing its thing to add filters, EQ, improve sliders and so on, I was left with time and headspace to take a step back and think about it. And thus in a few minutes the answer was there in a random reddit post: "is your device in silent mode?".

# build a simple webpage to test raw Web Audio API. use node. serve locally

Opened by phone, removed silent mode. Et voilà. Or so I thought.

While solving the issue, something I did not expect happened: Tone.js provides a simple dependency called unmute. It didn't feel right, though. Upon searching for the project, and as you can see on its GitHub page, the signs were there: it was archived in 2020.

unmute npm statistics. an 8 year old lib getting more traction with the advent of vibe coding.

The solution was easy: have vibe write the "play a silent mp3" hack itself:

// iOS Unmute: On iOS, Web Audio API is routed to ringer channel (affected by mute switch)
// while <audio> elements use media channel (not affected). Playing a silent <audio>
// element on user gesture routes Web Audio to media channel, bypassing hardware mute.
// We implement this inline rather than using 'unmute' or 'unmute-ios-audio' packages
// because both are archived/unmaintained (2020), and the solution is trivial.

The message was also clear: be on the lookout for old/deprecated packages. Avoid falling into the same trap of those 119 weekly downloads since the boom of vibe coding.

← Back to Posts