Install any skill in seconds. Free to start, no credit card required.
Get Started Free →jpoindexter/onboarding-and-empty-states
Reference-grade guide to designing every state a view can be in — ideal, empty (first-use vs cleared vs no-results), loading, partial, error, offline, success, blocked, and zero-results — plus first-run onboarding that drives activation to the aha moment through show-don't-tell, just-in-time guidance, seed data, progress checklists, and contextual permission priming.
Passed 21 of 22 test cases with the skill, and 20 of 22 without it.
1 fixed20 passed either way1 still failing0 broke
Tokens, turns and time describe resource use, not a dollar price.
A test case the skill fixed. Same model, same prompt, with and without the skill.
We are introducing a real-time collaborative whiteboarding feature into 'ProjectHub'. Marketing wants to trigger a full-screen un-skippable modal pop-up every time any user opens any project until they complete a 5-minute interactive tutorial. How should existing users be notified of new features?
| Checked | Without skill | With skill |
|---|---|---|
| Uses a non-blocking contextual callout. | Passed | Passed |
| Honors user dismissal so the notification does not re-appear after closing. | Missed | Passed |
The instructions your model reads when the skill loads.
Most teams design exactly one state: the screen full of beautiful data. Then it ships and the first real user sees a blank rectangle, a spinner that never resolves, an error with no recovery, and a permission prompt on launch they instantly deny. The discipline that separates senior work is simple and unglamorous: design every state a view can be in, not just the happy one. A screen is not a picture; it is a state machine. This skill is the checklist of states you owe every view, and the craft of turning the emptiest, earliest, most fragile moments — first run and the blank slate — into the highest-leverage moments you have.
Before a view is "done," walk it through every state below. Each is a real screen a real user will hit. Skipping one doesn't delete the state; it ships it undesigned.
| State | When it shows | The one job |
|---|---|---|
| Ideal / populated | Real data, happy path | Show the content; this is the reward |
| Empty — first use | New user, nothing created yet | Explain value + one next action |
| Empty — user-cleared | User deleted/completed everything | Celebrate or reassure, offer re-entry |
| Empty — no results | Filter/search returned nothing | Explain why + broaden/clear path |
| Loading | Data in flight | Hold layout, show progress, no jank |
| Partial | Some data loaded, some pending/failed | Show what you have, flag what's missing |
| Error | Request/action failed | What broke, why, how to recover, retry |
| Offline | No connectivity | Name it, show cached data, queue actions |
| Success / confirmation | Action completed | Confirm, show result, offer next step |
| Permission / blocked | Capability denied or gated | Explain need, route to unblock |
| Zero-results search | Query matched nothing | Suggest, broaden, never dead-end |
The three "empty" states are different states. Conflating them is the single most common mistake in this whole area. "You have no projects yet" (first-use → onboard) is not "You finished all your tasks" (cleared → celebrate) is not "No results for 'xqz'" (no-results → broaden the query). Same blank canvas, three opposite messages and three different next actions.
The first-use empty state is the most valuable screen in your product and the one most often left as a sad gray "No data." It is the moment a user decides whether this thing is worth their time. Treat it as onboarding, not absence.
A strong first-use empty state has four parts:
<!-- First-use empty state: value + single action + glimpse -->
<section class="empty" role="status">
<img src="illustration.svg" alt="" aria-hidden="true" />
<h2>Your invoices live here</h2>
test cases passed, vs 20 / 22 without
More skills from the same source and nearby in the registry, with their headline benchmark lift.