Vibe coding with Claude Code

Vibe coding with Claude Code
Photo by Benjamin Wedemeyer on Unsplash

I've been trying out Vibe Coding.

There's a new kind of coding I call "vibe coding", where you fully give in to the vibes, embrace exponentials, and forget that the code even exists

It's not been easy for me, as someone who puts a lot of effort in to how my code looks (even if I have had my fair share of horror show applications). But, I have to say, I've been really impressed with what some of these tools can do.

Firstly, I tried Claude Code. This is an experimental tool from Anthropic that you download and run from the command line. It sits on your machine, inside the root of your project and you can tell it to do things with your code. Because it's local, it can then run the code and respond to the changes it makes.

I had an idea of how to reimplement part of Collabor8Online - and as this feature was also needed in a brand new project we've just won, I figured I'd try implementing it as a Rails engine, so the code could be shared.

I started off by riffing on my idea. In my case, that meant opening BBEdit (instead of an IDE), and just writing out some ruby classes to see how they could slot together. After about half an hour, I was pretty sure I could make this work.

Then I built a skeleton Rails Engine and created a couple of the key models - database migrations, plus stuff like associations and validations.

It was at that point I thought about vibe coding. I downloaded Claude Code, initialised it in my gem's folder, then asked it to build RSpec for the models. It did a decent enough job (without missing any test cases, which has been a problem I've seen before). So then I added a few more models - migrations, associations and validations - and got Claude Code to do more specs.

One advantage of Claude Code is that it sits on your machine. It quickly realised that I wanted everything linted with standardrb and that it could run the specs itself. So it would make a change, run the specs, see the failure and fix the change it had made.

Then came the big one. I wanted to add Access Control Lists to this project. I told Claude what I wanted and used the magic words "think about this carefully". It spent at least two minutes "thinking" and presented me with four alternative implementations. I chose the first one and Claude went away and built it - migrations, models and specs - the lot. Claude also recommended the use of the word "subject" as the accepted term, as opposed to "owner" which I had used in my description.

Again, this took a while, and it went back every now and then, correcting itself as it worked. But by the end, we had a pretty good implementation along with much more comprehensive specs than I would have written alone. I checked the cost, and by this point I'd spent about $4.

One problem though. Claude had used the american "authorize" and "authorization" throughout. I'm English. So I asked Claude to alias "authorize" with "authorise" and allow both "Authorisation" and "Authorization" to be used when specifying classes. You can watch a video of Claude Code making those changes . It did a better job than I would have done, wrote comprehensive specs (if anything, they test too much and I'm going to slim them down) and completed the task in five minutes (at a cost of $0.93).

So far, not so vibey. I was busy checking all of Claude's output - especially the specs - because this is likely to be important code that will be maintained for a good few years. But I was very impressed with the way Claude Code works.

Next attempt at vibing. I loaded Claude Code into a project for a freelance client of mine. This project had a few system specs, plus a few request specs for the API. But it had no request specs for the HTML controllers. And as it required translations all over the place, I wanted to make sure that every end point would render correctly.

So I told Claude to look at all the controllers and routes. For each controller, create a skeleton controller spec in the appropriate spec/request folder and then look at which actions are defined within the controller. For each GET action, add a test for 401s, 404s and 200s. For each POST, PATCH or DELETE action, add a test for 401s, 404s and 302s. And for the POST and PATCH actions, look at the parameters that the controller is expecting and prefill the test with stub values for those parameters, so I don't need to add them myself.

Using the word "stub" was a mistake. Claude produced an abomination with stubs and mocks everywhere. So I went in to one of the controller specs, tidied it up, getting authentication working properly (create a user model, then go to the login page, post the username and password so that the session is correctly set before proceeding to the main test). And I told Claude to look at this controller spec and follow the same pattern in all the others.

It removed (most) of the stubs and mocks and left me with a useful set of outline controller specs that we could then fill in by hand. I didn't see the point in burning through a load of money explaining the data model to Claude so it could setup the correct models for each test. However, I had saved a ton of time and it was a task I would have struggled to do with just scripting.

Still not 100% vibey though. Until yesterday.

We had a quick catchup meeting and the boss mentioned a feature that's been talked about for ages. Collabor8Online manages revisions for construction drawings. A lot of them are in PDF format. And a comparison tool for PDFs - highlighting the differences between two revisions of the same document - was one of those features that would be really useful but I'd never added to the task list because I had no idea how to do it and it felt like it would take ages.

I asked Claude "build me a web page that allows two PDFs to be uploaded, then displays the differences between the two". Less than a minute later, I had an "artefact" that did exactly what we needed. Still unable to vibe fully, I took a look at the code. It was using PDF.js which we already used in our product, but the way the code was structured wasn't going to be easy to reuse. So I asked Claude to rewrite the HTML and JS as a custom web element with attributes that I can fill in telling it where to find the two PDFs. Claude did this (total time spent, around five minutes), I took the custom element javascript file and hooked it into our application. It took me about an hour in total, because I had to strip away some of the styling and HTML to make it match the rest of the application.

But it was done and I deployed it to staging for the others to take a look at.

A important feature that customers had been asking for was implemented in just over an hour. And I barely understand the code that's used to make it work.

Vibe achieved.

Rahoul Baruah

Rahoul Baruah

Rubyist since 1.8.6. I like hair, dogs and Kim/Charli/Poppy. Also CTO at Collabor8Online.
Leeds, England