tech, developers, and the code underneath

issue 213· essay·

The interface is the product

Users cannot see your architecture. They can see the six seconds it takes to do the thing they came for.

Engineers evaluate software by its internals: the architecture, the correctness, the elegance of the data model. Users evaluate it by the sequence of actions required to get what they came for.

These correlate less than we would like, and the gap is where a lot of otherwise good software fails.

what users actually experience#

Not your service boundaries. Not your consistency model. Not the fact that you handle a partition correctly.

  • How many steps to do the common thing.
  • Whether it responds instantly or after a spinner.
  • Whether an error tells them what to do.
  • Whether it does the same thing twice in a row.
  • Whether it remembers what they told it last time.

Every one of those is an interface property, and every one is achievable on top of an ugly implementation — or destroyed on top of a beautiful one.

the trade that is usually made backwards#

There is a real tension between internal cleanliness and external simplicity, and it comes up constantly:

  • The clean data model exposes three concepts where users think in one.
  • The correct API makes the caller specify things they do not care about.
  • The properly-separated services mean the UI has to make four calls and handle each failing independently.
  • The general solution has eleven configuration options; the specific one would have had zero.

The default resolution is to protect the internals and push the complexity outward, because the internals are what engineers look at and defend in review.

That is backwards. The interface is used far more times than the implementation is read. Complexity at the boundary is multiplied by every user and every call; complexity inside is paid by the people who chose it.

what this looks like in practice#

Collapse concepts at the boundary. If users think of one thing and your model has three, expose one and do the mapping internally. Yes, that is a lossy abstraction and you will occasionally have to break it. That is the correct place to put the pain.

Default everything. Every required parameter is a decision you have forced on someone who has less context than you. Make it optional with a sensible default, and let the people who genuinely need control find the option.

Make the common path one step. Count the actions for the thing 90% of users do 90% of the time. If it is more than two, that is the work.

Absorb the failure. If your architecture means four things can fail independently, the interface should not surface four independent failures. Retry, degrade, or present one coherent state.

Make it fast where they are waiting. A local read, an optimistic update, a cached response. Users cannot tell the difference between "fast because it is well-engineered" and "fast because you cheated" — and neither can anyone else.

the counterweight, honestly#

This is not an argument for shipping a nice facade over a broken system. The internals are what make the interface keep working — under load, at the edges, after a year of changes. Software that is lovely to use and impossible to change dies just as reliably, only slower.

The claim is narrower: when the two genuinely conflict, and they do, the interface should usually win — because it is what the software is for, and because interface decisions are much more expensive to reverse than internal ones. You can rewrite the storage layer. You cannot easily take back a concept you taught a million users.

the test#

Watch someone use your software for the first time without helping them.

Count the moments they hesitate. Each one is a place where your model and theirs diverged, and no amount of internal quality closes that gap.

That exercise is uncomfortable, takes twenty minutes, and consistently produces a better backlog than any amount of architectural discussion.

Dom, August 31, 2026

get README in your inbox

One dispatch, no noise. Tech and developer news, plus the occasional long piece on the craft.

subscribe →