DEV Community

Cover image for What Makes a Good Design System in Frontend Engineering
Tefe
Tefe

Posted on

What Makes a Good Design System in Frontend Engineering

A good design system is a product that has a roadmap, ownership, documentation, versioning, and feedback loops.

What is a design system?

A design system is a set of standardised building blocks and guidelines that enable teams to create consistent, scalable, and accessible user interfaces across projects.
They shape how teams collaborate, how products evolve, and how fast organisations can move without breaking consistency or accessibility.

Components of a Design System

Design Principle:

Every organisation has unique needs and goals. Communicating these through a set of principles helps shape how they present their product. It aids in making crucial design decisions.

An example of a Design principle is "Clarity and Simplicity". 

This means straightforward flows with clear instructions and minimal steps would be prioritised.

Guided by Clarity & Simplicity, my signup form would have:

  • One primary action per screen
  • Clear field labels (not placeholders as labels)
  • Inline validation with plain language

Instead of:

"Invalid input"
Enter fullscreen mode Exit fullscreen mode

The design system enforces:

"Password must be at least 8 characters"
Enter fullscreen mode Exit fullscreen mode

Design Tokens

Design tokens are named entities that store design-related values. These values can include colours, typography scales, spacing units, and shadows. When implemented correctly, they create a single source of truth, making theming and branding possible without rewrites.

There are 3 tiers of token;

Base tokens: Raw, hard-coded values that are the most atomic units in a design system. These are the actual values that never reference other tokens.


// tokens/base.json
{
  "color": {
    "base": {
      "blue": {
        "600": { "value": "#2563eb" },
        "700": { "value": "#1d4ed8" }
      },
      "slate": {
        "50": { "value": "#f8fafc" },
        "300": { "value": "#cbd5e1" },
        "900": { "value": "#0f172a" }
      },
      "white": { "value": "#ffffff" },
      "transparent": { "value": "transparent" }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Semantic Token: Purpose-based tokens that reference base tokens. They describe the intent or purpose rather than the appearance. With semantic tokens, when your organisation rebrands, you change the token values, not every affected component.

{
  "color": {
    "brand": {
      "primary": { "value": "{color.base.blue.600}" },
      "primaryHover": { "value": "{color.base.blue.700}" },
      "primaryActive": { "value": "{color.base.blue.800}" },
      "secondary": { "value": "{color.base.slate.500}" },
      "secondaryHover": { "value": "{color.base.slate.600}" }
    },
    "text": {
      "primary": { "value": "{color.base.slate.900}" },
      "secondary": { "value": "{color.base.slate.600}" },
      "inverse": { "value": "{color.base.white}" },
      "disabled": { "value": "{color.base.slate.400}" }
    },
    "background": {
      "base": { "value": "{color.base.white}" },
      "surface": { "value": "{color.base.slate.50}" },
      "sunken": { "value": "{color.base.slate.100}" },
      "transparent": { "value": "{color.base.transparent}" }
    },
    "border": {
      "default": { "value": "{color.base.slate.300}" },
      "focus": { "value": "{color.base.blue.600}" },
      "error": { "value": "{color.base.red.500}" },
      "transparent": { "value": "{color.base.transparent}" }
    },
    "feedback": {
      "success": { "value": "{color.base.green.500}" },
      "error": { "value": "{color.base.red.500}" },
      "warning": { "value": "{color.base.yellow.500}" },
      "info": { "value": "{color.base.blue.500}" }
    }
  },
  "spacing": {
    "xs": { "value": "{spacing.base.2}" },
    "sm": { "value": "{spacing.base.3}" },
    "md": { "value": "{spacing.base.4}" },
    "lg": { "value": "{spacing.base.6}" },
    "xl": { "value": "{spacing.base.8}" }
  },
}
Enter fullscreen mode Exit fullscreen mode

When to use semantic tokens:

  • All UI components (buttons, inputs, cards, modals)
  • Product interfaces
  • Anywhere that needs automatic theme support
  • When consistency and meaning matter more than specific values

Component tokens: define how a particular component looks. They reference semantic tokens and contain all styling decisions for a component.

Component tokens are optional for smaller systems where semantic tokens provide sufficient abstraction.

{
  "button": {
    "primary": {
      "backgroundColor": { "value": "{color.brand.primary}" },
      "backgroundColorHover": { "value": "{color.brand.primaryHover}" },
      "backgroundColorActive": { "value": "{color.brand.primaryActive}" },
      "textColor": { "value": "{color.text.inverse}" },
      "borderColor": { "value": "{color.border.transparent}" },
      "paddingBlock": { "value": "{spacing.sm}" },
      "paddingInline": { "value": "{spacing.md}" },
      "fontSize": { "value": "{fontSize.md}" },
      "fontWeight": { "value": "{fontWeight.medium}" },
      "borderRadius": { "value": "{borderRadius.md}" }
    },
    "secondary": {
      "backgroundColor": { "value": "{color.background.transparent}" },
      "backgroundColorHover": { "value": "{color.background.sunken}" },
      "textColor": { "value": "{color.text.primary}" },
      "borderColor": { "value": "{color.border.default}" },
      "paddingBlock": { "value": "{spacing.sm}" },
      "paddingInline": { "value": "{spacing.md}" },
      "fontSize": { "value": "{fontSize.md}" },
      "borderRadius": { "value": "{borderRadius.md}" }
    }
  },
  "input": {
    "default": {
      "backgroundColor": { "value": "{color.background.base}" },
      "textColor": { "value": "{color.text.primary}" },
      "borderColor": { "value": "{color.border.default}" },
      "borderColorFocus": { "value": "{color.border.focus}" },
      "borderColorError": { "value": "{color.border.error}" },
      "paddingBlock": { "value": "{spacing.sm}" },
      "paddingInline": { "value": "{spacing.md}" },
      "fontSize": { "value": "{fontSize.md}" },
      "borderRadius": { "value": "{borderRadius.md}" }
    }
  },
  "card": {
    "default": {
      "backgroundColor": { "value": "{color.background.base}" },
      "borderColor": { "value": "{color.border.default}" },
      "borderRadius": { "value": "{borderRadius.lg}" },
      "padding": { "value": "{spacing.lg}" }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Use component tokens for:

  • Large systems with many complex components
  • Products requiring extensive customisation options
  • Systems serving multiple brands or products
  • Centralising component styling decisions

Foundations:

The foundations of a design system ensure consistency and quality in design and development. It's built on two main pillars: d*esign tokens and system architecture*.

Foundational elements include:

  • Typography
  • Color system
  • Accessibility standards
  • Spacing and Layout
  • Iconography

What makes a solid foundation?

  • Mathematical consistency - using modular scales for type and spacing
//Good - Spacing uses consistent ratio (e.g., 1.5x multiplier)
spacing: {
  xs: "0.5rem",   // 8px
  sm: "0.75rem",  // 12px
  md: "1rem",     // 16px
  lg: "1.5rem",   // 24px
  xl: "2.25rem",  // 36px
  xxl: "3.375rem" // 54px
}

// Bad - No pattern, impossible to memorize
spacing: {
  tiny: "0.3125rem",  // 5px 
  small: "0.625rem",  // 10px
  medium: "0.9375rem", // 15px
  large: "1.375rem",  // 22px - random
  huge: "2.125rem"   // 34px
}
Enter fullscreen mode Exit fullscreen mode
  • Scalable naming conventions - clear, predictable names that grow with the system
// GOOD - Semantic tokens (references, flexible)
const semanticTokens = {
  colors: {
    action: {
      primary: baseTokens.colors.blue[200],        
      primaryHover: baseTokens.colors.blue[300],  
    },
    feedback: {
      success: baseTokens.colors.green[500],     
      error: baseTokens.colors.blue[500],        
    },
    text: {
      primary: baseTokens.colors.slate[900],      
      secondary: baseTokens.colors.slate[600],   
    }
  }
};


// Bad - what happens when "blue" becomes purple?
colors: {
  blueButton: "#2563eb",
  darkBlueHover: "#1d4ed8",
  lightBlueBackground: "#dbeafe"
}

// Now you're stuck with:
blueButton: "#7c3aed" // This is purple 
Enter fullscreen mode Exit fullscreen mode

Component Library

A component library is a collection of UI components within a design system.

What makes a good component library?

  • Single Responsibility: Each component should have a single responsibility.

// Good
<Button variant="primary" size="md">
  Save
</Button>

// Bad - ONE component trying to be everything
<Button
  variant="primary"
  size="large"
  icon="left"
  iconName="save"
  iconSize={16}
  iconColor="white"
  loading={false}
  loadingText="Saving..."
  loadingSpinnerSize={20}
  badge={2}
  badgeColor="red"
  badgePosition="top-right"
  tooltip="Click to save"
  tooltipPosition="bottom"
  animation="bounce"
  gradient={true}
  gradientFrom="blue"
  gradientTo="purple"
  // + more props...
/>
Enter fullscreen mode Exit fullscreen mode
  • Composable: It doesn’t try to predict every use case with prebuilt “big” components like in the button example above. Instead, it gives small, flexible primitives that can be composed.
<Button variant="primary">
  <Icon name="save" />
  Save Changes
  <Badge>2</Badge>
</Button>
Enter fullscreen mode Exit fullscreen mode
  • Consistent and predictable API
//Good- Same pattern in all components. Learn once, apply everywhere
<Button variant="primary" size="md" disabled />
<Input variant="outlined" size="md" disabled />
<Select variant="outlined" size="md" disabled />
<Card variant="elevated" />

//Bad - Each component uses different naming. Difficult to learn
<Button color="primary" />      // uses 'color'
<Input variant="outlined" />    // uses 'variant'
<Select theme="primary" />      // uses 'theme'
<Card type="elevated" />        // uses 'type'
Enter fullscreen mode Exit fullscreen mode
  • Smart defaults with Controlled Flexibility:
// Works great with/without props, uses variant="primary", size="md" as default
<Button>Click me</Button>

// But allows customisation when needed
<Button variant="secondary" size="lg">
  Large Secondary
</Button>

// Bad
<Button 
  variant="primary"    // Required
  size="md"            // Required
  type="button"        // Required
  disabled={false}     // Required
>
  Click me
</Button>
Enter fullscreen mode Exit fullscreen mode
  • Proper Prop Types & TypeScript Support

// Inherits valid button props and ensures only valid customizations
interface ButtonProps extends Omit<
  React.ComponentPropsWithoutRef<'button'>,
  'style'  // Block inline styles
> {
  variant?: 'primary' | 'secondary';
  size?: 'sm' | 'md' | 'lg';
}

// Bad - anything goes for props
const Button = ({ 
  variant, 
  size, 
  disabled, 
  loading, 
  children, 
  onClick,
  ...props  // anything works
}) => {
  return (
    <button 
      disabled={disabled}
      onClick={onClick}
      {...props}  // spreads everything
    >
      {children}
    </button>
  );
};
Enter fullscreen mode Exit fullscreen mode
  • Accessible by Default
//Good - Keyboard works, screen readers announce "button", forms work
<button onClick={handleClick}>
  Click me
</button>
// 

//bad - lacks focus, keyboard support, and screen reader compatibility
<div onClick={handleClick} className="button">
  Click me
</div>
Enter fullscreen mode Exit fullscreen mode

Pattern Library

A Pattern Library is a collection of design patterns that provide solutions to common design problems and user interface challenges. These patterns are reusable and follow best practices to ensure consistency and usability across an application or suite of applications.

Examples: Form Validation, Navigation.

What makes a strong pattern library?

  • Solves Real Problems:
// Form validation pattern used across 20+ forms
<FormField
  name="email"
  label="Email Address"
  validation={{
    required: "Email is required",
    pattern: {
      value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,
      message: "Invalid email"
    }
  }}
  helpText="We'll never share your email"
>
  <Input type="email" />
</FormField>
Enter fullscreen mode Exit fullscreen mode
  • Proper documentation:
## Empty State Pattern

### When to use
- List/table with no data
- Search with no results  
- New user with no content

### When NOT to use
- Loading states (use skeleton instead)
- Errors (use error pattern)

### Accessibility
- Must include descriptive text
- Action button should be clearly labeled
- Use role="status" for dynamic updates
Enter fullscreen mode Exit fullscreen mode

Handles Edge Cases: The pattern addresses loading states, errors, empty states, and validation - not just the happy path.

Tooling and Infrastructure

Tools like Storybook or similar for component development, visual regression testing to catch unintended changes, automated accessibility testing, and a clear publishing and versioning strategy.
Good systems have CI/CD that runs tests on every PR, automatically publishes packages, and generates changelogs from commits.

Testing

A design system demands rigorous testing at multiple levels. Unit tests verify component logic and prop handling.
Visual regression testing catches unintended UI changes. Accessibility testing ensures WCAG compliance.
Integration tests confirm components work together correctly.

Documentation

Documentation is critical for the success of a design system. It ensures that all stakeholders including designers, developers, and other team members understand how to use and maintain the system.

Thorough documentation is provided for every component and pattern, including usage guidelines, code examples, and accessibility considerations. It's easy for designers and developers to understand and implement.

Real World Example: Atlassian Design System

Atlassian, a leading provider of collaboration software, developed the Atlassian Design System to unify the user experience across its suite of products including Jira, Confluence, Bitbucket, and Trello. It serves as a comprehensive framework that consolidates design patterns, guidelines, and reusable components to ensure consistency, efficiency, and usability across all Atlassian products.

Atlassian Design Principles

  • Trusted fundamentals before comprehensive patterns
  • Meet system needs before delivering individual features
  • Bring people on the journey before helping for the moment

Atlassian's Foundation: Colour Palette

Atlassian's Foundation: Colour Palette

Source : Atlassian colour palette

Atlassian's Design Token: Text Color

Atlassian's Design Token: Text Color

Source: Atlassian color text

Atlassian's Component Library: Button

Atlassian's Component Library: Button

Source : Atlassian button component

Atlassian's Pattern Library: Form Validation

Atlassian's Pattern Library: Form Validation

Source : Atlassian form pattern

Atlassian's Documentation

Atlassian Design System is supported by a comprehensive documentation that serves as a central reference for designers, developers, and product teams. Documentation includes design principles, usage guidelines, code snippets, and design tokens. See here

Other Examples of design systems

  • Material Design by Google
  • Polaris by Shopify
  • Fluent Design System by Microsoft
  • Pajamas by Gitlab
  • Carbon Design System by IBM

Conclusion

A good design system should:

  • Be aligned with the brand identity
  • Accelerate development velocity without sacrificing quality
  • Ensure consistency across products while allowing necessary flexibility
  • Reduce decision fatigue for common UI patterns
  • Scale as the organisation grows
  • Have proper documentation, be easy to use and maintain.

References

https://www.figma.com/blog/design-systems-101-what-is-a-design-system/
https://atlassian.design/
Building Design Systems: Unify User Experiences through a Shared Design Language Edition: 1st ed. By Sarrah Vesselov and Taurie Davis
https://storybook.js.org/tutorials/design-systems-for-developers/
https://medium.com/@marcintreder/design-system-sprint-4-design-principles-8efb22d8a208
https://atlassian.design/get-started/about-atlassian-design-system#our-principles

Top comments (0)