Skip to main content

Design systems engineer role-specific interview questions

30 questions on role-specific for design systems engineer candidates. Expect prompts such as “How do you structure a multi-tier design token system?” and “How does CSS custom property inheritance affect theming at scale?”, each with a worked answer outline and the follow-ups interviewers push on.

Questions

Showing 1 to 25 of 30 role-specific questions (page 1 of 2).

As asked

Walk me through how you would architect a three-tier design token system, from primitive tokens through semantic tokens to component tokens. What naming conventions do you enforce, and how do you decide which layer a given value lives in?

Sample answer outline

Strong answers distinguish primitives (raw values like color-blue-500), semantics (purpose-bound aliases like color-action-primary), and component tokens (component-button-background-default). The candidate should explain that consumers should almost never reference primitives directly, that semantic aliases allow theming without touching component definitions, and that component tokens give component authors an escape hatch for exceptions.

Expect these follow-ups

  • How do you enforce that engineers don't bypass semantic tokens and reach for primitives?
  • How would you structure tokens for a dark-mode theme alongside a high-contrast accessibility theme without duplicating your entire token set?
design-tokensthemingnaming-conventionsarchitecture

As asked

Your design system uses CSS custom properties for all semantic tokens. A component deep in the tree needs to render in a different theme from its parent. Explain exactly how CSS custom property inheritance works in this case, what the :root strategy gets wrong, and how you would scope tokens to subtrees correctly.

Sample answer outline

CSS custom properties inherit down the cascade like any other inherited property. Setting --color-background on a scoped class or data attribute creates a new value for that subtree without affecting siblings. The :root-only approach fails for embedded third-party widgets and multi-theme pages. A strong answer mentions that @layer can affect specificity, that properties with initial keyword break inheritance deliberately, and that JavaScript can override via element.style.setProperty for runtime switching.

Expect these follow-ups

  • How do you handle components that intentionally need to opt out of the inherited theme, like a modal that must always appear in light mode?
  • What are the performance implications of deeply nested custom property lookups in a large component tree?
css-custom-propertiesthemingcascadescoping

As asked

You're designing the API for a Card component. A product engineer wants a single component that accepts props for header, footer, image, actions, and variant. Another engineer wants Card, CardHeader, CardBody, CardFooter as composable primitives. Walk me through how you evaluate the tradeoffs and what signals in a component tell you which model to use.

Sample answer outline

A strong answer argues that configuration APIs are faster to use for uniform repeated patterns but box out unforeseen variations, while composition forces more code but is extensible without API surface changes. Key signals favoring composition: content is variable or slot-based, order matters, the component wraps markup with semantic structure (li, section). Signals favoring configuration: the component has a fixed, well-understood layout with a small variation space. The candidate should mention Radix UI or Headless UI as examples of composition done well.

Expect these follow-ups

  • How would you handle a consumer who needs to insert a custom element between CardHeader and CardBody in the composable model?
  • How does your choice affect accessibility, specifically aria relationships between subcomponents?
api-designcomponent-librarycompositionreact

As asked

Walk me through the complete focus management behavior a modal dialog must implement to be WCAG 2.1 compliant. Include: when focus moves into the modal, how focus is trapped, what happens on close, and how you handle the case where the trigger element is removed from the DOM while the modal is open.

Sample answer outline

Focus moves to the modal container or its first focusable element on open. A focus trap intercepts Tab and Shift+Tab so they cycle only within the dialog. Escape closes and returns focus to the trigger. If the trigger is gone, focus falls to the nearest logical ancestor or document.body. The candidate should mention aria-modal=true, role=dialog, aria-labelledby pointing to the dialog heading, and that inert attribute on the background is now preferred over aria-hidden for modern focus trap implementations.

Expect these follow-ups

  • How does your focus trap handle nested modals or a date picker that opens inside the dialog?
  • How would you implement the same behavior as a headless hook in React so consumers can bring their own markup?
accessibilityfocus-managementariamodalcomponent-library

As asked

You have a custom dropdown component that must support keyboard navigation: Tab to focus, Enter or Space to open, arrow keys to navigate options, Escape to close. How do you test this behavior in a way that catches real regressions but doesn't test implementation details?

Sample answer outline

Testing Library with userEvent is the right tool because userEvent simulates real browser events, not synthetic React events, which exercises the actual keyboard handler registration. Tests should target accessible roles (combobox, option, listbox) rather than class names. A strong answer covers: rendering with render, using userEvent.tab() to focus the trigger, userEvent.keyboard('{Enter}') to open, asserting the listbox is visible via getByRole('listbox'), then navigating with ArrowDown and asserting aria-selected state. The candidate should note that userEvent v14 requires await because events are now asynchronous.

Expect these follow-ups

  • How would you test that the dropdown closes and focus returns to the trigger when Escape is pressed?
  • When would you reach for Playwright-based integration tests instead of Testing Library?
testingaccessibilitykeyboard-navigationtesting-librarycomponents

As asked

Give me concrete examples of changes to a Button component that are breaking changes requiring a major version bump versus changes that are safely backward compatible. How do you catch accidental breaking changes before they ship?

Sample answer outline

Breaking: removing a prop, changing a prop's type from string to enum, renaming a prop, changing an accessible role or aria attribute, changing a default value that alters visible behavior. Safe: adding an optional prop with a backward-compatible default, adding a new variant value, improving accessibility in a way that doesn't remove existing behavior. Detection tools include api-extractor to diff public API surface, and breaking-change-detector scripts that compare TypeScript declaration files between versions. The candidate should mention that even CSS class name changes can be breaking if consumers are targeting them.

Expect these follow-ups

  • How do you handle a breaking change that you know affects only 2 out of 30 consumer teams? Do you still bump major?
  • How do you communicate a breaking change that happened accidentally in a minor release?
semverbreaking-changesapi-designversioninggovernance

As asked

A product designer comes to you with a mockup of a highly specific 'stats card with animated counter' component and asks you to add it to the design system. Walk me through how you evaluate whether this belongs in the design system.

Sample answer outline

The evaluation criteria are: is this used or likely to be used on more than one product surface (rule of three), is it generic enough that its API would not be overloaded with domain-specific props, and does the design system have the capacity to maintain and document it with the same quality as other components. For a highly specific stats card, the answer is usually to extract the generalizable primitive (an animated number counter) and document the composition pattern rather than adding the full card. The candidate should describe the conversation they would have with the designer to explain this distinction without dismissing the request.

Expect these follow-ups

  • How do you handle a designer who disagrees with your evaluation and wants the full component in the system?
  • Is there any version of this component that you would add to the system? What would need to change about it?
situationalgovernancecomponent-libraryproduct-sensecollaboration

As asked

Your team wants a dramatic parallax onboarding animation. How do you make the motion accessible without stripping all personality from the product?

Sample answer outline

Start by identifying motion risks: vestibular discomfort, attention capture, reduced readability, and delayed task completion. Honour system reduced-motion preferences and provide a lower-motion variant that keeps sequencing and hierarchy through opacity, scale restraint, or instant state changes. Avoid large z-axis movement, endless loops, and motion behind text. Test the experience with real users where possible and with implementation constraints in mind. A senior motion designer frames accessibility as part of the creative brief, not a compliance tax at the end.

Expect these follow-ups

  • Which motion patterns are most likely to trigger discomfort?
  • How would you document reduced-motion behaviour in a spec?
  • What if brand stakeholders insist the full animation is essential?
accessibilityreduced-motiononboarding

As asked

We use Style Dictionary to compile our token JSON into platform outputs. Walk me through the transform pipeline: parsers, preprocessors, transforms, transform groups, formats, and actions. Where would you inject a custom transform to convert a raw hex value into an iOS UIColor initializer?

Sample answer outline

A strong answer describes the order of operations: parse (read source files), preprocess (modify the full dictionary), transform (per-token value mutation), format (serialize to output string), action (side effects like file copy). The custom iOS transform belongs in the transforms array registered with StyleDictionary.registerTransform, applied before the format step. The candidate should mention that transform groups are just named arrays of transform names and that order within the group matters.

Expect these follow-ups

  • How would you write a custom format that outputs Swift enums instead of a flat UIColor extension?
  • What happens when two tokens in different files define the same path?
style-dictionarydesign-tokensbuild-pipelineiostooling

As asked

Your design system ships to both consumer-facing products and government-contracted enterprise apps. WCAG 2.1 AA is the legal floor for the consumer app, but the enterprise contract requires AAA for some criteria. How do you structure your component library and token system to support both without forking your codebase?

Sample answer outline

Strong answers separate the concern of contrast ratios and interactive sizing into the token layer, so an accessible-plus theme can swap semantic tokens to hit AAA contrast ratios and minimum touch targets without any component code changes. The candidate should mention that some AAA criteria like SC 1.4.6 enhanced contrast require different color ramps, not just darkening existing tokens. They should flag that AAA is not required by WCAG as a blanket target, only for specific success criteria, so partial AAA coverage is intentional and documented.

Expect these follow-ups

  • Which WCAG AAA success criteria are realistically impossible to guarantee in a shared component library, and why?
  • How do you communicate WCAG conformance claims in your documentation so product teams know what the library handles and what they still own?
accessibilitywcagthemingcompliancetokens

As asked

Your design system has separate npm packages for tokens, icons, core components, and React-specific wrappers. How do you decide between independent versioning and fixed/locked versioning across packages? What versioning strategy do you use for breaking changes that span multiple packages simultaneously?

Sample answer outline

Independent versioning lets packages evolve at their own pace but creates diamond-dependency problems when a breaking change in the tokens package cascades into icons and components simultaneously. Fixed versioning simplifies coordination but forces a major bump everywhere even for a patch fix in one package. Strong candidates mention Changesets for atomic multi-package releases, the concept of a coordinated major release that aligns all packages at a new major, and the importance of a clear peer-dependency graph so consumers know which versions are compatible.

Expect these follow-ups

  • How do you communicate a breaking token rename to 40 product teams using different version ranges?
  • How would you handle a consumer pinned to an old version of your icon package but on the latest token package?
monorepoversioningnpmchangesetssemver

As asked

You maintain 200+ components, each with multiple states and themes. Describe how you would set up visual regression testing: what you capture, how you handle flakiness from animations and font loading, how you store and diff baselines, and how you gate pull requests on visual changes.

Sample answer outline

Strong answers mention Chromatic, Percy, or a self-hosted Playwright screenshot approach. Flakiness mitigation includes disabling CSS animations via prefers-reduced-motion in the test environment, waiting for fonts via FontFaceObserver or CSS font-display:block during test render, and stabilizing dates or random values. Baselines should be stored in a separate artifact store, not in git, because binary files bloat history. PR gating should require explicit approval for visual changes, separating intentional from accidental diffs, which Chromatic's UI review workflow handles well.

Expect these follow-ups

  • How do you decide which component states and variants are worth testing vs. which add too much maintenance overhead?
  • How do you handle visual regressions that appear only in specific browser engines, like a Safari rendering difference?
visual-regressiontestingchromaticplaywrightci

As asked

Your design system team is debating between runtime CSS-in-JS (styled-components or Emotion) and a build-time approach like vanilla-extract or CSS Modules. Walk me through the concrete performance, DX, and server-rendering tradeoffs that should drive this decision for a component library consumed by many product teams.

Sample answer outline

Runtime CSS-in-JS inserts style tags dynamically, which blocks the style recalculation pipeline on first paint and produces a hydration mismatch risk in SSR unless the emotion cache or styled-components ServerStyleSheet is correctly threaded through. Build-time tools generate static CSS files that ship with zero runtime overhead but lose the ability to compute styles from JavaScript variables at render time. vanilla-extract solves this with type-safe CSS-in-TypeScript compiled to static files. The candidate should also mention bundle size: Emotion core is 7-8 kB gzipped, which is meaningful for a shared library imported by 50 teams.

Expect these follow-ups

  • How would you migrate a large component library from Emotion to vanilla-extract without breaking consumer code?
  • How does the choice affect tree-shaking of unused component styles?
css-in-jsperformancevanilla-extractssrstyling

As asked

You have a token JSON source that needs to generate Swift constants for iOS, Compose MaterialTheme values for Android, and CSS custom properties for web, all from the same source. Walk me through the build pipeline, the per-platform output format decisions, and how you keep them in sync when a token changes.

Sample answer outline

Style Dictionary or Theo can drive multi-platform output from a single source using per-platform format registrations. For iOS, a Swift extension on UIColor or Color with static computed properties works well. For Android Compose, a Kotlin object with MaterialTheme color mappings is idiomatic. The sync story depends on the repo structure: a monorepo with mobile and web together can run the build pipeline in CI and open PRs against native codebases. The candidate should note that some token types like typography have platform-specific equivalents (UIFont vs. TextStyle) that require transform logic rather than direct value copy.

Expect these follow-ups

  • How do you handle platform-specific token overrides, where iOS needs a slightly different shadow value from web?
  • Who owns reviewing a generated Swift file when it changes, the design systems team or the iOS team?
cross-platformdesign-tokensiosandroidstyle-dictionary

As asked

You own a design system with 30 product teams as consumers. Some teams want to contribute new components. Walk me through the governance model you'd put in place: how a contribution is proposed, reviewed, accepted, and eventually promoted into the main library versus staying team-local.

Sample answer outline

A healthy contribution model has at least three tiers: team-local (not in the system), incubator/contrib (in a separate package or namespace, lower stability guarantees), and stable (full support, versioned, tested). Proposals should include a use-case survey showing at least two teams need it, a design spec signed off by a system designer, and an API proposal. Review gates include accessibility audit, visual regression baseline, doc page with live examples, and sign-off from at least one system team member. The candidate should mention how they handle disagreements when the system team thinks a component is too specific.

Expect these follow-ups

  • How do you sunset a component that was contributed three years ago and is now redundant?
  • What do you do when a product team ships their own version of a Button that has diverged significantly from yours?
governancecontributionprocesscomponent-libraryleadership

As asked

What is your approach to documentation for a component library so that the docs site always reflects the current state of the code? How do you extract prop types, generate code examples, and ensure that a component change automatically surfaces in the docs without a manual doc update?

Sample answer outline

Automated prop table extraction from TypeScript types using react-docgen-typescript or TypeDoc removes the need to manually document every prop. Storybook stories can serve as executable examples embedded in MDX docs pages via the Story block. A strong answer connects the doc site build to the same CI pipeline as the component library so a PR that changes a prop signature also regenerates the doc page in the same PR. The candidate should mention the danger of docs that live in a separate repo and fall out of sync.

Expect these follow-ups

  • How do you document deprecated props so consumers are warned without breaking their builds immediately?
  • How do you handle documenting behavior that differs between React, Vue, and web component versions of the same component?
documentationstorybooktypedoccomponent-librarydx

As asked

A product team reports that importing a single Button from your library is pulling in 40 kB of gzipped JavaScript. Walk me through how you'd diagnose the problem and what structural changes to the library would fix it.

Sample answer outline

Diagnosis starts with bundle-analyzer or source-map-explorer on the consumer's build to see which modules are included. Common culprits: a barrel file (index.ts) that imports everything, side-effect imports that defeat tree-shaking, or a CommonJS build format that bundlers can't statically analyze. Fix: export each component from its own entry point, mark the package as sideEffects: false in package.json, ship an ESM build alongside CJS, and avoid top-level side effects in module scope. The candidate should know that CSS imports at module level are side effects and need to be listed explicitly in the sideEffects array.

Expect these follow-ups

  • How do you test that your library is actually tree-shakeable in CI so regressions don't sneak in?
  • If the consumer is using webpack 4 which has weaker tree-shaking than webpack 5 or Rollup, what additional steps do you recommend?
bundle-sizetree-shakingesmperformancenpm

As asked

Explain the headless component pattern and describe a real case where shipping a headless version of a component is better than shipping a styled one. What are the downsides of headless components for typical product teams?

Sample answer outline

Headless components encapsulate behavior, state, and accessibility without rendering any markup, leaving all styling and DOM structure to the consumer. A good fit is when multiple product surfaces need the same accessible select dropdown behavior but with radically different visual treatments (a minimal admin UI vs. a rich branded storefront). Downsides: consumers must implement all styling themselves, which increases per-team work and risks accessibility regressions if they miss required aria attributes. Libraries like Radix UI and React Aria show the pattern at scale. A design system might ship both a headless primitive and a styled component built on top of it.

Expect these follow-ups

  • How do you document a headless component so that a consumer doesn't accidentally build an inaccessible version?
  • How would you expose state from a headless component so consumers can style based on open/closed or selected?
headless-componentscomponent-libraryaccessibilityapi-designradix

As asked

Describe the ideal workflow for keeping Figma design variables and code-side design tokens in sync as a single source of truth. Who owns the source, how do changes flow in each direction, and what tooling supports it?

Sample answer outline

There are two school of thoughts: code as source of truth (tokens live in JSON, Figma variables are generated from them via Tokens Studio or the Figma Variables REST API), or Figma as source of truth (designers update variables, a GitHub Action pulls them via the Figma API and commits updated token JSON). In either model, the sync must be gated so changes require review, not auto-committed. Tokens Studio (formerly Figma Tokens) is the most common plugin bridge. The candidate should mention that Figma's native Variables API (launched 2023) now makes this more reliable than plugin-based approaches, and that the sync must handle token types that don't exist in Figma natively (like shadow or motion tokens).

Expect these follow-ups

  • What happens when a designer renames a Figma variable that is already referenced in 10,000 lines of product code?
  • How do you handle token values that are computed at build time (like a tint of a base color) that can't be represented as a static Figma variable?
figmadesign-tokenssynctoolingworkflow

As asked

Your Button component accepts an as prop to render as a native button, an anchor, or a React Router Link. How do you type this correctly in TypeScript so that href is available when as='a' but not when as='button', and the component correctly infers the props of whatever element it renders as?

Sample answer outline

The solution uses a generic type parameter constrained to React.ElementType, combined with React.ComponentPropsWithoutRef to pick up the native element's props. A helper type like PolymorphicProps<T extends ElementType, Own> merges the component's own props with ComponentPropsWithoutRef<T>, omitting collisions. The ref must also be forwarded correctly using forwardRef with a second generic. The candidate should be aware that this pattern is verbose and libraries like Ark UI or Radix Slot handle it as a utility. They should also mention that as is an antipattern with styled-components because it conflicts with its own as prop, and asChild is preferred there.

Expect these follow-ups

  • How do you handle the ref type correctly when the rendered element changes at runtime?
  • How does the Radix Slot component achieve polymorphism without an as prop at all?
typescriptpolymorphic-componentsapi-designtype-safetyreact

As asked

You're designing a Dialog component that needs a header slot, a content slot, and a footer slot, and this component must ship for React, Vue, and as a Web Component. Walk me through how slots work differently in each platform and what design decisions help you keep the API consistent across them.

Sample answer outline

Web Components have native named slots via slot attribute on child elements and the slot element in the shadow DOM. Vue has named slots with the v-slot directive and scoped slots for passing data back to the parent. React has no native slot concept; the pattern is either explicit props (header, footer) accepting ReactNode, or a dot notation compound component pattern (Dialog.Header, Dialog.Footer). To keep API consistency across platforms, the candidate should advocate for a slot-name convention (header, footer, content) that maps to the same names in all three environments, even if the mechanism differs. The Shoelace library is a good reference for Web Component slots used alongside React wrappers.

Expect these follow-ups

  • How do you handle scoped slots in Vue, where the slot content needs data from the parent component?
  • How do you test that your React compound component renders its slots in the correct order in the DOM?
slotsweb-componentsvuereactcross-platform

As asked

Your design system needs to ship 500+ icons. Compare SVG sprites, inline SVG, and icon fonts on the dimensions of accessibility, performance, color customization, and developer experience. Which would you choose and why?

Sample answer outline

Icon fonts inherit color from CSS color but are rasterized at subpixel level and fail on some high-DPI displays. They also have accessibility issues because icon font characters are read by screen readers as Unicode code points. Inline SVG gives maximum control (fill, stroke, gradient) and allows aria-hidden directly, but bloats HTML. SVG sprites (a hidden svg element with symbol definitions + use hrefs) strike the best balance: HTTP cached, colorable with currentColor, accessible via aria-hidden on the use element, and supporting fill and stroke overrides. A modern alternative is an SVG sprite served as an external file referenced by xlink:href or href, though cross-origin issues require careful setup.

Expect these follow-ups

  • How do you handle an icon that needs two distinct fill colors, like a two-tone icon?
  • How do you enforce that engineers don't import raw PNG icons when SVGs are available?
iconssvgperformanceaccessibilitycomponent-library

As asked

A product team asks if running axe-core on every component in CI means their product is accessible. How do you explain what automated accessibility tools can and cannot catch, and what manual testing practices should a design system team own versus delegating to product teams?

Sample answer outline

Research consistently shows automated tools catch 20 to 40 percent of real accessibility issues. They excel at structural problems: missing alt text, invalid ARIA usage, color contrast failures. They cannot catch: meaningful alt text quality, keyboard trap detection in complex widgets, screen reader announcement logic, cognitive load issues, or focus order that is technically valid but disorienting. Design systems should own: contrast checking in tokens, ARIA pattern correctness in components, keyboard navigation in standard widgets. Product teams own: meaningful labels, reading order, page-level focus management, and manual screen reader testing with NVDA, VoiceOver, and TalkBack.

Expect these follow-ups

  • Which axe-core rules would you mark as violations versus warnings in your CI pipeline, and why?
  • How do you write a test that catches a focus trap regression that automated axe-core scanning would miss?
accessibilityaxe-coretestingwcagmanual-testing

As asked

Your organization has a design system used across 30 teams. How would you define and measure adoption, health, and impact? What data would you collect, from where, and how would you present it to engineering leadership to justify continued investment?

Sample answer outline

Key metrics: component adoption rate (percentage of UI surface area using system components vs. custom builds), version currency (percentage of consumers on the latest or n-1 version), time to build a new feature in design system consumers vs. non-consumers, accessibility defect rate in products using the system vs. not. Data sources: npm download stats, AST analysis of consumer codebases to count imports, production error tracking filtered by component. A strong answer includes a dashboard updated continuously from CI, not a quarterly survey, and ties adoption to business outcomes like reduced design inconsistency bugs or faster feature delivery.

Expect these follow-ups

  • How do you measure adoption of a token system rather than a component library?
  • What would you do if your adoption numbers looked great but product teams were still filing accessibility bugs?
metricsadoptiongovernanceanalyticsleadership

As asked

React Server Components are now the default in Next.js App Router. How does this change how you architect design system components that previously assumed a client-side rendering context, especially components that use useState, useRef, or browser APIs like window?

Sample answer outline

Server Components cannot use hooks, event handlers, or browser APIs. Design system components that are purely presentational (typographic elements, layout primitives, icon wrappers) can be Server Components. Components that need interactivity (dropdown, modal, toggle) must use 'use client'. The architecture implication is that the design system should expose a layered API: layout and typography primitives that are server-safe, and interactive components that are explicitly marked as client components. Barrel exports need 'use client' on client-only files, not the whole library. The candidate should also discuss that RSC context (like a theme provider) cannot be passed down through server component boundaries to client components and needs a different approach.

Expect these follow-ups

  • How do you handle a theme context that needs to be available in both Server and Client components?
  • How do you communicate to consumers which components in your library are safe to use as Server Components?
react-server-componentsnext-jsarchitecturecomponent-libraryssr