The first version of a tool is usually a conversation with yourself. The second version is a conversation with a stranger who has different assumptions, a different screen, and five minutes less time.
Make the happy path obvious
A useful interface answers three questions without explanation:
- Where am I?
- What can I do here?
- What happened after I did it?
This sounds simple, but small omissions create a surprising amount of friction.
A button that says Run is less helpful than a button that says Generate preview, especially when the operation takes a few seconds.
Prefer visible state over clever behavior
The most reassuring loading state is often the least sophisticated one:
const status = {
idle: 'Ready to start',
loading: 'Preparing preview…',
success: 'Preview is ready',
error: 'Something went wrong. Try again.',
};
It is also easier to test. A reviewer can inspect each state, a screen reader can announce it, and a future contributor does not need to reverse-engineer a chain of implicit transitions.
Trade-offs worth writing down
| Decision | We chose | We gave up |
|---|---|---|
| Static pages | Simple deployment and fast responses | Server-side personalization |
| Markdown content | Easy editing and version history | Rich CMS workflows |
| Explicit states | Predictable UI and testing | A little more markup |
The smallest useful release
For a new feature, I now ask:
- Can a reader understand the result without a demo?
- Can they recover from the most likely error?
- Can we remove one option without losing the core value?
If the answer to the last question is yes, remove it for now. A smaller tool leaves more room for observation, and observation is how the next version gets better.
Make the common path calm, the unusual path visible, and the dangerous path difficult to take by accident.