Techcookies

Design System Interview Guide — React Ecosystem

Architecture, Design Patterns | Wed Apr 29 2026 | 19 min read

Design System Interview Guide — React Ecosystem

A comprehensive guide covering core topics and famous interview questions for Design System interviews in the React ecosystem.


Table of Contents

  1. Core Topics
  2. Famous Interview Questions
  3. Must-Know Concepts

🎨 Core Topics


1. Component Architecture

  • Atomic Design methodology — Atoms → Molecules → Organisms → Templates → Pages
  • Compound components pattern — components that share implicit state (Tabs, Accordion, Select)
  • Controlled vs Uncontrolled components
  • Composition over configuration — build complex UIs by combining simple components
  • Polymorphic componentsas prop to render any HTML element while keeping styles

Key patterns to know:

jsx
// Compound Component Pattern
<Select>
  <Select.Trigger />
  <Select.Options>
    <Select.Option value="a">Option A</Select.Option>
    <Select.Option value="b">Option B</Select.Option>
  </Select.Options>
</Select>

// Polymorphic Component
<Text as="h1" size="xl">Heading</Text>
<Text as="p" size="md">Paragraph</Text>
<Text as="label" size="sm">Label</Text>

2. Design Tokens

Design tokens are the single source of truth for visual decisions — named variables that store design values.

Token tiers:

Global Tokens      →  color-blue-500: #3B82F6
      ↓
Alias Tokens       →  color-primary: {color-blue-500}
      ↓
Component Tokens   →  button-bg-color: {color-primary}

Key concepts:

  • Color, spacing, typography, shadow, border-radius, z-index
  • Naming conventions: {category}-{property}-{variant}-{state}
  • CSS variables vs JS tokens vs Tailwind config
  • Multi-brand / multi-theme token architecture
  • Tools: Style Dictionary, Token Studio (Figma plugin)
css
/* Global tokens */
--color-blue-500: #3B82F6;

/* Alias tokens */
--color-primary: var(--color-blue-500);

/* Component tokens */
--button-bg: var(--color-primary);
--button-bg-hover: var(--color-blue-600);

3. Theming & Styling

Styling approaches comparison:

Approach Pros Cons Best For
CSS-in-JS (Emotion, Styled Components) Dynamic styles, colocation Runtime cost, larger bundle Highly dynamic theming
CSS Modules Zero runtime, scoped No dynamic styles Component isolation
Tailwind CSS Utility-first, small CSS Long class strings Rapid UI development
CSS Variables Native, runtime theming Limited to CSS values Multi-theme support

Theme context pattern in React:

jsx
const ThemeContext = React.createContext('light');

function ThemeProvider({ theme, children }) {
  return (
    <ThemeContext.Provider value={theme}>
      <div data-theme={theme}>{children}</div>
    </ThemeContext.Provider>
  );
}

// CSS Variables driven by data-theme attribute
[data-theme="dark"] {
  --color-bg: #0f172a;
  --color-text: #f1f5f9;
}

Dark mode approaches:

  • prefers-color-scheme media query — respects OS setting
  • data-theme attribute on <html> — user-controlled
  • CSS variables — switch token values without JS re-render

4. Accessibility (a11y)

Every component in a design system must be accessible by default — consumers shouldn't have to think about it.

Key principles:

  • Use semantic HTML first, ARIA only when needed
  • Every interactive component must be keyboard operable
  • All interactive elements need visible focus indicators
  • Color alone should never convey meaning (use icons or text too)
  • Test with real screen readers (NVDA, VoiceOver, JAWS)

ARIA patterns for common components:

jsx
// Modal
<div role="dialog" aria-modal="true" aria-labelledby="dialog-title">
  <h2 id="dialog-title">Confirm Action</h2>
</div>

// Custom Checkbox
<div role="checkbox" aria-checked={checked} tabIndex={0}
     onKeyDown={handleKeyDown} onClick={toggle}>
  {checked ? '✓' : ''}
</div>

// Live region for notifications
<div aria-live="polite" aria-atomic="true">
  {notification}
</div>

Focus management rules:

  • Modal opens → focus moves to first focusable element inside
  • Modal closes → focus returns to the trigger element
  • Tab key cycles only within open modal (focus trap)
  • Route change → focus moves to page heading

5. Component API Design

The API is a contract with consumers — design it carefully because breaking changes are costly.

Props naming conventions:

  • Use on prefix for event handlers: onClick, onChange, onClose
  • Use is / has prefix for booleans: isDisabled, isLoading, hasError
  • Use default prefix for uncontrolled defaults: defaultValue, defaultOpen
  • Prefer descriptive over clever: variant="primary" not v="p"

Variants vs boolean props:

jsx
// ✅ Preferred — scales well, easy to document
<Button variant="primary" size="lg" />
<Button variant="secondary" size="sm" />

// ❌ Avoid — combinatorial explosion, hard to manage
<Button primary large />
<Button secondary small />

Ref forwarding — always do this in a design system:

jsx
const Button = React.forwardRef(({ children, ...props }, ref) => {
  return (
    <button ref={ref} {...props}>
      {children}
    </button>
  );
});
Button.displayName = 'Button';

Prop spreading safely:

jsx
// Allow consumers to pass native HTML attributes
function Input({ label, error, className, ...rest }) {
  return (
    <div className={clsx('input-wrapper', className)}>
      <label>{label}</label>
      <input {...rest} aria-invalid={!!error} />
      {error && <span role="alert">{error}</span>}
    </div>
  );
}

6. Documentation & Dev Experience

Good documentation is what separates a design system from just a component library.

Storybook story structure — every component should have:

  • Default — basic usage
  • Variants — all visual variants
  • Sizes — all size options
  • States — disabled, loading, error, success
  • Interactive — with Controls to tweak props live
  • Accessibility — keyboard nav demonstration
jsx
// Button.stories.jsx
export default {
  title: 'Components/Button',
  component: Button,
  argTypes: {
    variant: { control: 'select', options: ['primary', 'secondary', 'ghost'] },
    size: { control: 'radio', options: ['sm', 'md', 'lg'] },
    isLoading: { control: 'boolean' },
    isDisabled: { control: 'boolean' },
  },
};

export const Default = { args: { children: 'Click me', variant: 'primary' } };
export const Loading = { args: { children: 'Saving...', isLoading: true } };
export const AllVariants = () => (
  <Stack>
    <Button variant="primary">Primary</Button>
    <Button variant="secondary">Secondary</Button>
    <Button variant="ghost">Ghost</Button>
  </Stack>
);

Documentation site essentials:

  • Usage guidelines (do's and don'ts)
  • Props table with types and defaults
  • Code snippets ready to copy
  • Figma embed alongside code component
  • Changelog and migration guides

7. Versioning & Publishing

Semantic versioning:

MAJOR.MINOR.PATCH
  2  .  1  .  3

MAJOR → Breaking change (rename prop, remove component)
MINOR → New feature, backward compatible (new variant, new component)
PATCH → Bug fix, backward compatible

What counts as a breaking change:

  • Removing a component or prop
  • Renaming a prop
  • Changing a prop's type
  • Changing default behavior
  • Updating a peer dependency major version

Monorepo structure for publishing:

packages/
├── core/          → @myds/core (Button, Input, Modal...)
├── icons/         → @myds/icons
├── charts/        → @myds/charts
├── tokens/        → @myds/tokens
└── utils/         → @myds/utils

Release workflow:

  1. PR merged → automated changeset added
  2. CI runs tests + visual regression
  3. Changesets bot opens a "Version Packages" PR
  4. Merge → auto-publishes to npm with correct semver bump
  5. Changelog auto-generated from changesets

8. Testing Components

Testing pyramid for a design system:

        [Visual Regression]   ← Chromatic / Percy (screenshot diffs)
      [Accessibility Tests]   ← axe-core / jest-axe
    [Interaction Tests]       ← Storybook play() / Testing Library
  [Unit Tests]                ← Jest + React Testing Library

Unit + interaction testing:

jsx
// Button.test.jsx
test('calls onClick when clicked', async () => {
  const handleClick = vi.fn();
  render(<Button onClick={handleClick}>Click</Button>);
  await userEvent.click(screen.getByRole('button'));
  expect(handleClick).toHaveBeenCalledOnce();
});

test('does not call onClick when disabled', async () => {
  const handleClick = vi.fn();
  render(<Button isDisabled onClick={handleClick}>Click</Button>);
  await userEvent.click(screen.getByRole('button'));
  expect(handleClick).not.toHaveBeenCalled();
});

Accessibility testing:

jsx
import { axe, toHaveNoViolations } from 'jest-axe';
expect.extend(toHaveNoViolations);

test('Button has no accessibility violations', async () => {
  const { container } = render(<Button>Submit</Button>);
  expect(await axe(container)).toHaveNoViolations();
});

Visual regression with Chromatic:

  • Every story becomes a screenshot test
  • On every PR, Chromatic diffs screenshots against baseline
  • Reviewers approve or reject visual changes
  • Catches unintended CSS regressions automatically

9. Performance

Tree shaking — critical for design systems:

js
// ✅ Named exports — tree-shakeable
export { Button } from './Button';
export { Input } from './Input';
export { Modal } from './Modal';

// ❌ Barrel with * — can break tree shaking in some bundlers
export * from './components';

Avoiding re-renders in design system components:

  • Use React.memo for pure components
  • Avoid creating new objects/functions in render inside context providers
  • Keep ThemeContext value stable with useMemo
jsx
// ❌ Creates new object every render → all consumers re-render
<ThemeContext.Provider value={{ theme, tokens }}>

// ✅ Stable reference → only re-renders when theme changes
const contextValue = useMemo(() => ({ theme, tokens }), [theme, tokens]);
<ThemeContext.Provider value={contextValue}>

CSS performance:

  • Prefer CSS classes over inline styles
  • Avoid deeply nested selectors
  • Use CSS variables for runtime theming instead of JS-driven style recalculation
  • Keep specificity low — design system styles should be easy to override when necessary

10. Governance & Adoption

Contribution models:

Model How it works Best for
Centralized Core team owns everything Small orgs, strict consistency
Federated Product teams contribute, core team reviews Large orgs, many teams
Open contribution Anyone can PR, core team approves Open source design systems

Driving adoption:

  • Make it easier to use the DS than to build custom components
  • Provide codemods for migrations
  • Embed in starter templates and boilerplates
  • Track adoption metrics (% of UI using DS components)
  • Maintain a Slack/Discord channel for support

Handling one-off requests:

  1. Check if an existing component can be extended
  2. If it's a pattern seen in multiple places → add to DS
  3. If it's truly one-off → let product team own it locally
  4. Document the decision and revisit in next design system cycle

❓ Famous Interview Questions


Component Architecture Questions

  • How would you build a Button component that supports variants, sizes, loading state, and icons?
  • How do you implement the Compound Component pattern? Give an example with <Select> or <Tabs>
  • What is a polymorphic component? Build a <Text as="h1" /> component in React
  • How would you build a Form system with composable fields, labels, and error messages?
  • What's the difference between controlled and uncontrolled components in a design system context?
  • How do you design a Modal component that handles focus trap, scroll lock, and portal rendering?
  • How would you implement a Tooltip that works with both mouse and keyboard users?
  • Explain the difference between composition and configuration in component design

Design Tokens & Theming Questions

  • What are design tokens and how do they differ from hardcoded values or SCSS variables?
  • How would you implement a multi-theme system (light, dark, brand themes) in React?
  • What is the difference between global tokens, alias tokens, and component tokens?
  • How do you implement dark mode — CSS variables approach vs data-theme vs Context API?
  • How would you handle token scaling across multiple products / brands using one design system?
  • How do you keep Figma tokens and code tokens in sync?
  • What tool would you use to generate tokens for multiple platforms (web, iOS, Android)?

API Design Questions

  • How do you decide when to use a single flexible component vs multiple specialized components?
  • How would you design the props API for a <Button> — what props would it accept and why?
  • How do you handle prop forwarding and ref forwarding in design system components?
  • What are the pros/cons of variants as strings (variant="primary") vs boolean props (isPrimary)?
  • How do you design a spacing system — what scale would you use and why (4px base, 8px base)?
  • How do you handle style overrides — do you allow className, sx prop, CSS variables, or none?
  • How do you support responsive props like <Box mt={{ sm: 2, md: 4, lg: 6 }}>?

Accessibility Questions

  • How do you make a custom Dropdown/Select fully accessible (ARIA, keyboard, screen reader)?
  • What ARIA attributes are needed for a Modal dialog component?
  • How do you implement focus trapping inside a modal in React?
  • How would you make a custom Checkbox accessible without using native <input type="checkbox">?
  • How do you test your component library for accessibility violations in CI/CD?
  • How do you handle dynamic content announcements (toast notifications, live regions)?
  • What is the roving tabindex pattern and when do you use it?

Styling Questions

  • What are the trade-offs between CSS-in-JS vs CSS Modules vs Tailwind in a design system?
  • How would you implement CSS variables-based theming in a React component library?
  • How do you prevent CSS specificity conflicts when consumers use your components?
  • How do you handle responsive styles within components in a design system?
  • How do you ensure your components work correctly in SSR environments (Next.js)?
  • What is the zero-runtime CSS-in-JS trend (Vanilla Extract, Linaria) and why does it matter?

Storybook & Documentation Questions

  • How do you structure stories for a component — what scenarios should every component cover?
  • How do you use Storybook Controls to make components interactive in documentation?
  • How would you set up visual regression testing with Chromatic in a CI pipeline?
  • How do you write usage guidelines (do's and don'ts) for a component?
  • How do you keep documentation in sync with the actual component code?
  • What is Storybook's play() function and how does it enable interaction testing?

Versioning & Distribution Questions

  • How do you decide what is a breaking change in a component library?
  • How do you manage multiple major versions of a design system across different consuming apps?
  • How would you set up a monorepo to publish multiple packages (core, icons, charts)?
  • How do you write a migration guide when introducing breaking changes?
  • How would you use Changesets to automate versioning and changelog generation?
  • What is peer dependency and how do you handle React as a peer dep in your library?

Real-World / Scenario Questions

  • A product team says your Button doesn't support their use case — how do you handle it?
  • How do you roll out a new major version without breaking 20 consuming apps overnight?
  • How do you measure adoption of your design system across teams and products?
  • A designer wants to introduce a new color not in the token system — what do you do?
  • How do you convince engineers to use the design system instead of writing custom components?
  • Your design system's bundle size is too large — how do you investigate and fix it?
  • A team needs a component urgently that doesn't exist in the DS yet — what's your process?

🔥 Must-Know Concepts

Concept Why It Matters
React.forwardRef Pass refs to DOM elements inside DS components
React.createContext Theme and token distribution across the tree
Compound components Flexible composition (Tabs, Accordion, Select)
Polymorphic as prop Render any HTML element while keeping DS styles
CSS custom properties Runtime theming without JS re-renders
Storybook Documentation, visual testing, interaction testing
Semantic versioning Safe upgrades for all consuming teams
Radix UI / Headless UI Unstyled accessible primitives to build on top of
Style Dictionary Transform tokens to any platform (web, iOS, Android)
Changesets Automate versioning and changelogs in monorepos

🏆 Top 5 Must-Practice Questions

These come up most frequently at companies like Google, Airbnb, Atlassian, Razorpay, and Swiggy:

  1. Button component design — variants, sizes, states, ref forwarding, accessibility
  2. Theming / dark mode — CSS variables, token tiers, React context
  3. Compound components — implement Tabs or Select with shared implicit state
  4. Accessibility of custom components — build an accessible Dropdown from scratch
  5. Breaking change strategy — how to version, communicate, and migrate consumers

📚 Real-World Design Systems to Study

Company Design System Tech
Google Material Design / MUI React, Web Components
Airbnb DLS (Design Language System) React
Atlassian Atlaskit / Forge React
GitHub Primer React, CSS
Shopify Polaris React
IBM Carbon React
Adobe Spectrum React, Web Components
Razorpay Blade React


🧩 Additional Questions — Deep Dive

Component Internals

  • How would you implement a Toast / Snackbar system that supports stacking, auto-dismiss, and manual close?
  • How do you build a Popover component that handles positioning, flipping, and collision detection?
  • How would you implement a virtualized Dropdown that can handle 10,000 options without lag?
  • How do you build a Stepper / Wizard component that manages step state and validation between steps?
  • How would you implement a Command Palette (like VS Code's Ctrl+K) as a reusable component?
  • How do you build an Accordion using the compound component pattern with animation support?
  • How would you design a Table component that supports sorting, row selection, pagination, and sticky headers?
  • How do you implement a Color Picker component that is fully keyboard accessible?

Tokens & Theming Deep Dive

  • How would you design a token system that supports white-labeling for multiple enterprise clients?
  • How do you handle component-level token overrides without breaking the global token system?
  • How would you implement dynamic theming at runtime — for example, letting users pick an accent color?
  • What is the token transformation pipeline and how does Style Dictionary fit into it?
  • How do you ensure token parity between Figma and code — what is your sync strategy?
  • How do you handle semantic color tokens for states like error, warning, success, info across themes?
  • How would you structure tokens to support high contrast mode for accessibility compliance?

Styling Architecture

  • What is zero-runtime CSS-in-JS (Vanilla Extract, Linaria, Panda CSS) and why is it gaining popularity?
  • How do you handle the specificity war when consumers try to override your component styles?
  • How would you design a sx prop system (like MUI) that maps to CSS properties via tokens?
  • How do you ensure your components don't leak global styles that affect consumer apps?
  • How would you migrate a design system from Styled Components to CSS Modules with zero downtime?
  • How do you handle animation tokens (duration, easing) and apply them consistently across components?
  • What strategies do you use to reduce CSS bundle size in a component library?

State & Behavior

  • How would you manage shared state between compound components without exposing it to consumers?
  • How do you implement uncontrolled behavior with optional controlled mode in the same component?
  • How do you handle keyboard shortcuts in a design system component (e.g., Escape to close, Enter to confirm)?
  • How would you implement a context menu (right-click menu) that is accessible and positions correctly?
  • How do you manage animation state in components like Accordion or Dialog (enter/exit transitions)?
  • How would you build a drag-and-drop reorderable list as a design system component?

Testing Deep Dive

  • How do you test a compound component where child components rely on parent context?
  • How would you write tests for a Modal that checks focus trap and focus restoration?
  • How do you test keyboard navigation in a complex component like a ComboBox or Menu?
  • What is your strategy for mocking design system tokens in consumer app tests?
  • How do you prevent visual regression across 200+ components without making CI too slow?
  • How do you test components that use portals (Modal, Tooltip) rendered outside the component tree?

Monorepo & Infrastructure

  • How would you set up a Turborepo for a design system with packages for core, icons, tokens, and utils?
  • How do you handle peer dependency conflicts when multiple apps use different versions of your DS?
  • How would you implement automatic changelog generation using Conventional Commits + Changesets?
  • How do you set up Storybook with Module Federation so each team can have their own stories?
  • How do you bundle a component library — what is your Rollup or Vite config strategy?
  • How do you handle TypeScript declaration files (.d.ts) when publishing to npm?

Governance & Culture

  • How do you run a design system RFC (Request for Comments) process for new components?
  • How do you handle a situation where two teams built the same component independently before your DS had it?
  • How do you prioritize which components to build first in a new design system?
  • How do you structure a design system team — what roles are needed (engineer, designer, PM)?
  • How do you communicate deprecations to consuming teams without causing panic?
  • How do you build a community of contributors around your design system internally?
  • How do you define "done" for a component before it ships in the design system?

Performance Deep Dive

  • How do you measure the bundle size impact of your design system on a consumer app?
  • How would you implement on-demand imports so consumers only pay for what they use?
  • How do you prevent context re-render cascades in a deeply nested theme provider?
  • How do you optimize a design system component that uses CSS-in-JS for dynamic styles at scale?
  • How would you implement font loading strategy as part of the design system setup?
  • How do you handle icon performance — inline SVG vs sprite vs icon font vs image?

Quick-Fire Concept Questions

  • What is the difference between aria-label and aria-labelledby?
  • When would you use role="presentation" on an element?
  • What is React.cloneElement and when is it used in design systems?
  • What is the render prop pattern and how does it compare to compound components?
  • What is CSS containment and how can it help component isolation?
  • What is the difference between visibility: hidden and display: none from an accessibility standpoint?
  • What is inert HTML attribute and how does it help with modal accessibility?
  • What is headless UI and how does it differ from a traditional component library?
  • What is the difference between tabIndex="0" and tabIndex="-1"?
  • When would you use React.createPortal in a design system component?
  • What is color contrast ratio and what are the WCAG AA requirements?
  • What is the :focus-visible CSS pseudo-class and why is it preferred over :focus for design systems?

Last updated: April 2026