by joshstrange | 2025-04-23 17:18:28+00:00
"Vibe Coding" is just simply not sustainable. I've yet to see any tool that can make edit after edit after edit to the core code base without making mistakes unless a developer is watching carefully.

LLMs are amazing tools and I do use them for writing code, refactoring code, etc. but I would never prompt engineer only. My use of LLMs often is a mix of jumping between Aider and writing code myself when Aider doesn't doesn't understand what I want, or what I want is a big refactor, which LLMs are not good at because it's too easy for them to make mistakes when writing huge blocks of code, like syntax errors and the like.

For a human moving a function or even indenting a block (to wrap in an if/try/catch/etc) is child's play. To an LLM? Yeah, it can easily make stupid mistakes (linting aside, I'm talking syntax errors) when doing that. Also, what a waste. We really should have MCP-type tools of "Wrap the code on lines X-Y" in a try/catch, since the logic for that is stupid-easy but for an LLM the only way to accomplish it is a massive Find/Replace block. The bigger the block of code that the LLM writes in 1-shot, the higher the chance it messes stuff up (or at least that's my experience).

I expect this situation to improve over time as as more coding assistant tools learn how to use things like linting, running a test build, running tests, etc. And yes, I know some already do that, I've just not been super impressed with their ability to do that so far. Despite clear instructions I've had both Claude Code and Aider run the wrong `npm run test:xxxx` command (the watch command instead of the ci version) and I then I have intervene. Even when they run the right command, it's still to easy for an LLM to get off in the weeds or far down a path you don't want.

The trick with LLMs is "commit often", I don't code that way myself, I'm more of a "one commit a the end"-type of guy (yes, I know you can squash) but I've changed that with LLMs since it gives you "save" points when the LLM goes off track. Often a bad/failed edit can completely derail the progress and a human _must_ intervene, reset to the last good state, and start over again. If you aren't committing regularly (after every couple exchanges or so) then you can have a mess on your hands:

Commit - Feature - Feature - Feature - Disaster

If you do this you have to pick apart the disaster by hand or give up on the 3 features/bug fixes, improvements, etc since your last commit.

Aider does a very nice job of this by default. I was opposed it when I first started using it but it's invaluable.

While I enjoy learning about coding, coding is not about the journey for me, it's about about the destination. And I gladly use Aider to pump out UI that would take me hours if I was capable of doing it at all, so that I can keep moving towards my destination. BUT, if you don't understand the code that's being written then you've already lost. I understand grid/flexbox but I'm just very slow at it. LLMs can pump out a UI (or 5-10 iterations of a UI) in practically no time at all, I can edit styles, I'm just slow at writing them from scratch. This is where LLMs shine IMHO, trying out things that would take longer or not have the ROI to do yourself.

"Hey our settings screen is a little cluttered, can we clean it up?" has a _very_ different answer if you can test 5 iterations and pick the best one in <1hr vs spending 2-3+ hours doing it from scratch. The amount of UI I have written has skyrocketed since LLMs came out. And, not unlike Electron, the options were not "LLM UI" or "Bad UI", the options before this were often "LLM UI" or "No UI" (CLI or developer-only focused UI pages).