Skip to main content
AC
Build & Implementation5.1 KBMIT licensed

frontend-ui-engineering

Rewritten from patterns in addyosmani/agent-skills (MIT)

Build production-quality UI: components, layouts, state, accessibility, and polish that does not look AI-generated. Use when building or modifying user-facing interfaces, creating components, implementing responsive layouts, or fixing visual and UX issues. Not for commit and branch discipline around the change: use git-workflow-and-versioning. Not for pure design review without code.

  • frontend
  • engineering

SKILL.md

Frontend UI Engineering

Ship UI that looks like a design-aware engineer built it: real design system adherence, WCAG 2.1 AA accessibility, all four states handled (loading, error, empty, success). The recognizable "AI aesthetic" is a quality signal, and the signal says low.

Workflow

  1. Learn the project's system first. Find the spacing scale, color tokens, radius scale, and type hierarchy before writing a component. No design system: use a 0.25rem spacing scale, semantic tokens, and restraint.
  2. Structure the component. Colocate component, test, hook, and types in one directory. Composition over configuration: children and slots beat a dozen props. Split anything past ~200 lines. Separate data fetching (container) from rendering (presentation). Read references/patterns.md when you need the code patterns for composition, container/presentation, focus management, or optimistic updates.
  3. Pick the simplest state tool that works. useState for local UI, lifted state for 2-3 siblings, context for read-heavy globals (theme, auth), URL params for shareable state (filters, pagination), React Query/SWR for server data, a global store only for complex app-wide client state. Prop drilling past 3 levels means restructure.
  4. Handle all four states. Every data-driven view renders loading (skeleton, not spinner), error (message plus retry), empty (guidance plus action), and success. A blank screen in any state is a bug.
  5. Build accessibility in. Native elements first (<button>, not <div onClick>). Label every icon-only control and every input. Move focus on dialogs and route changes, trap it in modals. Contrast 4.5:1 normal text, 3:1 large. Never color as the only signal.
  6. Make it responsive mobile-first. Base styles for 320px, expand with breakpoints. Test at 320, 768, 1024, 1440.
  7. Kill the AI aesthetic. Checklist of defaults to reject: purple/indigo palette, gradients everywhere, rounded-2xl on everything, generic hero sections, lorem ipsum copy, uniform oversized padding, stock card grids, layered shadows. Replace each with the project's actual system and content-first layout.

Good vs bad

Bad: A dashboard card grid: every card rounded-2xl shadow-xl p-8, indigo gradient header, spinner while loading, blank div when the list is empty, <div onClick> for the row actions.

Good: Cards use the project's radius and spacing tokens, the grid prioritizes the two metrics users scan first, loading renders a skeleton matching final layout, empty state says "No tasks yet" with a create button, rows are real buttons reachable by Tab.

Verification

Do this pass on the finished UI. Tab through the entire page: every interactive element receives visible focus and activates with Enter/Space. Run axe-core (or the browser a11y devtools) and resize to 320px. Expect: zero console errors, zero axe violations, no horizontal scroll at 320px, and all four states reachable. Any failure: fix it before handing off, "works with a mouse at 1440px" is not done.

Completion checklist

  • [ ] Project design tokens used, no invented spacing or raw hex values
  • [ ] Component colocated, under ~200 lines, composition-based
  • [ ] State managed with the simplest sufficient tool
  • [ ] Loading, error, empty, success all implemented
  • [ ] Keyboard pass clean, labels on all unlabeled controls
  • [ ] Contrast and non-color signals verified
  • [ ] Works at 320, 768, 1024, 1440
  • [ ] No AI-aesthetic defaults present

Any box unchecked: not done. Fix or say so.

Red flags

Verbatim rationalizations that precede low-quality UI:

  • "Accessibility is a nice-to-have for now"
  • "We'll make it responsive later"
  • "This is just a prototype"
  • "The design isn't final, so styling can wait"
  • "The AI look is fine for a first pass"

Closure rule: prototypes become production. If the code will be seen by a user or a reviewer, the standards above apply to it now, not later.

Footguns

  • Spinner-for-everything loading. Spinners cause layout shift and hide structure. Fix: skeletons that match the final layout, aria-busy on the container.
  • Div soup interactivity. <div onClick> is invisible to keyboards and screen readers. Fix: native <button>/<a>; if forced, add role, tabIndex, and both Enter and Space handling.
  • Arbitrary values. padding: 13px and #7c3aed scattered around defeat the system. Fix: tokens and scale values only; an arbitrary value is a signal you skipped step 1.
  • Optimistic updates without rollback. UI updates, request fails, state lies. Fix: snapshot previous state in onMutate, restore it in onError (pattern in references/patterns.md).

Reference files

More in Build & Implementation

All skills