How do you architect a scalable, consistent UI system?
UI Engineer
answer
A production UI system starts with a tokenized design language, a governed component library, and documented interaction patterns. Organize primitives (color, type, spacing, motion) as tokens, expose stable component APIs, and encode accessibility by default. Keep logic in hooks/services; keep views thin. Share utilities, icons, and layouts via versioned packages. Enforce linting, Storybook docs, visual tests, and CI gates so multiple apps ship consistent UI without copy-paste.
Long Answer
A large-scale UI system is a product, not a toolbox. Its job is to encode decisions once and multiply them across teams with predictable quality. The architecture aligns four layers: foundations (design tokens), components (primitives and patterns), application shells (layouts, navigation, theming), and governance (versioning, review, telemetry). Each layer is explicit and independently evolvable.
1) Foundations: tokens and theming
Define tokens for color, type, spacing, radius, elevation, and motion. Keep tokens in a single source of truth and emit artifacts (CSS variables, native formats). Support light/dark and brand variants via theme objects, not ad-hoc overrides. Enforce contrast and motion policies, including reduced-motion and high-contrast modes.
2) Components: accessible and stable
Build an audited library in Storybook. Ship accessible names/roles, keyboard support, focus management, and ARIA only when semantics are not native. Standardize APIs (controlled/uncontrolled, event names, slots). Provide typings, usage examples, and migration notes.
3) Patterns: forms, navigation, feedback
Codify patterns—forms and validation, master-detail, empty states, progress indicators—so teams assemble screens without inventing UX. Patterns reference tokens and components to keep spacing and motion coherent.
4) Data and side effects
Keep components presentational. Move fetch/cache/mutation into composables or services (useQuery, useMutation) with retry, cancellation, optimistic updates, and error translation. Apps may choose REST/GraphQL without forking UI.
5) Layouts, routing, and responsiveness
Ship shells: top-nav, side-nav, and workspace layouts with responsive breakpoints. Use grid/flex utilities bound to tokens and container queries where supported. Provide route-aware links and skeleton loaders to sustain speed.
6) Performance and delivery
Set budgets for interactivity. Tree-shake, code-split heavy widgets, lazy-load icons, and prefetch on intent. Animate transform/opacity, not layout. Offer SSR/ISR adapters and hydration controls. Track Core Web Vitals and block regressions in CI.
7) Documentation and discovery
Document purpose, do/do not, props, states, accessibility notes, and live code. Map Figma ↔ code and preview tokens.
8) Governance and evolution
Release with semver; require RFCs for breaking APIs; ship codemods. Lint token usage and accessibility; run visual regression and contract tests. Telemetry reports component usage and version mix to guide deprecations.
9) Multi-app distribution
Publish as versioned packages in a monorepo or registry. Support extension points and theming hooks so teams add variants without forks.
Designed this way, the UI system scales across modules and apps while staying maintainable: teams compose from stable parts, upgrades are assisted, and users experience consistent, accessible interfaces that perform well.
Table
Common Mistakes
Organizing code by technical type instead of domains, scattering intent. Treating the library as a parts bin with inconsistent props and events, so reuse collapses. Shipping custom widgets without roles, focus, or keyboard support. Letting tokens drift from code and Figma; no single source of truth. Overloading the global store instead of local state; coupling unrelated screens. Fetching data inside components without retry/cancel, making tests brittle. Skipping route-level code splitting; shipping megabundles. Animating layout properties and causing jank. Lacking semver, RFCs, or codemods, so upgrades break apps. Thin docs and no Storybook, leaving teams to guess. No visual or contract tests; regressions sneak in. Ignoring reduced-motion and contrast policies. CPU-only perf budgets with no Core Web Vitals gates. Missing ownership and support channels; issues pile up. Treating patterns as documentation only, not code, so designs and runtime drift apart.
Sample Answers
Junior:
I would follow a shared component library and tokens for color, spacing, and type. I would keep components focused on rendering and move data fetching to small hooks so they are easy to test. I would check accessibility (roles, labels, focus order) and document props in Storybook before merging.
Mid:
I organize the app by domain and import a versioned @ui package with accessible components and patterns. Tokens flow from a single source into CSS variables. I add route-level code splitting, adopt useQuery/useMutation for data, and enforce linting, unit tests, and visual tests in CI. The result is consistent views and predictable builds.
Senior:
I treat the UI system as a product: semver releases, RFCs for breaking changes, and codemods. I set performance and accessibility budgets, track Core Web Vitals, and gate deployments. Extensions happen through theming hooks and slots, not forks. Telemetry shows component usage and version drift so we can deprecate safely and keep apps aligned.
Evaluation Criteria
Strong answers treat the UI system as layered: tokens → components → patterns → app shells → governance. Look for a single source of truth for tokens, accessible components with stable APIs, and codified patterns for forms, navigation, and feedback. Candidates should separate presentation from data via hooks/services, mention route-level code splitting and performance budgets, and plan for SSR/ISR where needed. Testing must include Storybook documentation, accessibility linting, visual regression, and contract tests for events. Governance signals seniority: semver, RFCs, codemods, and deprecation telemetry. Distribution across apps should happen via versioned packages with theming hooks and extension points, not forks. Red flags: global state everywhere, tokens duplicated in code and design, JS-only widgets with poor semantics, CPU-only autoscaling of performance, and no plan for migration. Bonus: service catalog, ownership model, and dashboards tying Core Web Vitals to releases. Expect explicit accessibility support for reduced motion and high contrast across themes.
Preparation Tips
Create a small multi-app sandbox (web-admin + web-shop) that imports a shared @ui package. Define tokens in JSON and generate CSS variables; wire light/dark themes. Build five accessible components (Button, Input, Dialog, Toast, Combobox) with Storybook docs and keyboard tests. Codify two patterns: validated forms and master-detail. Add a data layer with useQuery/useMutation, retry with backoff, cancellation, and optimistic updates. Enable route-level code splitting and SSR/ISR on two pages. Set budgets for bundle size and interaction latency; track Core Web Vitals. Integrate ESLint accessibility rules, visual regression, and contract tests for events; block PRs on failures. Publish the library with semver and write one RFC plus a codemod for a breaking prop rename. Add a service catalog entry with owners, changelog, and support channel. Run a quick review of focus order, reduced-motion, contrast, and error copy; log gaps as tickets linked to tokens, components, or patterns. Share dashboards for Web Vitals and release health to close the loop with each iteration.
Real-world Context
A marketplace centralized tokens and a component library; brand refreshes rolled out to four apps in two days and UI inconsistencies dropped. A fintech moved fetch logic into hooks and codified form patterns; validation errors fell and support tickets declined. A media platform added route-level splitting and lazy icons; first interaction improved while keeping visual parity. A SaaS vendor adopted semver releases with codemods; teams upgraded the UI package without breakage, and velocity increased. A government portal standardized accessible components and navigation patterns; keyboard success rates rose and reported barriers decreased. A global retailer introduced theming hooks and extension points; regional teams customized surfaces without forking. Observability tied component versions to Core Web Vitals; a regression in Dialog focus was caught within hours and fixed in one patch release. Across these cases, treating the UI system as a product delivered consistency, scalability, and confidence.
Key Takeaways
- Treat the UI system as a layered, versioned product.
- Encode decisions as tokens; ship accessible, stable components.
- Codify patterns and responsive shells for fast assembly.
- Separate presentation from data; budget performance and test.
- Govern with semver, RFCs, codemods, and telemetry.
Practice Exercise
Scenario:
You must stand up a shared UI system for three web applications (admin, customer, partner). Leadership demands visual consistency, fast iteration, and accessibility by default. The first pilot ships in four weeks.
Tasks:
- Foundations: define tokens (color, type, spacing, radius, motion) in JSON and generate CSS variables; create light/dark themes with contrast and reduced-motion policies.
- Library: implement five primitives (Button, Input, Select, Dialog, Toast) and one composite (Combobox) with roles, focus traps, keyboard support, and docs in Storybook; add prop/event contracts.
- Patterns: build two form templates (simple/stepped), a master-detail view, and empty/error states tied to tokens.
- Data layer: add useQuery/useMutation with retry, cancel, optimistic updates, and typed errors; keep components presentational.
- Delivery: route-level code splitting, lazy icons, SSR/ISR adapter; set budgets for bundle size and interaction latency; add visual regression and contract tests to CI.
- Governance: publish as a versioned package; write one RFC and ship a codemod for a breaking rename; add telemetry for component usage and version drift.
- Adoption: integrate the library in all three apps; replace one legacy screen per app using patterns; collect Web Vitals and task-success baselines.
Deliverable:
A concise runbook with the token table, component and pattern inventory, CI gates, dashboards, and a risk list with owners and dates. Include screenshots of before/after flows to demonstrate consistency and latency gains.

