A Complete Guide to Dynamic Themes in React

A Complete Guide to Dynamic Themes in React

A Complete Guide to Dynamic Themes in React

Jun 11, 2025

Creating strong, flexible design systems is vital in today's product development. At the core of these systems are design tokens. These tokens act as the single, reliable source for all your design choices—things like colors, fonts, and spacing. When these design decisions are made in a tool like Figma, the next challenge is smoothly turning them into usable code for different platforms, especially for dynamic themes that can change (like light or dark mode).

This is where Style Dictionary integrates seamlessly. It's an open-source tool that allows you to define your design tokens once and use them across platforms. Combined with custom transformations, it becomes an effective way to generate dynamic themes directly from your Figma files for React applications.

Design Tokens from Figma

Figma, with plugins like Tokens Studio for Figma (formerly Figma Tokens), enables designers to structure design decisions into JSON. These JSON structures can then be exported for further processing.

A common requirement is implementing light and dark themes, or even multiple brand themes. Managing these manually in code is error-prone. Style Dictionary offers an elegant solution by processing your tokens and applying logic to generate theme-specific outputs.

Style Dictionary: Your Theming Engine

Style Dictionary processes platform-agnostic tokens and generates platform-specific outputs. For React, you can generate JavaScript/TypeScript theme objects or CSS variables.

Tokens are defined hierarchically, such as:

json

{
  "color": {
    "brand": {
      "primary": { "value": "#007BFF", "type": "color" },
      "secondary": { "value": "#6C757D", "type": "color" }
    },
    "text": {
      "default": { "value": "{color.brand.primary}", "type": "color" },
      "inverse": { "value": "{color.neutral.100}", "type": "color" }
    },
    "neutral": {
      "100": { "value": "#F8F9FA", "type": "color" },
      "900": { "value": "#212529", "type": "color" }
    }
  }
}

For light/dark theming, you can export separate token sets (e.g., colors-light.json, colors-dark.json) and configure Style Dictionary to generate theme-specific code.

Dynamic Theming with Custom Transforms

To implement dynamic theming in React, you'll need:

  1. Exported theme-specific JSON tokens from Figma.

  2. Style Dictionary setup to handle light and dark tokens, with appropriate transforms and formats.

  3. Integration of generated themes into your React application, using context, CSS variables, or libraries like styled-components.

Below is a React-based implementation focusing on colors.

Step 1: Export Tokens from Figma

Export your Figma tokens into tokens/light/color.json and tokens/dark/color.json:

tokens/light/color.json

json

{
  "color": {
    "background": {
      "primary": { "value": "#FFFFFF", "type": "color" }
    },
    "text": {
      "default": { "value": "#212529", "type": "color" }
    }
  }
}
tokens/dark/color.json
json
{
  "color": {
    "background": {
      "primary": { "value": "#212529", "type": "color" }
    },
    "text": {
      "default": { "value": "#FFFFFF", "type": "color" }
    }
  }
}

Step 2: Set up Style Dictionary Project

Install Style Dictionary:

bash
npm install --save-dev style-dictionary
Create style-dictionary.config.js:
js
const StyleDictionary = require('style-dictionary');
StyleDictionary.registerTransform({
  name: 'color/hex-css',
  type: 'value',
  matcher: prop => prop.attributes.category === 'color',
  transformer: prop => prop.value.toLowerCase()
});
StyleDictionary.registerFormat({
  name: 'javascript/theme-module',
  formatter: ({ dictionary, options }) => {
    const className = options.className || 'theme';
    return `export const ${className} = {\n${dictionary.allTokens
      .map(t => `  "${t.name}": "${t.value}",`)
      .join('\n')}\n};\n`;
  }
});
function getStyleDictionaryConfig(theme) {
  return {
    source: [`tokens/${theme}/**/*.json`],
    platforms: {
      js: {
        transformGroup: 'js',
        transforms: ['attribute/cti', 'name/cti/kebab', 'color/hex-css'],
        buildPath: `build/react/${theme}/`,
        files: [
          {
            destination: 'theme.js',
            format: 'javascript/theme-module',
            options: { className: `${theme}Theme` }
          }
        ]
      }
    }
  };
}
module.exports = {
  buildAll: () => {
    ['light', 'dark'].forEach(theme => {
      console.log(`Building ${theme} theme...`);
      StyleDictionary.extend(getStyleDictionaryConfig(theme)).buildPlatform('js');
    });
    console.log('Build complete!');
  }
};

In package.json:

json
CopyEdit
"scripts": {
  "build-tokens": "node style-dictionary.config.js buildAll"
}
Run:
bash
npm run build-tokens
This generates:
bash
build/react/light/theme.js
build/react/dark/theme.js
Each exports:
js
export const lightTheme = {
  "color-background-primary": "#ffffff",
  "color-text-default": "#212529"
};

Step 3: Integrate into React Application

You can integrate these themes in a React app using styled-components, Emotion, CSS variables, or context.

Example with styled-components

Install:

bash
CopyEdit
npm install styled-components
Create theme exports:
js
// src/themes/index.js
export { lightTheme } from '../../build/react/light/theme';
export { darkTheme } from '../../build/react/dark/theme';
Use in App:
jsx
// src/App.jsx
import React, { useState } from 'react';
import { ThemeProvider } from 'styled-components';
import { lightTheme, darkTheme } from './themes';
function App() {
  const [isDark, setIsDark] = useState(false);
  const theme = isDark ? darkTheme : lightTheme;
  return (
    <ThemeProvider theme={theme}>
      <div style={{
        backgroundColor: theme['color-background-primary'],
        color: theme['color-text-default'],
        height: '100vh',
        padding: '2rem'
      }}>
        <h1>Dynamic Theming with Style Dictionary</h1>
        <button onClick={() => setIsDark(!isDark)}>
          Toggle to {isDark ? 'Light' : 'Dark'} Theme
        </button>
      </div>
    </ThemeProvider>
  );
}

export default App;

Beyond Colors: Applying to Other Tokens

The same approach applies to spacing, typography, border radius, shadows, etc. You’d:

  • Export tokens from Figma (e.g., spacing, typography).

  • Add transforms to convert units (e.g., px or rem to numbers or strings).

  • Create custom formats to output theme objects or CSS variable definitions.

For example, you can define spacing tokens as:

json

{
  "spacing": {
    "small": { "value": "8px", "type": "spacing" },
    "medium": { "value": "16px", "type": "spacing" }
  }
}

Then generate JavaScript objects:

js

export const spacing = {
  "spacing-small": "8px",
  "spacing-medium": "16px"
};

Conclusion

Using Style Dictionary along with Figma and React provides a consistent, scalable theming pipeline:

  • Single source of truth in Figma.

  • Automatic code generation for multiple themes.

  • Consistent and error-free theme application in React.

  • Easy extension to support multiple brands, modes, or platforms.

This workflow accelerates development, minimizes manual work, and keeps your React app styles perfectly aligned with your design system.

Streamline Your Design-to-Code Workflow

Looking to automate your token pipeline without building it all yourself? Explore Superflex.ai an automation platform that keeps your design system in sync with Figma and generates ready-to-use code for React, Flutter, and more.