Every word in an interface is a design decision. Strip away the colors, the shadows, the border radii, and what's left is text. That text is doing most of the work.
A pixel-perfect layout with lazy copy feels broken. A plain layout with precise copy feels professional. The gap between the two is not aesthetics — it's trust.
Button Labels Are Promises
A button label is a promise — it tells the user what will happen when they click. That makes it one of the highest-stakes pieces of text in any interface.
I follow a simple test: a button label should complete the sentence "I want to ___." "I want to save changes" works. "I want to OK" does not. If the label can't finish that sentence, it's not doing its job.
Placeholder Text Is Not a Label
A placeholder disappears the moment you start typing, which means it fails at the exact moment the user needs it most — when they're mid-input, trying to remember what the field is asking for.
The label says what it is. The placeholder shows what it looks like.
Error Messages Are Conversations
The worst error message is "Invalid input." It tells the user they're wrong without telling them how to be right. Good error messages have three parts: what happened, why it happened, and what to do about it.
Tone matters too. "Password must be at least 8 characters" is neutral. "Your password is too short" feels judgmental. "Use 8 or more characters" is helpful.
Confirmation Messages Name What Happened
"Success" is the confirmation equivalent of "OK" on a button — technically correct and practically useless. The user just performed an action, and the system's response should mirror that specificity back. "Your changes to 'Project Alpha' have been saved" closes the cognitive loop.
This matters most when users are doing things in bulk or across multiple tabs. If you saved three different documents in the last minute, a green checkmark and "Success!" tells you nothing about which save just completed.
Empty States Are Turning Points
An empty state is the most overlooked moment in interface design — the user had intent, typed a query, navigated somewhere with a purpose, and came up short. Most teams treat this as a non-moment: "No results found." Dead end.
But an empty state is actually a turning point. A thoughtful one echoes back what the user tried, confirms the system understood them, and suggests what to do next.
Destructive Actions Demand Clarity
"Delete" is fine for removing a tag from a list. "Delete" is dangerous for wiping a project someone spent three months building. The word is the same, but the stakes are completely different — and the interface should reflect that.
Emails Deserve the Same Rigor
Two rules I apply to every transactional email. First: use consistent nouns. If the subject line says "invitation," the body should not switch to "invite" halfway through. Inconsistency signals that nobody proofread this.
Second: no relative dates. "This link will expire in 72 hours" is useless the moment someone opens the email a day late. "Expires March 27, 2026" is unambiguous regardless of when the email is read. Relative time is convenient for the sender. Absolute time is useful for the reader.
This invitation was intended for hi@vercel.com.
This invite was sent on March 24, 2026, 12:55 AM (UTC) and will expire in 72 hours. This invitewas sent from 204.13.186.218 located in São Paulo, Brazil. If you were not expecting this invitation, you can ignore this email. If you are concerned about your account's safety, please visit our Help page to get in touch with us.
Manage your notification settings
This invitation was sent to hi@vercel.com on March 24, 2026 at 12:55 AM (UTC) from 204.13.186.218 (São Paulo, Brazil). Expires March 27, 2026.
Didn't expect this? Safe to ignore. Concerned about your account? Visit our Help page.
Manage notification settings
Changelogs Are Retention Surfaces
Most changelogs read like commit messages: "Added dark mode support. Fixed bug in export." Nobody cares. The engineer who wrote the fix cares. The PM who filed the ticket cares. The user scrolling the "What's New" modal does not.
A changelog is a retention marketing surface disguised as documentation. Every line is an opportunity to remind users why they pay for your product. "Fixed custom font rendering issue" describes what the engineer did. "Your exports now include custom fonts" tells the user what they gained. The first is a task completion. The second is a gift.
The shift is simple: write from the user's perspective, not the developer's. Instead of describing the change, describe the outcome. Instead of naming the component, name the benefit. "Added dark mode support" becomes "You can now switch to dark mode from Settings" — suddenly the user knows exactly where to find it and what to do.
Teams that write changelogs like release notes churn users. Teams that write them like personal letters keep them.
Loading Copy Defends a Delay
When the product is slow, the copy is the product. For a few seconds, the user has nothing to look at, nothing to interact with, nothing to do — just words on a screen and a spinner. Every other piece of interface copy describes an action. Loading copy is the only moment where the interface has to justify its own existence in real time.
"Please wait..." is dead air. It communicates nothing except that the system is busy and you should sit there. It doesn't say what's happening, how long it will take, or whether anything is actually working. It's the software equivalent of hold music with no queue position.
"Generating your report — this usually takes about 6 seconds" does three things at once: it names the task (so the user knows something is actually happening), it sets a time expectation (so they know whether to stay or switch tabs), and the word "usually" hedges honestly (so if it takes 8 seconds, the copy still holds).
Click "Generate Report" in both panels and wait.
Notes
- Interfaces should sound like a helpful colleague — clear, concise, and human.
- Words compound. One well-written label is forgettable. A hundred of them make software feel alive.