Comprehensive patterns for perceived performance, loading states, skeleton screens, optimistic UI, notification systems, empty states, error states, onboarding flows, and offline-first patterns.
From ux-ui-masterynpx claudepluginhub phazurlabs/ux-ui-mastery --plugin ux-ui-masteryThis skill uses the workspace's default tool permissions.
references/empty-error-onboarding-states.mdreferences/notification-system-design.mdreferences/perceived-performance-patterns.mdDesigns and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
Every interface exists somewhere on a spectrum of states. The difference between an application that feels polished and one that feels fragile lies almost entirely in how it handles the moments between the ideal. Loading, emptiness, failure, first contact, disconnection — these transitional states collectively occupy more of a user's lived experience than the "happy path" designers typically obsess over. This skill addresses that full spectrum with rigor, providing concrete patterns, code, and architectural guidance for every in-between moment.
An interface element moves through a predictable lifecycle of states. Designing for all of them is not optional — it is the baseline for professional-grade UX.
EMPTY -> LOADING -> SKELETON -> PARTIAL -> COMPLETE -> ERROR -> OFFLINE
| | | | | | |
v v v v v v v
First-use Spinner Shimmer Streaming Ideal Recovery Cached
guidance or bar placeholders data render + retry fallback
Empty is the starting point: the user has arrived but there is no content yet. This could be a brand-new account, a search with no results, or a list that has been cleared. Empty states are opportunities to guide, teach, and motivate.
Loading is the state of uncertainty. The system is working, but the user cannot yet see results. The perceived duration of this state is more important than its actual duration — perceived performance is a design problem, not just an engineering one.
Skeleton is a specific loading sub-state where placeholder shapes mirror the eventual content layout. Skeleton screens reduce perceived wait time by giving the brain structural information to process, making the transition to real content feel faster and less jarring.
Partial is the state where some data has arrived but not all. Streaming server-side rendering, progressive image loading, and paginated lists all produce partial states. The key design challenge is making partial content usable without misleading users about completeness.
Complete is the happy path — all data loaded, all interactions available. This is the state most mockups depict, but it represents only one moment in the lifecycle.
Error is the state where something went wrong. Network failures, server errors, validation problems, permission issues, rate limits — each error type demands a different response. The goal is always: tell the user what happened, what it means for them, and what they can do next.
Offline is the state where network connectivity is lost. Modern applications must handle this gracefully, serving cached content where possible and queuing actions for later synchronization.
Users do not experience milliseconds — they experience feelings about speed. Research consistently shows that perceived performance matters more than actual performance for user satisfaction. A 3-second load that feels fast (because of skeleton screens and progressive rendering) outperforms a 2-second load that feels slow (because of a blank screen followed by a sudden content dump).
The three pillars of perceived performance are:
Skeleton screens, optimistic UI updates, pre-fetching, and progressive loading are all implementations of these principles. Detailed patterns, code examples, and implementation guidance are provided in the reference material.
See: references/perceived-performance-patterns.md
Notifications are the interface's voice — the mechanism by which an application communicates with users across time and context. A well-designed notification system respects attention as a finite resource. A poorly designed one trains users to ignore everything, or worse, to uninstall.
The notification taxonomy spans six channels, each with different characteristics:
| Channel | Persistence | Urgency | Context |
|---|---|---|---|
| Toast | Ephemeral (3-8s) | Low to medium | In-app, immediate |
| Banner/Alert | Until dismissed | Medium to high | In-app, contextual |
| Badge | Until addressed | Low (ambient) | In-app, persistent |
| Push | Until opened | Medium to high | OS-level, external |
| Notification Center | Permanent list | Varies | In-app, on-demand |
| Email/SMS | Permanent | Varies | External, asynchronous |
The architectural challenge is building a unified system where a single event can be routed to the appropriate channel based on urgency, user preferences, and context. A new message from a colleague might appear as a toast if the app is open, a push notification if it is not, and an email if the user is offline for hours — all from a single notification event.
Urgency must be calibrated carefully. If everything is marked critical, nothing is. The "crying wolf" anti-pattern — overusing high-urgency styling — is one of the most common notification design failures.
See: references/notification-system-design.md
Onboarding is not a single screen or a tooltip tour. It is a spectrum of patterns that help users move from unfamiliarity to competence. The best onboarding serves the user's goal, not the product's feature tour.
The onboarding spectrum, from least to most intrusive:
The pattern chosen should match the product's complexity and the user's likely familiarity with the domain. A developer tool can assume higher baseline literacy than a consumer social app. A complex B2B platform may need a checklist; a simple utility may need nothing beyond a well-designed empty state.
Empty states and onboarding are deeply connected. The first-use empty state is often the user's first onboarding moment — it should answer "What is this?" and "What do I do first?"
See: references/empty-error-onboarding-states.md
This skill intersects heavily with other areas of the UX/UI knowledge base:
Component Patterns & Code (component-patterns-code) — Foundational component architecture for buttons, forms, modals, and other elements referenced throughout the state patterns here. Loading buttons, form validation states, and modal error displays all build on component-level patterns.
Interaction & Motion Design (interaction-motion-design) — Animation timing, easing curves, and transition choreography for skeleton shimmer effects, toast enter/exit animations, progress indicator motion, and onboarding tour transitions. Motion is the connective tissue that makes state changes feel natural rather than jarring.
Mobile UX Design (mobile-ux-design) — Mobile-specific considerations for notification positioning, pull-to-refresh loading patterns, offline handling on unreliable cellular connections, and touch-optimized error recovery. Mobile constraints (smaller screens, intermittent connectivity, OS-level notification rules) shape many of the patterns here.
Accessibility & Inclusive Design (accessibility-inclusive-design) — ARIA live regions for dynamic notification announcements, screen reader behavior during loading states, focus management after error recovery, and ensuring skeleton screens do not confuse assistive technology. Every state pattern must be accessible or it is incomplete.
Cognitive Psychology & UX (cognitive-psychology-ux) — The psychological foundations underlying perceived performance (the perception of time), notification urgency calibration (attention and interruption science), empty state motivation (goal-gradient effect, endowed progress), and error message framing (loss aversion, self-efficacy).
Every state is a design opportunity. Empty states guide. Loading states reassure. Error states teach. Offline states demonstrate reliability. None of these are edge cases — they are core experiences.
Perceived speed trumps actual speed. Invest in skeleton screens, optimistic updates, and progressive loading. Users remember how fast something felt, not how fast it was.
Notifications are a finite resource. Every notification you send withdraws from a trust account. Send too many, and users revoke permission or uninstall. Earn the right to interrupt.
Error messages are a conversation. Write them in plain language. Tell the user what happened, why it matters to them, and what they can do about it. Never show raw error codes or stack traces.
Onboarding should be invisible when possible. The best onboarding is an interface so clear it does not need a tour. When explicit onboarding is necessary, make it serve the user's first goal, not the product's feature list.
Offline is not an error — it is a state. Modern applications should handle disconnection as a normal operating condition, not an exception. Cache aggressively, queue writes, and synchronize gracefully.
When designing any new feature, view, or component, walk through this checklist to ensure every state has been considered. Incomplete state coverage is the single most common source of "unpolished" feelings in production software.
For every data-dependent view, verify you have designed:
For every user action, verify you have designed:
For every notification event, verify you have designed:
This checklist is not exhaustive, but completing it for every new feature will eliminate the vast majority of state-related UX gaps that erode user trust over time.