frontend-ui-reviewer
Skill1 starsChanged 2 months agoMITView on GitHub
Reviews user-facing UI code (React, Vue, Svelte, HTML/CSS): traces keyboard and screen-reader paths, checks every UI state, responsive layout, Core Web Vitals, forms and design tokens, then ranks P0-P3 findings with fixes. Use when asked to review a component, screen, modal, dialog or form UI before it ships, do an accessibility or a11y check, WCAG contrast, keyboard or focus support, mobile layout, layout shift or bundle size, or when building frontend UI in a rush ("just make the form work, skip the a11y"). Do not use for a backend or API diff with no UI (use production-code-review), or building and shipping a whole feature (use feature-to-production).
In this repository14 other files it gives its agents.
- data-scientistSkill
- debugging-investigatorSkill
- deploy-pipeline-reviewerSkill
- feature-to-productionSkill
- incident-responderSkill
- production-code-reviewSkill
- product-managerSkill
- repo-architectSkill
- research-to-decisionSkill
- security-auditorSkill
- spec-and-planSkill
- system-design-reviewerSkill
- test-first-developerSkill
- threat-modelerSkill
The file
We split this skill into the rules it gives an agent
9 rules. About 0 are common, 4 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 75
Check names and semantics: Every input has a <label> or aria-label/aria-labelledby — placeholder is not a label.
- Very specific: line 89
Check responsiveness and visuals: Look for fixed pixel widths and heights on containers, missing max-width, horizontal overflow, touch …
- Very specific: line 101
Verify: If a browser or runner exists, tab through the UI, run axe (@axe-core/playwright, jest-axe, or the browser extension), and resize …
- Very specific: line 125
Write UI_REVIEW.md with these sections, in order:
- Distinctive: line 155
Stop and correct course if any of these are true:
- Distinctive: line 158
Every finding concerns the success render.
- Distinctive: line 190
Canvas, maps, video or charts: check the surrounding controls and text alternatives.
- Very specific: line 192
Server-rendered or no-JS HTML: check that forms and links work before hydration.
- Distinctive: line 194
Asked to fix, not just review: write the review first, then apply the fixes and re-run the keyboard trace and any automated check.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Purpose
Catch the UI defects generic code review walks past: controls a keyboard cannot reach, fields a screen reader cannot name, states nobody designed, layouts that break at 390px, and markup that shifts or bloats the page. Each finding names who it hurts and how to fix it, and the report says plainly what was verified in a browser and what was only read.
When to use
- A component, page, modal or form is about to ship and someone asks for a review, a "quick look", or "is this ready".
- Asked about accessibility, a11y, WCAG, contrast, keyboard or screen-reader support, mobile or responsive layout, layout shift, or bundle weight.
- Building UI yourself: run the workflow on your own output before handing it back, especially when the request says to skip the polish.
- As the UI pass inside
feature-to-productionor alongsideproduction-code-reviewon a diff that touches JSX, templates or CSS.
When NOT to use
- The diff has no user-facing surface (API handler, migration, worker) —
use
production-code-review. - The task is building and shipping a whole feature end to end — use
feature-to-production; it calls this skill for its UI stage. - A conceptual question ("flexbox vs grid", "what is ARIA") with no code to review — answer it directly.
- Pure visual-design critique (palette, typography taste) with no defect — say so; this skill reports defects, not preferences.
Required inputs
- The UI files: components, templates, styles, and the design-token file if one exists.
- Context: who uses it, the main devices or viewport widths, and the framework. If unstated, assume mobile and keyboard users exist and say so.
- Optional: a running dev server, Storybook, or test runner for verification.
Workflow
- Scope. List the files reviewed, the framework, and the entry point (what opens or renders this UI). Note whether a browser or test runner is available; that decides what step 9 can verify.
- Inventory interactive elements. For every element with an event
handler, record its tag. A
div/spanwithonClickand no role,tabIndexand key handler is a keyboard dead end. Anything that navigates should be<a href>; anything that acts should be<button>. - Trace the keyboard path. Walk Tab order through the UI in source
order: can every control be reached, is focus visible (no
outline: nonewithout a replacement), and does Enter/Space activate it? For dialogs: focus moves in on open, Tab is trapped inside, Escape closes, focus returns to the trigger on close, and the dialog hasrole="dialog",aria-modaland an accessible name. - Check names and semantics. Every input has a
<label>oraria-label/aria-labelledby— placeholder is not a label. Every meaningful image hasalttext; decorative ones havealt="". Headings are in order. ARIA is only added where native HTML can't do the job; anaria-*attribute that contradicts the element is a defect, not a fix. - Enumerate UI states. For each async action or data source, find the
code for loading, empty, error, partial, and disabled/submitting. Missing
submitting state means double-submit; an error path that resets state
means the user retypes everything. Async results and errors must be
announced (
role="alert",aria-live, or focus moved to the message). - Check forms. Errors are tied to their field (
aria-describedby,aria-invalid), input survives a failed submit, the submit is a realtype="submit"so Enter works, and fields carryautocomplete,inputModeand the righttype. - Check responsiveness and visuals. Look for fixed pixel widths and
heights on containers, missing
max-width, horizontal overflow, touch targets under 24x24 CSS px (44x44 preferred), and text colors. Compute contrast for every text/background pair you can resolve: 4.5:1 for normal text, 3:1 for large text and UI component boundaries (WCAG AA). - Check performance and consistency. Images without
width/height(oraspect-ratio) cause layout shift; below-the-fold images needloading="lazy". Whole-library imports for one helper (lodash,moment) bloat the bundle. Look for expensive work in render on hot paths and inline objects that defeat memoization. Hard-coded colors and spacing next to existing tokens, and re-implemented components, are consistency findings. - Verify. If a browser or runner exists, tab through the UI, run axe
(
@axe-core/playwright,jest-axe, or the browser extension), and resize to 320px and 390px. Otherwise state exactly which checks were static, and list what needs a browser or a screen reader. - Rank and write. Rank P0-P3 by who is blocked and how badly, give
each finding file:line, evidence, affected users and a concrete fix, then
write
UI_REVIEW.md. Do not edit source unless asked.
Tool & resource guidance
- For dialogs, buttons vs links, labels, live regions and ARIA misuse, read
references/accessibility-patterns.md; it has the fix code for each. - For loading/empty/error/submitting states and form behavior, read
references/ui-states-and-forms.md. - For layout shift, bundle weight, render cost and lazy loading, read
references/web-vitals-in-components.md. - Grep for
onClick=on non-button tags,outline: none,placeholder=,<img, hex colors,pxwidths and whole-library imports to seed the inventory, then read each hit in context. - Resolve CSS variables to real values before computing contrast; a token name is not a color.
Output contract
Write UI_REVIEW.md with these sections, in order:
- Verdict — ship / ship after P0-P1 fixes / do not ship, in one line, plus the count of findings by severity.
- Scope — files, framework, entry point, assumed users and viewports, and whether a browser or test runner was used.
- Findings — a table: ID, severity, dimension (a11y, states, responsive, performance, forms, consistency), title, file:line, affected users.
- Finding details — per finding: evidence (quoted code), user impact naming who is affected, the fix as code or a precise change, and how to verify it.
- Checked and fine — things that were examined and are correct, so the reader knows they were not skipped.
- Needs manual or browser verification — what static reading could not settle (screen-reader announcements, real contrast over images, zoom).
Quality checks
- Every interactive element was inventoried and its keyboard path traced.
- Every finding has file:line, quoted evidence, affected users and a fix.
- Each async action was checked for loading, error, empty and submitting states, not only the success render.
- Contrast claims cite the two resolved colors and the ratio.
- Correct patterns (decorative
alt="", labelled checkbox) appear under "Checked and fine", not as findings. - The verdict matches the severities: no "ship" with an open P0.
- Static-only checks are labelled as such.
Red flags
Stop and correct course if any of these are true:
- You are about to approve and cannot list the Tab order through the UI.
- Every finding concerns the success render; no line mentions what the user sees while the request is in flight or after it fails.
- You called a control accessible because it has an
aria-*attribute, without checking it has a role, a name and keyboard handling. - A finding says "low contrast" with no colors or ratio.
- A finding is a preference (rounder corners, another font) filed as P1-P2.
- You flagged
alt=""on a decorative image, or a<label htmlFor>pair, as missing accessibility. - You wrote "verified" for something you only read.
Common rationalizations
Excuses that come up for skipping this workflow, and why they don't hold:
| Rationalization | Reality |
| "It's an internal tool, accessibility doesn't matter." | Internal users include keyboard-only users, screen-reader users and people with injuries. Public-sector and enterprise buyers also audit internal tools. |
| "The design system handles that." | Only if the component uses it. A div styled to look like the system's button inherits none of its semantics or focus handling. Check the code in front of you. |
| "We'll add loading states later." | A missing submitting state on a payment button is a double charge today. States are part of the feature, not polish. |
| "It looks fine on my screen." | Your screen is wide, fast and mouse-driven. Most users are on a 390px phone, some on a slow network, some with no mouse. |
| "It has aria-label, so it's accessible." | A name on an element that can't take focus or respond to Enter is still unusable. ARIA describes behavior; it doesn't add it. |
| "axe passed, so we're done." | Automated checks catch roughly a third of WCAG issues. They can't tell you focus returns to the trigger or that an error is announced. |
| "The user said skip the a11y and just make it work." | Then keep the review short, not absent: a control the keyboard can't reach doesn't work. Flag P0s; defer P3s. |
Edge cases
- Component library in use (MUI, Radix, Headless UI): check it is used
as documented — a Radix
DialogwithoutDialog.Titlestill lacks a name. - Only a diff is available: review the changed UI, read the parent and styles it depends on, and list unread context under manual verification.
- Colors from variables you can't resolve (theme at runtime): mark the contrast check as needing browser verification rather than guessing.
- Canvas, maps, video or charts: check the surrounding controls and text alternatives; note the inner widget as needing manual testing.
- Server-rendered or no-JS HTML: check that forms and links work before
hydration; a
div onClickdoes nothing until JS loads. - Asked to fix, not just review: write the review first, then apply the fixes and re-run the keyboard trace and any automated check.
References
references/accessibility-patterns.md— dialog focus management, button vs link, labels, live regions, ARIA misuse, contrast, with fix code.references/ui-states-and-forms.md— the state checklist and form behavior, with fix code.references/web-vitals-in-components.md— CLS, LCP and INP causes in component code and their fixes.examples/settings-drawer-review.md— a full workedUI_REVIEW.mdfor a Vue account-settings drawer.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

