Most SaaS onboarding advice is strategy: which users to target, when to show pricing, how to sequence emails. This isn't that. This is about the four or five UX mechanics that actually happen on screen in the first session — the empty state, the checklist, the progressive disclosure, the moment something first works — because that's where activation is won or lost, and it's the part most teams under-invest in relative to the acquisition funnel that got the user there in the first place.
Empty states that teach instead of apologize
The default empty state is a gray box with "No data yet" and maybe a button. That's a wasted screen. The first time a user sees a table, a dashboard, or a workspace with nothing in it, that screen is doing one job: showing them what it will look like once it's not empty, and giving them exactly one action to get there. A good empty state has a short sentence describing the end state ("Your first project will show up here"), a visual approximation of populated content — even a grayed-out mockup — and a single primary button that starts the shortest path to filling it in. Multiple competing buttons on an empty state is a sign the team hasn't decided what the first action actually is.
Empty states are the screen every new user sees and the screen teams QA least, because by the time you're testing internally your account already has data. Log in with a genuinely fresh account before every release and look at every list, table, and dashboard with nothing in it.
Setup checklists that guide without nagging
A setup checklist works when it's short, ordered by dependency, and disappears once it's done. It stops working the moment it becomes a permanent fixture nagging a user who has already gotten value from the product without finishing item 4. The pattern that holds up: 3-5 items, each one unlocked or made obviously relevant by the item before it, progress shown as a fraction or bar rather than a vague percentage, and a way to dismiss it that the product respects — if a user closes the checklist, don't resurrect it on every page load.
function SetupChecklist({ steps, onDismiss }) {
const done = steps.filter(s => s.complete).length;
if (done === steps.length || steps.dismissed) return null;
return (
<div className="checklist">
<div className="checklist-header">
<span>{done} of {steps.length} done</span>
<button onClick={onDismiss}>Dismiss</button>
</div>
{steps.map(step => (
<a key={step.id} href={step.href}
className={step.complete ? 'done' : 'pending'}>
{step.label}
</a>
))}
</div>
);
}
Progressive disclosure: hide the 80% that isn't needed yet
Every mature SaaS product accumulates settings, edge-case options, and power-user features that a brand-new account has no use for and no context to evaluate. Progressive disclosure means the first-run experience shows the smallest set of controls that produces a working result, and everything else — advanced filters, bulk actions, integrations, permission granularity — appears only when the user reaches a point where they'd plausibly need it. The mistake is confusing this with hiding things behind an extra click for its own sake; the goal isn't fewer options visible, it's fewer options visible before the user has the context to make sense of them. A settings panel with forty toggles on day one teaches the user that this product is complicated before they've learned it's useful.
Engineering the first activation moment
Activation is usually defined at the account or cohort level — "70% of users who do X in the first week retain" — but from the UX side it's a specific moment on a specific screen: the first chart that renders with real data, the first automated email that goes out, the first teammate who accepts an invite. That moment needs to be visually distinct from the fifty times it happens afterward — a brief animation, a confirmation toast, a "nice, that's your first one" microcopy — because the user needs external confirmation that what they did actually worked and mattered. Silence at that moment reads as ambiguity, and ambiguous success feels the same as failure to someone still deciding whether this product is worth their time.
Celebrating success with a modal that requires a click to dismiss adds friction to the exact moment you want frictionless. A toast, an inline badge, or a state change in the UI the user is already looking at works better than anything that interrupts.
When checklists and disclosure work against each other
These patterns can conflict: a setup checklist that says "configure your team's permissions" is pointing straight at the advanced settings panel that progressive disclosure is supposed to be hiding. The fix isn't to drop one pattern, it's to make the checklist item itself the disclosure trigger — clicking "configure permissions" from the checklist should reveal exactly the permissions UI in context, not dump the user into a fully-expanded settings page where the one setting they need is one of thirty. Treat every checklist item as a deep link into a temporarily-disclosed piece of UI, not a signpost to go find something.
Wrapping up
None of these patterns are novel — empty states, checklists, and progressive disclosure have been onboarding staples for a decade. What separates a product that activates well is treating them as one connected system rather than separate features: the empty state hands off to the checklist, the checklist reveals disclosure in context, and the whole thing ends at a clearly marked first win. Get that chain right and most of the "onboarding strategy" conversations upstream get a lot easier to have.
Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.