Thoughts from vibecoding

By

I've been vibecoding for a while now and wanted to share some thoughts that I haven't seen discussed elsewhere regarding the process. To quote the original vibecoding definition by Andrej Karpathy:

It's not too bad for throwaway weekend projects, but still quite amusing. I'm building a project or webapp, but it's not really coding - I just see stuff, say stuff, run stuff, and copy paste stuff, and it mostly works.

And that's pretty much what I do as well. Some of vibecoded projects are on my website (said listing was also vibecoded — but all the text was written by hand), there are plenty more sitting in my ~/Downloads folder that I haven't bothered to clean up and publish.

Also note that I haven't gotten started with the whole "agentic" thing yet, so I'm just still typing prompts into a web browser and copying code out of it.

My standards have gone up#

Being a software engineer generally means that when something goes wrong with computers, you have a rough idea of what might have caused the error. Usually my response is along the lines of, well, all software is buggy, that's life.

These days I'm interested in seeing if I can do something better, both to make my life better, but also to just prove that we can make better software. As an example, a few months ago, I was filming a video for work and was relying on a random teleprompter website for our script.

I was struggling a bit with getting the emphasis right; the website didn't support any type of bold or italic formatting. Knowing what I know about HTML and JavaScript, I guessed that the website was treating everything as plain text, and that in theory, could support rich text if it used contenteditable.

I spent 10 minutes prompting Claude and then an hour fixing small bugs in the CSS/JS, and boom, an "Improved Teleprompter".

When the MTA released a new mobile app, it was okay, but not exactly the way I wanted my routes laid out. I built my own subway stops tracker that presents upcoming trains just how I want to see them, plus it stores all my data locally.

This doesn't necessarily mean the code is better, but rather the user experience is.

JavaScript is privacy-friendly#

Main article: Thinking of JavaScript as privacy-friendly tech

For the longest time, my stance was that JavaScript was a privacy-violating technology that needed to be avoided. I don't think that stance was originally irrational, given that most online tracking uses it, and tools like NoScript and RequestPolicy/uMatrix were effective at stopping that.

But today I think JavaScript has just as much to offer as privacy-friendly technology through things like client-side cryptography but also just keeping computing local instead of happening on someone else's computer.

You can get pretty far with JavaScript, localStorage, and optionally, some remote APIs. (Though CORS can be super annoying...)

Modifying is harder, but#

Modifying vibecoded projects is definitely harder because I didn't write the original code, and often it's not in the style I would have used. But I've found it's usually easy enough to just start over from scratch, replaying your original prompts, but with whatever modifications I needed.

I expect this is an area that I might have a different experience once I get around to agentic LLMs.

Content-Security-Policy is great#

This is not really news, I think it's well understood that the introduction of Content-Security-Policy has significantly improved web security. And that extends to vibecoded projects, especially if you haven't 100% reviewed everything.

The first version of my JSON diff tool that Claude created had a pretty glaring XSS that I noticed and fixed right away. But even if I hadn't, I deployed it with a policy of script-src 'self', so any inline <script> execution would be blocked.

In general it's nice to be able to clearly see and understand exactly what external websites (if any) these small projects will connect to.

I also really like how easy it is to share single-file HTML/CSS/JS projects (pages?), but having inline styles and scripts requires a weaker CSP. So I wrote resource-rewriter to use a single-file for deployment and then automatically move them to separate files during deployment.