Essential vs Accidental Difficulty: Programming with LLMs for Process, Not Output

There's a right way and a wrong way to code with LLMs. Fixate on the output and you lose your grip on your codebase's internals--and this will bite you soon™.

Seeing the split between essential and accidental difficulties [1] makes it clear where LLMs actually help.

The Split

Essential difficulty is the irreducible conceptual work of software: understanding the problem, defining the data/algorithms/constraints, and maintaining coherence as the system evolves.

Accidental difficulty is instantiating those platonic ideas into our grimy real world: boilerplate, APIs, configs, glue code, syntax, and the friction of iteration.

The Problem with Vibe Coding

When you vibe-code, you delegate the essential difficulty to the model. This hands you an outcome that you can observe from the outside: the app, the tool, the game. However, you end up being excluded from the process. You don't deeply understand or learn what is going on, nor are you able to iterate or integrate.

Maybe most importantly, this tends to be a soul-sucking workflow that alienates you from the craft of your work.

A Better Way

It doesn't have to be like this. Used deliberately, LLMs can help you work through the essential difficulty instead of obscuring it. In practice, you can use LLMs to:

  • Act as a pair programmer who can surface tradeoffs and pressure-test your designs.

  • Prototype alternative implementations so you can see concrete tradeoffs instead of reasoning in the abstract.

  • Verify assumptions, both internal to the code and external to the problem domain.

  • Map connections and data flows in the codebase that weren't initially obvious.

  • Generate flashcards so you learn the system faster (yes, I do this).

The Payoff

This approach pays off on any project that lives longer than a few days. Importantly, it still lets me take pride in my craft. For those quick one-off explorations, vibe it away.


[1] No Silver Bullet: Essence and Accidents of Software Engineering by Frederick P. Brooks, Jr.