Mahamudul Hasan Rubel
HomeBlogCoursesAboutProjectsSkillsExperiencePhotosContact
Mahamudul Hasan Rubel

Senior Software Engineer crafting high-performance web applications and SaaS platforms.

Navigation

  • Home
  • Blog
  • Courses
  • About
  • Projects
  • Skills
  • Experience
  • Photos
  • Contact

Get in Touch

Available for senior/lead roles and consulting.

bd.mhrubel@gmail.comHire Me

Subscribe to the newsletter

Get new articles and course lessons delivered to your inbox. No spam, unsubscribe anytime.

© 2026 Mahamudul Hasan Rubel. All rights reserved.

Built with using Next.js 16 & Tailwind v4

Back to Blog
Lesson 40 of the Advanced React: Performance, Architecture & Patterns course
ReactJune 28, 20263 min read

Building Design System Primitives: Tokens and Theming

Learn to build a scalable Design System using design tokens and theme-aware components. Eliminate hardcoded values and enforce UI consistency in React apps.

ReactDesign SystemCSS-in-JSThemingConsistencyjavascriptfrontend

Previously in this course, we explored using Portals for UI overlays to handle complex, detached DOM structures. Now, we shift our focus from functional DOM placement to visual architectural integrity: building a Design System that scales.

In large-scale React applications, "style drift" is the silent killer of productivity. When developers hardcode hex values or spacing units, the UI loses its cohesion. Today, we define the foundation of a robust Design System by implementing design tokens and theme-aware components.

What are Design Tokens?

Design tokens are the atomic building blocks of your UI. Instead of using raw values like #3b82f6 or 16px directly in your components, you define a semantic mapping.

  • Global Tokens: Raw values (e.g., blue-500: #3b82f6).
  • Alias Tokens: Purpose-driven values (e.g., brand-primary: var(--blue-500)).
  • Component Tokens: Contextual values (e.g., button-bg: var(--brand-primary)).

By decoupling the value from the intent, you enable theming and global style updates without touching a single component file.

Implementing Themed Components

To enforce consistency, we move away from standard CSS and toward a CSS-in-JS or CSS Variable approach. Let's build a theme provider that leverages CSS variables for maximum performance and compatibility.

The Token Foundation

First, define your design tokens in a central configuration object.

JAVASCRIPT
// tokens.js
export const themeTokens = {
  light: {
    CE9178">'--color-bg': CE9178">'#ffffff',
    CE9178">'--color-text': CE9178">'#1a1a1a',
    CE9178">'--spacing-md': CE9178">'16px',
  },
  dark: {
    CE9178">'--color-bg': CE9178">'#1a1a1a',
    CE9178">'--color-text': CE9178">'#f0f0f0',
    CE9178">'--spacing-md': CE9178">'16px',
  }
};

The Themed Wrapper

We use a ThemeProvider to inject these tokens into the root of our application. This allows us to switch themes dynamically by simply swapping the CSS variable definitions.

JSX
// ThemeProvider.jsx
import { createContext, useContext, useEffect } from CE9178">'react';

const ThemeContext = createContext(CE9178">'light');

export const ThemeProvider = ({ theme, children }) => {
  useEffect(() => {
    const root = document.documentElement;
    const tokens = themeTokens[theme];
    
    Object.entries(tokens).forEach(([key, value]) => {
      root.style.setProperty(key, value);
    });
  }, [theme]);

  return (
    <ThemeContext.Provider value={theme}>
      {children}
    </ThemeContext.Provider>
  );
};

Enforcing Consistency with Primitives

To ensure developers don't bypass the system, we create "Primitive" components. These are low-level building blocks like Box, Text, and Stack that expose our design tokens as a strict API.

JSX
// Box.jsx
import styled from CE9178">'styled-components';

export const Box = styled.divCE9178">`
  background-color: var(--color-bg);
  color: var(--color-text);
  padding: var(--spacing-md);
  transition: background-color 0.2s ease;
`;

By wrapping our layout logic in these primitives, we ensure that every Box in the application automatically responds to theme changes and adheres to our spacing scale.

Practice Exercise: Implementing a Theme Switcher

Your task is to extend the ThemeProvider to support a user-defined theme toggle.

  1. Create a useTheme hook that exposes the current theme and a toggleTheme function.
  2. Build a ThemeToggle button that updates the state in the ThemeProvider.
  3. Ensure that switching the theme triggers a smooth transition for all Box components using the CSS variable system.

Common Pitfalls

  • Over-tokenizing: Don't create a token for every single value. If a value isn't reused or doesn't have semantic meaning (like a specific border-radius for one unique card), keep it as a local style.
  • Ignoring Performance: If you use CSS-in-JS libraries that generate classes dynamically for every prop change, you'll bloat your CSSOM. Prefer static CSS variables for theme switching.
  • Hardcoding Units: Always use your tokens (e.g., var(--spacing-md)) rather than raw numbers. If you find yourself writing padding: 16px, create a new token.

Recap

Building a Design System requires a shift in mindset: stop thinking about pixels and start thinking about intent. By implementing CSS-in-JS patterns or CSS variables, you enable theming as a first-class citizen. This approach guarantees consistency across your application, making it easier to maintain and faster to scale.

As you advance, remember that your design system should evolve with your application. If you're struggling with data-heavy views, consider how these UI primitives might integrate with API Design Caching Strategies or the API Design Soft Delete Patterns we've discussed for backend stability.

Up next: Managing Large-Scale Data Fetching.

Previous lessonImplementing Virtualized ListsNext lesson Managing Large-Scale Data Fetching
Back to Blog

Similar Posts

ReactJune 28, 20263 min read

Security Best Practices in React: Hardening Your Production Apps

Master Security Best Practices in React by learning to sanitize inputs, implement CSP, and manage data flow to prevent XSS and sensitive data leakage.

Read more
ReactJune 28, 20264 min read

Micro-Frontends with React: Mastering Module Federation Architecture

Learn to architect scalable micro-frontends with React and Module Federation. Discover how to manage shared dependencies and handle cross-app communication.

Part of the course

Advanced React: Performance, Architecture & Patterns

advanced · Lesson 40 of 47

  1. 1

    Deep Dive into the Reconciliation Algorithm

    4 min
  2. 2

    Profiling with React DevTools

    3 min
  3. 3

    Establishing Performance Budgets

    3 min
Read more
ReactPerformanceJune 28, 20264 min read

Managing Large-Scale Data Fetching: Orchestration and Cancellation

Master Data Fetching orchestration in large-scale React apps. Learn to manage parallel requests, handle complex dependencies, and implement robust cancellation.

Read more
  • 4

    Strategic use of React.memo

    3 min
  • 5

    Mastering useCallback and useMemo

    4 min
  • 6

    State Colocation Strategies

    4 min
  • 7

    Optimizing Context Providers

    4 min
  • 8

    Advanced Context Composition

    4 min
  • 9

    Eliminating Prop Drilling

    4 min
  • 10

    Introduction to Concurrent React

    4 min
  • 11

    Non-blocking UI with useTransition

    4 min
  • 12

    Handling Deferred Data with useDeferredValue

    3 min
  • 13

    Mastering Suspense for Data Fetching

    4 min
  • 14

    Streaming Server-Side Rendering

    3 min
  • 15

    Designing Compound Components

    3 min
  • 16

    The Render Props Pattern

    4 min
  • 17

    Implementing Control Props

    4 min
  • 18

    Headless UI Architectures

    3 min
  • 19

    Modular Directory Structures

    3 min
  • 20

    Refactoring Monolithic Components

    3 min
  • 21

    Optimistic UI Updates

    3 min
  • 22

    Advanced Cache Invalidation

    4 min
  • 23

    Handling Race Conditions

    4 min
  • 24

    Server-Client State Synchronization

    3 min
  • 25

    Route-level Code Splitting

    4 min
  • 26

    Offloading Tasks with Web Workers

    3 min
  • 27

    Advanced Error Boundaries

    3 min
  • 28

    Monitoring Production Performance

    4 min
  • 29

    Final Project Audit & Optimization

    4 min
  • 30

    Advanced Hook Patterns

    3 min
  • 31

    Managing Global State with Zustand/Redux

    4 min
  • 32

    Testing Performance-Critical Components

    4 min
  • 33

    Static Site Generation (SSG) Patterns

    4 min
  • 34

    Internationalization (i18n) Architecture

    3 min
  • 35

    Accessibility (a11y) in Advanced Components

    4 min
  • 36

    Managing Third-Party Integrations

    3 min
  • 37

    Advanced Form Handling

    4 min
  • 38

    Using Portals for UI Overlays

    4 min
  • 39

    Implementing Virtualized Lists

    4 min
  • 40

    Building Design System Primitives

    3 min
  • 41

    Managing Large-Scale Data Fetching

    4 min
  • 42

    Micro-Frontends with React

    4 min
  • 43

    Security Best Practices in React

    3 min
  • 44

    Advanced Ref Usage

    Coming soon
  • 45

    Memoization Pitfalls

    Coming soon
  • 46

    Mastering React Patterns for Scalability

    Coming soon
  • 47

    Advanced TypeScript with React

    Coming soon
  • View full course