Based on Katherine Gilligan's public "Build For Good UX" series (@synsation_). Use this as an implementation checklist for UI work, not as transcript notes.
Core Principle
Good UI is how an app looks. Good UX is whether users understand what to do, what happened, what failed, and how to recover. AI-generated UI often covers only the happy path. Build the full experience.
Every screen needs these states:
State
Required UX
Loading
Shows progress appropriate to wait time and scope
Success
Confirms the user's action worked
Error
Explains what happened, why, and next action
Empty
Explains why nothing is there and how to start or continue
Good UX builds trust. Bad UX creates uncertainty, extra steps, and friction. Users leave and blame the product, not themselves.
Required Workflow
When building or reviewing a UI, do this before considering the work complete:
Identify every user action and async data source.
Define loading, success, error, and empty states for each relevant screen or section.
Pick the loader based on scope and duration.
Place errors next to the thing that caused them unless the issue blocks the whole flow.
Ensure every action gives visible feedback.
Make each page section resilient when other sections load slowly or fail.
Use familiar patterns for the user's device, locale, and audience.
Reduce choice overload with grouping, curation, filtering, or progressive disclosure.
Verify the final checklist at the bottom of this file.
Loading States
Missing loaders make users think the app is broken. A blank screen with no response can lose users in 2-3 seconds. Bad loaders can also make the app feel slower.
Choose Loader By Context
Pattern
Use When
Avoid When
Skeleton screen
Whole page or large content section loads
Small contained action
Progress bar
Duration or progress is knowable
Unknown background wait
Inline spinner
Button or small section is working
Whole page load
Optimistic UI
Action is very likely to succeed
Failure would be costly or confusing
No loader
Work finishes under 1 second
Delay may exceed 1 second
Timing Rules
Duration
UX Rule
Under 1 second
Show result, no loader. Spinner flash feels slower.
1-2 seconds
Plain spinner is enough.
2-5 seconds
Spinner still works.
5-10 seconds
Add text. Prefer changing text like "Connecting..." then "Almost there...".
Over 10 seconds
Replace looped spinner with progress bar or step indicator.
On failure
Show error as soon as possible. Do not make users wait then fail.
Skeleton Rules
Show page structure first as gray placeholder outlines.
Match final layout closely so users start processing structure before data arrives.
Use skeletons for feeds, dashboards, profiles, and content-heavy pages.
Use inline spinners for buttons or small parts where skeletons do not fit.
Optimistic UI Rules
Update UI immediately when action is likely to succeed, like a like/favorite/toggle.
Do not wait for server confirmation before showing the expected result.
If the server fails, roll back clearly and gracefully.
Do not use optimistic UI for payments, destructive actions, bookings, or anything where false success creates risk.
Error States
Errors must reduce uncertainty. Never leave users wondering whether an action worked.
Error Message Formula
Good error messages include all three:
What happened.
Why it happened, in user language.
What the user can do next.
Bad:
Something went wrong.
Good:
Your payment didn't go through. Your card was declined. Check your card details or try a different payment method.
Error Rules
Never dump database, backend, stack trace, or raw exception details into UI.
Never silently fail. A clicked button must produce feedback.
Avoid vague messages when user needs certainty.
Always provide recovery: retry, edit, request access, update payment, or contact support.
Show errors immediately when known. Do not hide failure behind long loading.
Error Placement
Placement
Use When
Rules
Inline
Field-specific errors, button action failure, most forms
Closest to the problem. Use red border plus message.
Toast
Non-critical, recoverable status
Auto-dismiss only if user can miss it without harm. Example: "Couldn't connect, retrying..."
Modal
Critical blocker requiring user action
Blocks flow. Must include clear next action. Use sparingly.
If blocking the user with a modal, provide a way forward.
Form UX
Forms create friction. Reduce effort, uncertainty, and rework.
Form Rules
Disable submit until required fields are valid, but explain what is missing.
Mark required fields clearly so users are never guessing why submit is disabled.
Validate inline when users leave a field, not only after submit.
Keep validation messages near the field, not at the top of the page.
Show character counts for limited fields.
Pre-fill known values, such as logged-in user's email.
Show password requirements while typing and check them off live.
Accept forgiving formats, such as phone numbers with spaces, dashes, parentheses, or no formatting. Normalize in code.
For forms with more than seven fields, consider splitting into multiple steps or sections.
Form Mistakes To Avoid
Disabled button with no explanation.
Submit, wait, then scroll to find errors.
Rejecting user input because formatting differs from preferred display format.
Making users type data the app already knows.
Showing all fields at once when the form feels like a wall.
Empty States
Empty states are often first impressions. Do not leave blank areas or dead ends.
Empty State Rules
Explain what the area is for.
Explain why it is empty.
Provide a clear next action.
Add guidance, steps, or onboarding when helpful.
Handle every empty section, not only the page-level state.
Empty Search Results
"No results" is acceptable but weak.
"No results for purple shoes" is better because it confirms the query.
Offer an action: clear filters, try a broader search, or search the same term elsewhere if relevant.
Goal Empty States
When emptiness is success, celebrate it:
Inbox zero.
No open tasks.
All steps complete.
Use subtle delight, animation, or visual reward so the state feels achieved, not broken.
Partial Loading And Graceful Degradation
Pages are made of sections backed by different data sources. Each section should load, fail, and recover independently.
Rules
Load what is available instead of waiting for everything.
Give each section its own loading state, error state, and retry action.
If one section fails, keep the rest of the page usable.
Show cached content while fresh data loads when available.
Think through mixed states: some sections loaded, some loading, some failed, some stale.
Implementation Pattern
Page
|-- Profile section: own data, loader, error, retry
|-- Feed section: own data, loader, error, retry
|-- Sidebar section: own data, loader, error, retry
`-- Charts section: own data, loader, error, retry
Avoid
Full-page loading screen until every component is ready.
Full-page error because one API call failed.
One failed section taking down the whole page.
Hiding cached or stale-but-useful content during refresh.
Success States
Users need to know their action worked. Missing success feedback creates anxiety and repeated actions.
Success Feedback Rules
Always close the loop after user action.
Match feedback intensity to importance.
Use subtle feedback for small actions like likes, toggles, or saved settings.
Use clear confirmation for high-stakes actions like payment, booking, or submission.
Use celebration for milestones like first project, major task completion, or achievement.
Sometimes the changed state is confirmation, like a card moving from "To do" to "Done" and staying there.
Avoid
No feedback after critical action.
Over-celebrating routine actions.
Full-page success for actions that only need inline confirmation.
Leaving users unsure whether they should click again.
Familiar Patterns And Jakob's Law
Users spend most of their time in other apps. They expect yours to follow patterns they already know. Predictable structure lets users focus on their goal instead of relearning basics.
Rules
Standardize placement for common components: navigation, search, cart, checkout, form patterns, account controls.
Apply standards for the user's context, not a generic desktop default.
Desktop web patterns differ from mobile patterns.
Mobile layouts must account for thumb reach. Important actions often belong near the bottom.
Locale matters. Right-to-left experiences may mirror placement, such as cart moving from top right to top left.
Audience and market norms matter. Follow the pattern users in that context already know.
Keep structure familiar while making visual design distinct.
Standardize Vs Customize
Standardize
Customize
Navigation placement
Brand color and typography
Cart and checkout flow
Illustration style
Search placement
Motion and microinteractions
Form layout conventions
Tone and copy
Error/success placement
Visual personality
Creative placement of common controls creates friction. Creative styling of familiar structure creates personality without confusion.
Hick's Law And Choice Complexity
Decision time increases as choices increase in number and complexity. Good UX keeps visible options manageable without removing capability.
Rules
Prioritize one clear primary action per screen or step.
Reduce competing calls to action.
Group related options.
Curate defaults or recommendations instead of showing everything.
Use filters, search, and categories to help users narrow options.
Use progressive disclosure: show the next useful choice when it becomes relevant.
Break large forms into pages, steps, or sections when field count and complexity become overwhelming.
Consider multi-step forms when there are more than seven fields.
Examples
Google focuses the homepage on one action: search.
Netflix has thousands of titles but shows curated rows and recommendations first.
A long menu can show key options first, then let users search, filter, or expand.
Avoid
Showing every option on the first screen.
Making secondary actions compete with the primary action.
Hiding needed options so deeply users cannot recover them.
Treating choice reduction as removing power. It should reduce overload while preserving access.
Quick Decision Tables
Loader Choice
Situation
Use
Whole page or feed loading
Skeleton
File upload/download/install
Progress bar
Button click or small section refresh
Inline spinner
Like, favorite, low-risk toggle
Optimistic UI
Under 1 second
No loader
Error Placement
Situation
Use
Invalid field
Inline field error
Button action failed
Inline near button
Non-critical background issue
Toast
Payment, permission, or blocker
Modal with action
Success Feedback
Action
Feedback
Like/favorite/toggle
Immediate visual state change
Save setting
Inline saved status or subtle toast
Payment/booking/submission
Clear confirmation or receipt
Milestone/first completion
Celebration or dedicated success state
Common Mistakes
Mistake
Fix
Building only happy path
Define loading, success, error, and empty states first
Blank screen while loading
Show skeleton or section-level loading
Spinner flashes under 1 second
Show result directly
Infinite spinner over 10 seconds
Use progress or step indicator
"Something went wrong"
Explain what happened, why, and next action
Raw backend error shown
Map to user-safe message
Toast for critical error
Use inline or modal depending on blocker
Disabled submit with no clue
Mark required fields and explain missing input
Full-page error for one failed card
Isolate section failure and keep rest usable
No confirmation after action
Add feedback matched to action importance
Desktop pattern copied to mobile
Adapt to device reach and mobile norms
All options shown at once
Group, curate, filter, or disclose progressively
Final UX Checklist
Before shipping any UI, verify:
UI and UX both considered: visual design plus understandable behavior.
Loading state exists for every async page, section, and action.
Loader type matches scope and duration.
No spinner appears for work under 1 second.
Text appears for waits over 5 seconds.
Progress or steps appear for waits over 10 seconds.
Success state confirms every user action.
Error messages explain what happened, why, and next action.
No raw backend/database/stack errors are exposed.
No silent failures.
Errors are placed near the cause, unless they block the whole flow.
Empty states explain purpose, reason, and next action.
Search empty states mention the query and offer recovery.
Achievement empty states feel rewarding.
Forms mark required fields and show what is missing.
Forms validate inline and keep errors near fields.
Forms pre-fill known data where possible.
Inputs accept forgiving formats and normalize internally.
Long or complex forms are grouped or split when needed.
Page sections load and fail independently.
Cached content is shown during refresh when available.
Familiar patterns match device, locale, audience, and market norms.
Common controls are standardized; brand expression stays in styling.
Primary action is clear.
Choices are grouped, curated, filtered, or progressively disclosed.
1---2name: build-for-good-ux3description: Use when building, reviewing, or improving user-facing UI, frontend components, pages, forms, flows, loading states, error handling, empty states, success feedback, graceful degradation, familiar layouts, or choice-heavy interfaces.4---56# Build For Good UX78Based on Katherine Gilligan's public "Build For Good UX" series ([@synsation_](https://instagram.com/synsation_)). Use this as an implementation checklist for UI work, not as transcript notes.910## Core Principle1112Good UI is how an app looks. Good UX is whether users understand what to do, what happened, what failed, and how to recover. AI-generated UI often covers only the happy path. Build the full experience.1314Every screen needs these states:1516| State | Required UX |17|---|---|18| Loading | Shows progress appropriate to wait time and scope |19| Success | Confirms the user's action worked |20| Error | Explains what happened, why, and next action |21| Empty | Explains why nothing is there and how to start or continue |2223Good UX builds trust. Bad UX creates uncertainty, extra steps, and friction. Users leave and blame the product, not themselves.2425## Required Workflow2627When building or reviewing a UI, do this before considering the work complete:28291. Identify every user action and async data source.302. Define loading, success, error, and empty states for each relevant screen or section.313. Pick the loader based on scope and duration.324. Place errors next to the thing that caused them unless the issue blocks the whole flow.335. Ensure every action gives visible feedback.346. Make each page section resilient when other sections load slowly or fail.357. Use familiar patterns for the user's device, locale, and audience.368. Reduce choice overload with grouping, curation, filtering, or progressive disclosure.379. Verify the final checklist at the bottom of this file.3839## Loading States4041Missing loaders make users think the app is broken. A blank screen with no response can lose users in 2-3 seconds. Bad loaders can also make the app feel slower.4243### Choose Loader By Context4445| Pattern | Use When | Avoid When |46|---|---|---|47| Skeleton screen | Whole page or large content section loads | Small contained action |48| Progress bar | Duration or progress is knowable | Unknown background wait |49| Inline spinner | Button or small section is working | Whole page load |50| Optimistic UI | Action is very likely to succeed | Failure would be costly or confusing |51| No loader | Work finishes under 1 second | Delay may exceed 1 second |5253### Timing Rules5455| Duration | UX Rule |56|---|---|57| Under 1 second | Show result, no loader. Spinner flash feels slower. |58| 1-2 seconds | Plain spinner is enough. |59| 2-5 seconds | Spinner still works. |60| 5-10 seconds | Add text. Prefer changing text like "Connecting..." then "Almost there...". |61| Over 10 seconds | Replace looped spinner with progress bar or step indicator. |62| On failure | Show error as soon as possible. Do not make users wait then fail. |6364### Skeleton Rules6566- Show page structure first as gray placeholder outlines.67- Match final layout closely so users start processing structure before data arrives.68- Use skeletons for feeds, dashboards, profiles, and content-heavy pages.69- Use inline spinners for buttons or small parts where skeletons do not fit.7071### Optimistic UI Rules7273- Update UI immediately when action is likely to succeed, like a like/favorite/toggle.74- Do not wait for server confirmation before showing the expected result.75- If the server fails, roll back clearly and gracefully.76- Do not use optimistic UI for payments, destructive actions, bookings, or anything where false success creates risk.7778## Error States7980Errors must reduce uncertainty. Never leave users wondering whether an action worked.8182### Error Message Formula8384Good error messages include all three:85861. What happened.872. Why it happened, in user language.883. What the user can do next.8990Bad:9192```text93Something went wrong.94```9596Good:9798```text99Your payment didn't go through. Your card was declined. Check your card details or try a different payment method.100```101102### Error Rules103104- Never dump database, backend, stack trace, or raw exception details into UI.105- Never silently fail. A clicked button must produce feedback.106- Avoid vague messages when user needs certainty.107- Always provide recovery: retry, edit, request access, update payment, or contact support.108- Show errors immediately when known. Do not hide failure behind long loading.109110### Error Placement111112| Placement | Use When | Rules |113|---|---|---|114| Inline | Field-specific errors, button action failure, most forms | Closest to the problem. Use red border plus message. |115| Toast | Non-critical, recoverable status | Auto-dismiss only if user can miss it without harm. Example: "Couldn't connect, retrying..." |116| Modal | Critical blocker requiring user action | Blocks flow. Must include clear next action. Use sparingly. |117118If blocking the user with a modal, provide a way forward.119120## Form UX121122Forms create friction. Reduce effort, uncertainty, and rework.123124### Form Rules1251261. Disable submit until required fields are valid, but explain what is missing.1272. Mark required fields clearly so users are never guessing why submit is disabled.1283. Validate inline when users leave a field, not only after submit.1294. Keep validation messages near the field, not at the top of the page.1305. Show character counts for limited fields.1316. Pre-fill known values, such as logged-in user's email.1327. Show password requirements while typing and check them off live.1338. Accept forgiving formats, such as phone numbers with spaces, dashes, parentheses, or no formatting. Normalize in code.1349. For forms with more than seven fields, consider splitting into multiple steps or sections.135136### Form Mistakes To Avoid137138- Disabled button with no explanation.139- Submit, wait, then scroll to find errors.140- Rejecting user input because formatting differs from preferred display format.141- Making users type data the app already knows.142- Showing all fields at once when the form feels like a wall.143144## Empty States145146Empty states are often first impressions. Do not leave blank areas or dead ends.147148### Empty State Rules149150- Explain what the area is for.151- Explain why it is empty.152- Provide a clear next action.153- Add guidance, steps, or onboarding when helpful.154- Handle every empty section, not only the page-level state.155156### Empty Search Results157158- "No results" is acceptable but weak.159- "No results for purple shoes" is better because it confirms the query.160- Offer an action: clear filters, try a broader search, or search the same term elsewhere if relevant.161162### Goal Empty States163164When emptiness is success, celebrate it:165166- Inbox zero.167- No open tasks.168- All steps complete.169170Use subtle delight, animation, or visual reward so the state feels achieved, not broken.171172## Partial Loading And Graceful Degradation173174Pages are made of sections backed by different data sources. Each section should load, fail, and recover independently.175176### Rules177178- Load what is available instead of waiting for everything.179- Give each section its own loading state, error state, and retry action.180- If one section fails, keep the rest of the page usable.181- Show cached content while fresh data loads when available.182- Think through mixed states: some sections loaded, some loading, some failed, some stale.183184### Implementation Pattern185186```text187Page188|-- Profile section: own data, loader, error, retry189|-- Feed section: own data, loader, error, retry190|-- Sidebar section: own data, loader, error, retry191`-- Charts section: own data, loader, error, retry192```193194### Avoid195196- Full-page loading screen until every component is ready.197- Full-page error because one API call failed.198- One failed section taking down the whole page.199- Hiding cached or stale-but-useful content during refresh.200201## Success States202203Users need to know their action worked. Missing success feedback creates anxiety and repeated actions.204205### Success Feedback Rules206207- Always close the loop after user action.208- Match feedback intensity to importance.209- Use subtle feedback for small actions like likes, toggles, or saved settings.210- Use clear confirmation for high-stakes actions like payment, booking, or submission.211- Use celebration for milestones like first project, major task completion, or achievement.212- Sometimes the changed state is confirmation, like a card moving from "To do" to "Done" and staying there.213214### Avoid215216- No feedback after critical action.217- Over-celebrating routine actions.218- Full-page success for actions that only need inline confirmation.219- Leaving users unsure whether they should click again.220221## Familiar Patterns And Jakob's Law222223Users spend most of their time in other apps. They expect yours to follow patterns they already know. Predictable structure lets users focus on their goal instead of relearning basics.224225### Rules226227- Standardize placement for common components: navigation, search, cart, checkout, form patterns, account controls.228- Apply standards for the user's context, not a generic desktop default.229- Desktop web patterns differ from mobile patterns.230- Mobile layouts must account for thumb reach. Important actions often belong near the bottom.231- Locale matters. Right-to-left experiences may mirror placement, such as cart moving from top right to top left.232- Audience and market norms matter. Follow the pattern users in that context already know.233- Keep structure familiar while making visual design distinct.234235### Standardize Vs Customize236237| Standardize | Customize |238|---|---|239| Navigation placement | Brand color and typography |240| Cart and checkout flow | Illustration style |241| Search placement | Motion and microinteractions |242| Form layout conventions | Tone and copy |243| Error/success placement | Visual personality |244245Creative placement of common controls creates friction. Creative styling of familiar structure creates personality without confusion.246247## Hick's Law And Choice Complexity248249Decision time increases as choices increase in number and complexity. Good UX keeps visible options manageable without removing capability.250251### Rules252253- Prioritize one clear primary action per screen or step.254- Reduce competing calls to action.255- Group related options.256- Curate defaults or recommendations instead of showing everything.257- Use filters, search, and categories to help users narrow options.258- Use progressive disclosure: show the next useful choice when it becomes relevant.259- Break large forms into pages, steps, or sections when field count and complexity become overwhelming.260- Consider multi-step forms when there are more than seven fields.261262### Examples263264- Google focuses the homepage on one action: search.265- Cluttered portals create unnecessary competing choices.266- Netflix has thousands of titles but shows curated rows and recommendations first.267- A long menu can show key options first, then let users search, filter, or expand.268269### Avoid270271- Showing every option on the first screen.272- Making secondary actions compete with the primary action.273- Hiding needed options so deeply users cannot recover them.274- Treating choice reduction as removing power. It should reduce overload while preserving access.275276## Quick Decision Tables277278### Loader Choice279280| Situation | Use |281|---|---|282| Whole page or feed loading | Skeleton |283| File upload/download/install | Progress bar |284| Button click or small section refresh | Inline spinner |285| Like, favorite, low-risk toggle | Optimistic UI |286| Under 1 second | No loader |287288### Error Placement289290| Situation | Use |291|---|---|292| Invalid field | Inline field error |293| Button action failed | Inline near button |294| Non-critical background issue | Toast |295| Payment, permission, or blocker | Modal with action |296297### Success Feedback298299| Action | Feedback |300|---|---|301| Like/favorite/toggle | Immediate visual state change |302| Save setting | Inline saved status or subtle toast |303| Payment/booking/submission | Clear confirmation or receipt |304| Milestone/first completion | Celebration or dedicated success state |305306## Common Mistakes307308| Mistake | Fix |309|---|---|310| Building only happy path | Define loading, success, error, and empty states first |311| Blank screen while loading | Show skeleton or section-level loading |312| Spinner flashes under 1 second | Show result directly |313| Infinite spinner over 10 seconds | Use progress or step indicator |314| "Something went wrong" | Explain what happened, why, and next action |315| Raw backend error shown | Map to user-safe message |316| Toast for critical error | Use inline or modal depending on blocker |317| Disabled submit with no clue | Mark required fields and explain missing input |318| Full-page error for one failed card | Isolate section failure and keep rest usable |319| No confirmation after action | Add feedback matched to action importance |320| Desktop pattern copied to mobile | Adapt to device reach and mobile norms |321| All options shown at once | Group, curate, filter, or disclose progressively |322323## Final UX Checklist324325Before shipping any UI, verify:326327- [ ] UI and UX both considered: visual design plus understandable behavior.328- [ ] Loading state exists for every async page, section, and action.329- [ ] Loader type matches scope and duration.330- [ ] No spinner appears for work under 1 second.331- [ ] Text appears for waits over 5 seconds.332- [ ] Progress or steps appear for waits over 10 seconds.333- [ ] Success state confirms every user action.334- [ ] Error messages explain what happened, why, and next action.335- [ ] No raw backend/database/stack errors are exposed.336- [ ] No silent failures.337- [ ] Errors are placed near the cause, unless they block the whole flow.338- [ ] Empty states explain purpose, reason, and next action.339- [ ] Search empty states mention the query and offer recovery.340- [ ] Achievement empty states feel rewarding.341- [ ] Forms mark required fields and show what is missing.342- [ ] Forms validate inline and keep errors near fields.343- [ ] Forms pre-fill known data where possible.344- [ ] Inputs accept forgiving formats and normalize internally.345- [ ] Long or complex forms are grouped or split when needed.346- [ ] Page sections load and fail independently.347- [ ] Cached content is shown during refresh when available.348- [ ] Familiar patterns match device, locale, audience, and market norms.349- [ ] Common controls are standardized; brand expression stays in styling.350- [ ] Primary action is clear.351- [ ] Choices are grouped, curated, filtered, or progressively disclosed.
Run npx skillmds@latest add alper-dev/build-for-good-ux in your terminal (requires Node.js), paste this page's agent-chat prompt into Claude, Cursor, or any MCP-connected agent, or download the SKILL.md file and copy it into your agent's skills directory.
Use when building, reviewing, or improving user-facing UI, frontend components, pages, forms, flows, loading states, error handling, empty states, success feedback, graceful degradation, familiar layouts, or choice-heavy interfaces. It is listed under Web & Frontend on SkillMD.
This skill has not completed SkillMD's automated safety review yet. SkillMD never runs a skill's scripts for you; review the SKILL.md before installing.
This skill is tagged as working with Claude Code, Claude.ai, OpenAI Codex. SKILL.md is an open format, so most agents that read a skills directory can load it too.
Yes. Installing skills from SkillMD is free, and the skill stays under its author's original license.
alper-dev (@alper-dev) published this skill. Their other Agent Skills are listed on their SkillMD profile.