Writing

The empty state is the product

The screen a new user sees before they've done anything is the most important one you'll design — and the one most teams skip.

Open almost any app for the first time and you’ll meet a blank table, a spinner, or a cheerful “Nothing here yet!” with a shrug emoji. The team built the populated state first — the dashboard full of data, the inbox full of mail — and bolted on the empty version at the end, in the last sprint, by whoever had a spare afternoon.

That’s backwards. The empty state is the first thing every user sees, and for a long stretch it’s the only thing they see. It is, functionally, your onboarding — the most-viewed screen in the entire product, shown to exactly the people who haven’t decided to stay yet.

What a good empty state does

A good empty state answers three questions at a glance:

  1. What is this? — In one line, what does this surface do once it’s full?
  2. Why should I care? — The value, stated as a benefit, not a feature.
  3. What do I do next? — A single, obvious action. Not five.

Here’s the shape I reach for:

type EmptyState = {
  // What the user is looking at
  title: string;
  // One sentence of value, in their language, not ours
  body: string;
  // Exactly one primary action
  action: { label: string; href: string };
};

One action. The moment you add a second primary button, you’ve handed the user a decision they don’t have enough context to make. “Import data” or “Create your first project” or “Invite your team” — pick the one that leads to the fastest taste of value and make the rest secondary, or cut them.

The two empty states people forget

There’s the first-run empty state, which gets at least some attention. Then there are two others that almost never do:

The you-cleared-everything state. The user finished all their tasks, archived every email, resolved every ticket. This should be a celebration, not the same sad shrug they saw on day one. They earned this. Show them they did.

The search-returned-nothing state. A dead end that says “No results” is a missed chance to suggest a broader query, fix an obvious typo, or offer the thing they were probably looking for. “No results for reciept” should quietly ask: did you mean receipt?

These aren’t edge cases. They’re the moments a real user actually hits, over and over, long after onboarding is a memory.

The tell of a rushed product

When I’m evaluating a tool, I deliberately look at it empty — fresh account, no data, nothing imported. You learn more from the empty state than from the marketing site. A team that sweated the blank screen sweated everything. A team that didn’t is telling you, honestly and for free, where their attention goes.

The populated state is where your product lives. The empty state is where it earns the right to.