| name | unhappypath |
| description | Run the unhappypath CLI to find missing loading, empty, error, and retry UI states, then fix findings and re-run until the score target is met. |
unhappypath
What this skill does
Runs the unhappypath scanner — a deterministic CLI that finds missing unhappy-path UI in Next.js/React apps:
- Loading — user sees blank screen while data fetches
- Empty — list renders nothing with no explanation or CTA
- Error — API failure shows no message or retry
- Pending — buttons/forms allow double-submit
It does not run the browser or call an LLM. It reads source files and reports findings with file + line + rule ID.
Prerequisites
Install or build unhappypath once:
npx unhappypath --help
git clone https://github.com/paladini/unhappypath.git
cd unhappypath && npm ci && npm run build
Workflow (follow exactly)
-
Scan from the user's app root (where package.json is):
npx unhappypath .
-
Parse output — note score, band, and every finding (RTE-*, QRY-*, MUT-*, FRM-*).
-
Fix in priority order:
- Routes (
RTE-*) — add loading.tsx, error.tsx, not-found.tsx, global-error.tsx
- Queries (
QRY-*) — add if (isLoading), if (isError), empty-data branches
- Mutations (
MUT-*) — disable buttons while pending; never use empty catch {}
- Forms (
FRM-*) — wire isSubmitting / disabled submit
-
Re-run until score ≥ target (default 75, production 90):
npx unhappypath . --min-score 75
-
Report final score and list any remaining findings.
Fix recipes
| ID | Fix |
|---|
| RTE-01 | Add loading.tsx in route segment or parent app/ |
| RTE-02 | Add not-found.tsx; use notFound() for missing resources |
| RTE-03 | Add 'use client' error.tsx with reset() retry button |
| RTE-04 | Add app/global-error.tsx |
| QRY-01 | if (isLoading) return <Loading /> |
| QRY-02 | if (isError) return <ErrorUI error={error} onRetry={refetch} /> |
| QRY-03 | if (!data?.length) return <EmptyState /> |
| MUT-02 | disabled={pending} + pending state around async handler |
| FRM-01 | disabled={isSubmitting} on submit button |
Full catalog: https://github.com/paladini/unhappypath/blob/main/docs/FINDINGS.md
Rules
- Always run the CLI — never substitute an LLM-based code review for unhappypath.
- Prefer minimal diffs in flagged files unless a shared wrapper (e.g.
<UIStates>) is clearly better.
- Prefer skeletons over spinners for loading; always offer retry on errors.
- If a finding looks like a false positive, note the ID and explain why — do not silently ignore.