← All writing

Vibe Coding

An orange cat perched on a person’s shoulder.

It’s been a long time since I posted here. I’m back, with a cat who may occasionally help with the writing. 🐱

I’ve spent the last four years in Barcelona at Apple, where I’m a lead machine learning engineer. My work has covered foundation models, inference on phones, and the search systems behind Spotlight and Siri. I’ve worked with people who are both very good at what they do and kind to the people around them. The projects have ranged from fitting Transformers onto mobile hardware to batch inference and the different stages of LLM training.

One highlight was presenting some of our work to Tim Cook and the AI/ML leadership at the Steve Jobs Theater. The project focused on Siri’s performance in everyday use, where memory, latency, and battery use all constrain what you can run.

Two people posing at the Steve Jobs Theater.

Apple’s secrecy is part of why this blog has been quiet. Most of the work I wanted to write about wasn’t something I could share publicly.

I’m now on sabbatical and heading to the Recurse Center in NYC for the S2’25 batch. RC is a self-directed programming retreat where people spend 6 to 12 weeks working on projects they choose. I’ve wanted to go for a long time, and I’m looking forward to having that much time to learn and build.

I plan to work on high-performance AI reasoning algorithms, spend more time with functional programming, and try a few projects that have been sitting in my notes for years. I’m also looking forward to meeting people whose programming interests are different from mine.

Vibe coding

One thing I’ve been thinking about lately is vibe coding. Andrej Karpathy coined the term to describe programming by asking an AI for changes and accepting the results without keeping track of the code itself.

With tools such as Cursor and Claude Sonnet, you can describe a program, accept the generated changes, and get something running quite quickly. When it breaks, you can paste the error into the conversation and ask for another attempt. I can see the appeal, especially when you want to try an idea before spending much time on it.

I use these tools every day. Copilot’s autocomplete saves me time, and I ask Claude for help with regular expressions, boilerplate, and confusing stack traces. I still want to understand the resulting code and make the decisions about how the program fits together.

Why vibe coding bothers me

My main concern is ending up responsible for code I can’t explain. While writing a feature, I need to think about how it interacts with the rest of the system, what it costs to run, and what happens with unexpected inputs. Accepting changes without following them leaves those questions unanswered, which becomes a problem when the software needs to be maintained.

That lack of understanding also makes debugging harder. Generated code can fail for the same reasons as other code, and asking the model for another patch doesn’t tell me whether it has found the cause. I want to be able to follow the failure myself and judge whether the proposed fix makes sense.

I also worry about what I miss when I skip the reasoning. Working through an unfamiliar system is how I learn to make better decisions the next time. A tool can help with that process by explaining code or suggesting possibilities, but I don’t get much practice if I only accept its answers.

There are impressive demonstrations, including Pieter Levels building games through prompting. They show how quickly an idea can become something people can try. The security concerns raised around these projects also make me cautious about treating a working demo as evidence that the software is ready for wider use.

Much of my software work involves an existing codebase, constraints from other systems, and decisions made with a team. A coding model can help me work through parts of that, but I still need enough context to decide whether a change fits.

Autocomplete and generated boilerplate have been useful because they let me spend less time typing code I already know I need. Debugging suggestions help when I can check them against the behavior I’m seeing. Those are the uses I trust most in my own work.

Maximilian Schwarzmueller’s discussion is close to how I think about it: use the tools for assistance while staying responsible for the design and the result.

Understanding still beats vibing

I want to use coding tools without losing track of what I’m building. Getting a program to run sooner is useful, but I also need to be able to change it, debug it, and explain why it behaves the way it does.

I’ll keep using these tools and trying new ways to work with them. For a project I expect to maintain, though, understanding the code remains part of the work.

Discussion

Read or leave a comment on GitHub.