Vibe coding

Vibe coding has become the expression du jour for letting large language models (LLMs) write code for you. It lives on a spectrum between the agentic, fully integrated IDE that runs commands, reads files and writes new ones at the merest suggestion you want it to do something and glorified autocomplete.

Please, I had a long day, stop calling it that

I know, as a self-identified grump and hater, the term ‘vibe coding’ makes me die a little inside every time I read it or hear it used unironically. But saying it is fun. It’s one of those terms that the youths, the rappers (same thing) or the nerds would allegedly use as slang, but really, it’s mostly your streamer’s favourite streamer and other millennials using it compulsively (‘ironically’). Like the ancient ‘YOLO’, ‘pwned’, ‘gank’, ‘1337’ and ‘swag’, or the more recent ‘rizz’, ‘sigma’ and ‘sus’. Of course ‘vibe coding’ is in the center of the Youtube, business and gen Z slang bubbles, which makes it a perfectly disgusting thing to say while eagerly checking the people around you for nervous eye twitching.

To avoid it, let’s call the practice of letting an LLM agent program for you, preferably in a language you don’t know anything about, Claude sitting, or more generically bot sitting.

How I learned to stop worrying and love the bot

As I wrote previously, I don’t think letting LLMs write code for you is as problematic, ethically speaking, as other forms of generative AI. Is it actually good, though? I have used various models in various forms and various languages for the last years and I have changed my mind about it a bit. In the beginning, I was very negative, whenever someone tried to convince me that absolute novices could produce useful code using chatGPT. I work in an academic setting and part of my job is to program in R at an intermediate level. As Tim Scott puts it in aRrgh: a newcomer’s (angry) guide to R:

R is a shockingly dreadful language for an exceptionally useful data analysis environment. The more you learn about the R language, the worse it will feel. The development environment suffers from literally decades of accretion of stupid hacks from a community containing, to a first-order approximation, zero software engineers.

Tim has since repented and added a disclaimer to his guide, but he is not too wrong about R and its developers. So I thought my early bad experiences with letting chatGPT cook up R code was a combination of those models being fundamentally unable to reliably code and R being too obscure and the data the models were trained on being full of bad code. For me, this changed around the time OpenAI released chatGPT 4. Not because it produced better R code, but because it became bad at doing the one thing I had used 3.5 for routinely: writing function documentation. So I changed to Anthropic’s Claude and was blown away. Claude just wrote documentation without being as chatty or wrong as chatGPT was. Eventually, I started trusting Claude enough to ask him for actual code, first in R, then Python and eventually everything else. So Claude is just better? No, he was just my first love.

If Copilot is moving fish, who’s flying the plane?

With this website project I have fully become a bot sitter. A relative novice at HTML and CSS, just prompting away and watching the code write itself. At the best times it’s like magic. From a simple instruction with typos and non-technical language, the agent looks around himself and spins up a whole host of pages that all look like real websites link to each other and he turns to you and smugly asks “anything else, boss?”

Most of the time, it is not like that. Most of the time, something just doesn’t work and you keep prompting variations of the same sentence in increasing desperation, expecting a different result this time. Every time the bot finds a new possible reason for what could be wrong and, getting supposedly agitated, it adds more and more code that looks like it should not be there. Even worse, sometimes it suddenly works and since you don’t have a clue what any of it means, you are afraid to touch any of the mess that the two of you created in a teenage-house-party binge of prompts and hundreds of lines of unread answers and sweat and tears and server usage. Your parents never come home to look at you full of disappointment, but there’s an uneasy feeling that you shouldn’t have done that.

Unlike the name of a popular AI autocomplete implementation suggests, the bot you’re bot sitting is not a copilot. They’re the pilot and will fly the plane with unwaning enthusiasm. You are not expected to know how to fly, you’re expected to babysit the pilot, because they’re not actually that good at it either. If you want to not crash, you either have to stay in the air indefinitely, get lucky, or learn enough about aviation from the manual to guide them through the steps and, maybe, eventually, you will have accidentally learned a thing or two about planes.

Here’s an example where I asked a Gemini-driven agent in cursor to move a fish on the landing page microblog feed a bit further below the box, this ‘reasoning’ process took 56 seconds, feel free to not read it, I certainly didn’t:

Shifting Fish Position

I'm currently focused on adjusting the ASCII fish's position. The challenge lies in preventing its collision with the microblog bubble's tail, which uses a ::before pseudo-element. I'm exploring modifications to the .sidebar .microblog-bubble margin, specifically the bottom value, to create the necessary separation.

Fine-tuning Fish Placement

I've revised the margin on .sidebar .microblog-bubble, increasing the bottom value. This shift offers more space for the fish. I'm also considering negative margins on the fish element to refine its vertical position. The goal is to ensure a natural appearance, free from clipping.

Reassessing Fish Spacing

I'm now focusing on the precise vertical positioning of the ASCII fish relative to the microblog bubble. I've analyzed the existing margins and positioning values, realizing the current bottom offset is too aggressive. My revised approach involves adjusting the bubble's bottom margin to provide adequate clearance for the speech tail. I'll test new values to ensure a gap.

Finalizing Fish Adjustment

I'm now zeroing in on the precise offset needed to place the ASCII fish beneath the microblog bubble, ensuring no overlap with the tail. I've calculated the required vertical displacement, considering the bubble's bottom margin and the tail's position. My next step is testing this refined value. I believe I've pinpointed the correct parameters for the final adjustment.

Calculating Tail Separation

I'm now calculating the precise vertical offset to ensure the ASCII fish avoids overlapping the microblog bubble's tail, which extends downward 20px. Given the 35px bottom margin of the bubble and the tail's positioning, I'm focusing on positioning the fish below the tip of the tail, using the container's height as a basis. I'll test new values and continue the refinements.

Finalizing Vertical Separation

I'm now calculating the precise vertical offset for the fish to avoid overlapping the bubble's tail. I've considered the tail's 20px extension and the bubble's 35px bottom margin. The current bottom: -28px is too close. I plan to test a larger negative bottom value to guarantee adequate separation, ensuring the fish's top edge clears the tail.

Refining Vertical Placement

I'm now focused on calculating the proper vertical offset for the fish to prevent tail overlap. Considering the tail's 20px extension and bubble's 35px margin, I'm adjusting the bottom value to ensure fish visibility. This entails testing and fine-tuning the bottom property to achieve perfect visual separation.

Analyzing Fish Positioning

I'm now calculating the precise vertical offset needed to ensure the ASCII fish avoids overlapping the microblog bubble's tail in the sidebar. I'm focusing on finding a value for the bottom property that places the fish sufficiently below the tail, considering the bubble's bottom margin of 35px. I'll test and refine the bottom value to achieve the desired visual separation.

Fine-Tuning Fish Position

I'm now focusing on the precise vertical alignment of the ASCII fish to ensure it avoids the bubble's tail. After analyzing the layout, I've concluded that a bottom: -39px value should provide the necessary separation. This places the fish's bottom edge further down, clearing the tail.

Calculating Desired Spacing

I'm now calculating the precise vertical offset to guarantee the ASCII fish remains clear of the speech tail. Given the tail's 20px extension and the bubble's bottom margin, I plan to set the fish bottom property to -39px, ensuring the fish is safely positioned below. This should resolve the overlap.

Positioning the Animated Fish

I'm now calculating the precise vertical offset needed for the ASCII fish to avoid the microblog bubble's tail. I've considered the bubble's 35px bottom margin and the tail's 20px extension. The current bottom: -4px position places the fish too high. I'll test new values and refine further.

Finalizing the Calculation

I'm now calculating the precise vertical offset to ensure the ASCII fish remains clear of the speech tail. I've determined that bottom: -4px should provide the necessary separation. This should place the fish's bottom edge safely below the tail. I'll test it out!

Finalizing Position Adjustments

I'm now implementing the calculated bottom value of -4px for the ASCII fish and analyzing the results in my local test environment. I'll evaluate the appearance and make any needed adjustments. This step confirms the necessary separation of the fish from the bubble's tail in the sidebar's microblog.

Finalizing Position Adjustments

I've tested the revised margin on the microblog bubble and the fish's bottom value. The change to margin-bottom: 39px and bottom: 0px effectively positions the fish below the bubble's tail. This adjustment ensures the ASCII fish is now safely below the bubble and well within the allocated margin. I've verified the positioning and gap between the fish and tail are visually acceptable.

Positioning Fish Finalization

I've rigorously analyzed the vertical positioning, leading to a calculated adjustment. After careful consideration of the speech tail extension and microblog bubble's margin, I'm confident that a bottom: 0px value and a margin-bottom: 39px on the .microblog-bubble will guarantee the fish's optimal placement below the tail, and that's what I will test first.

Calculating Necessary Margin

I've revised the margin on the .sidebar .microblog-bubble, increasing the bottom value to 49px. This is to guarantee ample space below the tail, accounting for its extension and the fish's height. The fish's placement remains at the bottom, so with the increase in the bubble margin, the tail is now clear.

Finalizing Margin Adjustments

I've revised the margin on .sidebar .microblog-bubble, increasing the bottom value to 49px. This is to ensure ample space between the bubble tail's tip and the fish, taking into account the tail's 20px extension. The fish's position will remain at bottom: 0px within its container.

Anyway, so I moved the fish myself

So bot sitting is not a magic bullet to let novices code, I think. Fundamentally, it’s a great way to get started quickly, there’s no hello world anymore, there’s a whole week of struggling worth of code generated in seconds. The start will most often look and work very well for no effort on your side. But slowly, you will have to understand what is actually happening and how it happens in order to fix the small and large issues the bot created in its eternal effort to make sense of the next word given its limited context window. You will have to grow up fast, the bot won’t. You will come home from school, looking at the mess you both made, you will be disappointed in the both of you and do better next time. Maybe.

Had I written the CSS that positions the fish myself, I would have immediately been able to move the fish without any reasoning. This way, I had to scroll through the whole jungle of style Claude had made for my page, find the fish and try three different settings to get it below the box. Gemini had moved the fish into the box after finishing its deep thought. But I learned something about organising the CSS file, relative and absolute positioning. For me, that was a more fun way to learn than to do yet another “hello world” and lose interest after that. I was vibing.