Skip to content
Development
Skill

/build-for-good-ux-skill

Audit, build, or refactor frontend UI components, pages, forms, and interactive flows to implement complete UX states (loading, success, error, empty), resilient async degradation, accessible button interactions, error recovery, Fitts's Law mobile touch targets, and choice

From plugin
build-for-good-ux-skill
181 skill

Claude Code

$ npx -y skills add alper-dev/build-for-good-ux-skill --skill build-for-good-ux-skill --agent claude-code

SKILL.md

build-for-good-ux-skill.SKILL.md
name: build-for-good-ux
description: Audit, build, or refactor frontend UI components, pages, forms, and interactive flows to implement complete UX states (loading, success, error, empty), resilient async degradation, accessible button interactions, error recovery, Fitts's Law mobile touch targets, and choice simplification. Use when creating or reviewing user-facing interfaces, form validations, multi-section dashboards, checkout flows, or gesture-sensitive mobile screens.

Build For Good UX

Based 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.

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:

1. Identify every user action and async data source. 2. Define loading, success, error, and empty states for each relevant screen or section. 3. Pick the loader based on scope and duration; place loaders inside action buttons when scoped to that trigger. 4. Place errors next to the thing that caused them unless the issue blocks the whole flow. 5. Ensure every action gives visible or tactile feedback across all button states (default, hover, focus, pressed, loading, disabled; see [Button States And Accessibility](#button-states-and-accessibility)). 6. Decide whether to keep submit enabled with focused error jump instead of disabled button traps. 7. Make each page section resilient when other sections load slowly or fail. 8. Apply Tesler's Law: absorb complexity in code and system design rather than offloading it to users. 9. Use familiar patterns for the user's device, locale, and audience (Jakob's Law). 10. Respect Fitts's Law: optimize tap target sizes, invisible hit padding, thumb reach, and resolve scroll-vs-tap gesture conflicts. 11. Reduce choice overload with grouping, curation, filtering, or progressive disclosure without hiding core discoverability. 12. 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:

1. What happened. 2. Why it happened, in user language. 3. 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

1. Apply the disabled-button decision rule below; default to keeping sub

Read more
Stats
18
Stars
1
Forks
Maintained
Maintenance
Apache-2.0
License
Last commit
Created

Repo: alper-dev/build-for-good-ux-skill

@alper-dev
Ships withbuild-for-good-ux-skill

Agent skill for building UIs with proper loading states, error handling, empty states, form UX, and graceful degradation

Stars on GitHub

Momentum

stars in total
18
Star history of alper-dev/build-for-good-ux-skill on GitHub, a chart by star-history.com

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills2w309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc2w293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react5d252k
@facebook@facebookInstall Skill

Questions about build-for-good-ux-skill.

Which coding agents can use build-for-good-ux-skill?
build-for-good-ux-skill installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.