Coding with Claude
Back in July1 I took the leap and started asking Claude to build me some micro-apps, prompted by Simon Willison’s ongoing notes on AI-generated tools. It’s surprisingly effective and fun!
Since then I’ve been thinking about whether I can streamline this for myself and better integrate it into a development workflow. Right now, when I’m just doing it with the Claude.ai chat front end:
If I want to do any local coding, there’s a lot of bidirectional copy+pasting involved, so I can’t get into a good rhythm on either coding or chatting.
If there are any server side components involved, I have to do local coding, so I don’t have the option of sticking with just the chat.
On the flip side, sometimes I get into too good a rhythm on the chatting.
Meanwhile, I want a proper version history! This should be a git repo.
The rhythm stuff
As others have noted, Claude will tend to get me the first 90% right away.
Then in the artifact preview, I’ll quickly spot some trivial-seeming bug or simple tweak I want to make that would typically just take me a minute to track down and fix in a normal development flow.
But switching to local development is kind of a pain with all that copy+pasting. So instead I often tell Claude what’s wrong and ask it for a fix.
I’m finding that we tend to veer into hallucination territory at this point. Sometimes Claude’s fix works. But sometimes it doesn’t, and we’ll get into a lengthy back-and-forth with Claude repeatedly apologizing and confidently asserting this time it’s definitely fixed. Each time, it isn’t.
The longer we go, the more likely that Claude decides to change some other stuff too while it’s in there, rather than focusing narrowly on my one edit. (Interestingly, these interactions feel like they fit a “junior developer” pattern, which makes me think Claude may be picking up on inadvertent social cues from the way I’m delivering feedback.)
Obviously, if I could just switch effortlessly between chatting and coding, I’d skip all of that, saving myself a lot of time and saving Claude a lot of stress. Starting a fresh chat with just the buggy code often does better, but that’s not effortless either!
Coding with Aider
Aider should be better for all of this. I’ve tried it out a few times now — people keep recommending it! — but it’s only recently begun to stick for me at all.
It’s almost doing too much for my preferences. I find it a lot harder to keep the code all loaded in my head as soon as Aider gets involved, so for many use cases the cognitive overhead isn’t worth the speed.
When Aider is working directly in my filesystem, it feels less like collaboration and more like temporarily ceding control. Its methodical chain-of-thought style ("First we need to modify x, then update y to match, finally adjust z... here's the diff... okay, we've completed all three changes") keeps the conversation loops tight and productive, but also means I'm following along with someone else’s thought process rather than driving my own.
That said, if I’m willing to just let someone else be in the driver’s seat, it does sometimes work very well for me. I just have to think of it more like someone else’s codebase that I’ve inherited or am temporarily collaborating on.
Emergent patterns
There are interesting emergent code organization patterns too between coding-with-Claude.ai vs coding-with-Clauder-in-Aider:
When coding with Claude.ai it’s often easiest to keep our code in one big file, because that makes it easier for us to hand it back and forth with the clipboard.
When coding with Aider it’s often easiest to break up our code into small files pretty quickly, because that allows me to regain finer-grained control over what the AI knows about and is allowed to edit in any given prompting session.
Cognitive ownership
These different approaches and user interfaces really affect how I maintain mental ownership of the code.
When working with Claude.ai, the friction of the process keeps me engaged even when Claude's originating the code. The conversation-first interface and the always-asking-questions system prompt mean that I'm constantly explaining what I want, evaluating what Claude proposes, and responding to questions about where I want to take the code and conversation next.
And Claude's tendency toward lazy shortcuts like /* rest of code remains the same... */
rather than diffs actually helps a lot here — it forces me to actively read every line, find the matching context, and consciously choose what to integrate. That all serves to keep the code fresh in my working memory.
Aider's filesystem integration, which should make everything smoother, actually undermines this ownership. Changes appear directly in my working tree, code evolves in place, and both Aider and I are actively modifying the same local files. The seamless handling of multi-file changes makes it a lot harder to track it all in my head.
And the direct git commits to my checked-out branch mean that we skip past the git diff
, git add
, and commit-message-crafting steps that I would typically use as last-chance opportunities to both review & load it all back in to my head.
Commit-driven development
I’ve been thinking that what I really want a lot of the time would be commit-message-driven development:
I write a thoughtful, thorough commit message that outlines what changes were made & why, and maybe even indicate which files were changed. But I don’t actually touch any files. Or maybe I do touch a few files a little bit, adding as much or as little of the implementation as I feel like, and maybe some
@@TODO
comments. But mostly I spend time on the commit message.I …
commit --allow-empty
that message? Or push it to a branch? Or put it in a chat interface somewhere? Or file it as a Github issue? ¯\_(ツ)_/¯My AI coding companion picks things up from there, puts together a diff, and submits a pull request.
I review the pull request in Github.
Perhaps we chat things over asynchronously in the PR. Perhaps further edits are made by either of us.
Eventually I merge it.
I suspect that would let me retain the cognitive ownership that I often want, re-clarify the authorship and blames that my current AI workflows are blurring, and put the code review bits where I naturally want to look for them.
Coding with anything but Claude
For a while I was using Claude exclusively for this stuff. Recently something shifted: I like Claude too much, so I find myself wanting to conserve my precious tokens.
Now I’m increasingly going over to ChatGPT or Gemini when I have something boring2 to code or need to look up some documentation, and reserving Claude for the (still very frequent) times when I want to chat through options, get insightful feedback, see creative solutions, or just need someone who understands my aesthetic and voice.
Before that I had tried AI-assisted coding a few times since ChatGPT came out, but this was the first time I actually liked it or found it at all useful. It turns out the trick was using Claude instead of ChatGPT.
Today I asked ChatGPT to “continue this pattern up to 16”:
const column_grid_classes = {
1: 'grid-cols-1',
2: 'grid-cols-2',
};
It was glorious!