Skip to main content

Source: ocean/docs/design-system-workflow.md | ✏️ Edit on GitHub

Design System Workflow: Figma + next-themes + TanStack Router

Overview

This document outlines the best practices for integrating Figma design tokens with our React application using next-themes for theme management.

Architecture

┌─────────────┐     ┌──────────────┐     ┌──────────────┐     ┌─────────────┐
│ Figma │ --> │ Design Tokens│ --> │ CSS Variables│ --> │ next-themes │
│ (Source) │ │ (JSON) │ │ (tokens) │ │ (Runtime) │
└─────────────┘ └──────────────┘ └──────────────┘ └─────────────┘

1. Design Token Structure

In Figma

Organize your design tokens in Figma using this structure:

Design System/
├── 🎨 Semantic Tokens
│ ├── Light Theme
│ │ ├── background
│ │ ├── foreground
│ │ ├── primary
│ │ └── ...
│ └── Dark Theme
│ ├── background
│ ├── foreground
│ ├── primary
│ └── ...
├── 🔤 Typography
│ ├── Font Families
│ ├── Font Sizes
│ └── Line Heights
└── 📏 Spacing
├── Padding
└── Margins

Token Export Format

Use Figma Tokens plugin to export in this format:

{
"global": {
"spacing": {
"xs": "0.25rem",
"sm": "0.5rem",
"md": "1rem"
},
"typography": {
"fontFamily": {
"sans": "system-ui, sans-serif"
}
}
},
"light": {
"color": {
"background": "#FFFFFF",
"foreground": "#09090B",
"primary": "#18181B"
}
},
"dark": {
"color": {
"background": "#09090B",
"foreground": "#FAFAFA",
"primary": "#FAFAFA"
}
}
}

2. CSS Variable Implementation

Token Conversion

Convert Figma tokens to CSS variables in /src/styles/tokens.css:

@layer base {
:root {
/* Light theme (default) */
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--primary: 240 5.9% 10%;

/* Global tokens (theme-independent) */
--radius: 0.5rem;
--font-sans: system-ui, sans-serif;
}

.dark {
/* Dark theme overrides */
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--primary: 0 0% 98%;
}
}

3. next-themes Integration

Setup (already implemented)

// src/routes/__root.tsx
import { ThemeProvider } from 'next-themes'
;<ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<App />
</ThemeProvider>

Usage in Components

import { useTheme } from 'next-themes'

function ThemeToggle() {
const { theme, setTheme } = useTheme()

return <button onClick={() => setTheme(theme === 'dark' ? 'light' : 'dark')}>Toggle theme</button>
}

4. Figma Integration Workflow

Step 1: Design in Figma

  1. Use only semantic tokens in designs
  2. Never use raw color values
  3. Test designs in both light and dark themes

Step 2: Export Tokens

  1. Use Figma Tokens plugin
  2. Export as JSON
  3. Place in design-tokens/figma-tokens.json

Step 3: Transform Tokens

Create a script to transform Figma tokens to CSS:

// scripts/transform-tokens.js
const tokens = require('../design-tokens/figma-tokens.json')

function hexToHSL(hex) {
// Convert hex to HSL for better theme flexibility
// Implementation here
}

function generateCSS(tokens) {
// Generate CSS variables from tokens
// Implementation here
}

Step 4: Update CSS Variables

Run the transformation:

node scripts/transform-tokens.js > src/styles/tokens.css

5. Component Development

Best Practices

  1. Always use semantic tokens

    // ✅ Good
    <div className="bg-background text-foreground">

    // ❌ Bad
    <div className="bg-white text-black">
  2. Create theme-aware components

    // ✅ Good - Uses CSS variables
    <Card className="bg-card border-border">

    // ❌ Bad - Hardcoded colors
    <Card className="bg-gray-100 border-gray-300">
  3. Use Tailwind with CSS variables

    /* In tailwind config */
    colors: {
    background: 'hsl(var(--background))',
    foreground: 'hsl(var(--foreground))',
    }

6. Testing Themes

Visual Testing

  1. Toggle between light/dark in development
  2. Test with system preferences
  3. Verify no flash of incorrect theme

Automated Testing

// In tests
import { ThemeProvider } from 'next-themes'

function renderWithTheme(ui, { theme = 'light' } = {}) {
return render(
<ThemeProvider defaultTheme={theme} enableSystem={false}>
{ui}
</ThemeProvider>
)
}

7. CI/CD Integration

Token Validation

Add a GitHub Action to validate token changes:

- name: Validate Design Tokens
run: |
npm run tokens:validate
npm run tokens:build

Preview Deployments

Ensure preview deployments show both themes:

  • /preview/light - Force light theme
  • /preview/dark - Force dark theme

8. Design Handoff

For Designers

  1. Always specify which tokens are used
  2. Provide both light and dark variants
  3. Document any new tokens needed

For Developers

  1. Check if tokens exist before implementing
  2. Request new tokens if needed
  3. Never create ad-hoc colors

9. Token Governance

Adding New Tokens

  1. Designer proposes in Figma
  2. Team reviews semantic naming
  3. Developer implements in both themes
  4. Update documentation

Deprecating Tokens

  1. Mark as deprecated in Figma
  2. Add console warning in dev
  3. Migrate components
  4. Remove after migration

10. Tools and Resources

  • Figma Tokens: For managing design tokens in Figma
  • Style Dictionary: For transforming tokens (alternative to custom scripts)
  • Chromatic: For visual regression testing with themes

VSCode Extensions

  • Tailwind CSS IntelliSense: Autocomplete for custom CSS variables
  • Color Highlight: Preview color values in code

Browser Extensions

  • Figma to Code: Quick token reference
  • Theme Switcher: Test theme transitions

Conclusion

This workflow ensures:

  1. Single source of truth (Figma)
  2. Automated token synchronization
  3. Type-safe theme switching
  4. Consistent user experience
  5. Easy theme maintenance

The combination of Figma tokens, CSS variables, and next-themes provides a robust, scalable design system that works perfectly with TanStack Router and modern React applications.