Frontend Development

From Design to Code: Implementing Design Tokens with Figma Variables and React

In the modern frontend landscape, the gap between design and development is often the primary source of inefficiency. For years, the handoff process involved manual translation of visual specs into code, leading to "design drift" and maintenance nightmares. The solution? Design tokens. By treating design attributes like colors, spacing, and typography as data structures that can be shared across platforms, we create a single source of truth. This post explores how to bridge the gap using Figma’s native Variables feature, standard CSS Custom Properties, and React components.

Why Design Tokens Matter

At their core, design tokens are atomic values—specifically the colors, spacing, and font sizes used in your UI. They act as the building blocks for design systems. Instead of hardcoding #0055ff into your components, you reference a semantic token like primary-action-bg. This abstraction allows for easy theming, consistency, and a streamlined workflow where changes in the design tool automatically reflect in the codebase.

Leveraging Figma Variables

Recent updates to Figma have introduced powerful Variables capabilities. Unlike legacy styles, variables support data types such as color, number, string, and boolean, and they allow for local and collection modes. This means you can define a theme-light and theme-dark mode directly within Figma. When exporting these tokens, you typically use plugins or manual scripts to generate a JSON representation that maps Figma variable names to semantic tokens.

For example, a Figma variable named Color/Primary/Default might map to a semantic token named brand-primary. This mapping is crucial for maintaining context as you move from design to development.

Connecting to CSS Custom Properties

CSS Custom Properties (CSS Variables) are the ideal bridge for web implementation. They are native to the browser, allow for inheritance, and can be dynamically overridden. To implement this, we map our design tokens directly to CSS variables within the :root selector.

Here is an example of how your CSS might look after exporting tokens:

:root {
  /* Semantic Color Tokens */
  --color-brand-primary: #0055ff;
  --color-brand-primary-hover: #0044cc;
  --color-text-primary: #1a1a1a;
  --color-text-secondary: #666666;

  /* Spacing Tokens */
  --space-xs: 0.25rem;
  --space-sm: 0.5rem;
  --space-md: 1rem;
  --space-lg: 2rem;

  /* Typography Tokens */
  --font-family-base: 'Inter', sans-serif;
  --font-size-lg: 1.25rem;
  --font-weight-bold: 700;
}

By using semantic names (e.g., --color-text-primary rather than --color-grey-500), you decouple the code from specific implementation details. If your design team decides to shift from grey to dark blue for secondary text, you only update the variable definition, not every component using it.

Integrating with React Components

In a React application, you can consume these CSS variables directly in your components without needing complex context providers for basic theming, thanks to CSS cascade inheritance. However, for dynamic theming, you might toggle classes on the body or a root container.

import React from 'react';

const PrimaryButton = ({ children }) => {
  return (
    <button
      style={{
        backgroundColor: 'var(--color-brand-primary)',
        color: '#ffffff',
        padding: 'var(--space-sm) var(--space-md)',
        borderRadius: '4px',
        fontWeight: 'var(--font-weight-bold)',
        cursor: 'pointer',
        transition: 'background-color 0.2s ease'
      }}
      onMouseEnter={(e) => {
        e.target.style.backgroundColor = 'var(--color-brand-primary-hover)';
      }}
    >
      {children}
    </button>
  );
};

export default PrimaryButton;

This approach ensures that your React components remain theme-aware and consistent with the rest of your UI. For more complex logic, you can also extract these values into JavaScript objects for programmatic access, ensuring type safety and better developer experience.

Conclusion

Implementing design tokens is not just about saving time; it’s about building a scalable, maintainable design system. By connecting Figma Variables to CSS Custom Properties and React, you create a fluid pipeline where design and code speak the same language. Start small by standardizing your colors and spacing, and gradually expand your token library to include typography and effects. The result is a more cohesive product and a happier development team.

Share: