Design Tokens
Define your application's visual language through semantic design tokens. Change primary once, see it reflected everywhere.
Quick Start
Copy & Paste
import { createDashTheme } from './createDashTheme';
import { createMuiThemeFromDashTheme } from '@dashforge/theme-mui';
const myTheme = createDashTheme({
color: {
intent: {
primary: '#7c3aed', // Brand purple
success: '#059669', // Emerald green
},
},
});
const muiTheme = createMuiThemeFromDashTheme(myTheme);Override 2 tokens → 10+ components update instantly
Live Examples
See how token changes affect multiple components consistently
Live Token Demo
This is proof that tokens control the UI system. Change the primary token below and watch multiple components update consistently.
Primary Token:
#2563EB
✓ 1 token changed → 3+ components updated instantly
Why This Matters
Design tokens solve three critical problems in product development
Without Design Tokens
- Inconsistent UI
- Hardcoded colors everywhere
- Theme changes are slow and error-prone
- No scalable branding
With Design Tokens
- Consistent UI across the entire app
- Centralized semantic control
- Instant global updates
- Multi-tenant ready
1
Consistency at Scale
Change one token and update your entire UI consistently. No scattered values, no broken designs.
2
Faster Product Iteration
Rebrand, theme, or adjust system colors without rewriting components. Ship faster.
3
Multi-Brand Ready
Use the same codebase with different tenant identities. White-label at scale.
Design tokens are not a styling convenience. They are the foundation of a scalable UI system.
Mental Model
You are not choosing colors. You are defining meaning.
⚠️ If you treat tokens like colors, you are using Dashforge wrong.
Three Rules for Success
1
Define meaning, not appearance
Tokens express semantic intent (primary = "brand action"), not visual properties.
2
One token should affect many components
Changing primary updates buttons, links, focus states, checkboxes—everywhere.
3
Meaning stays stable even if appearance changes
Success can be green in default theme, blue in color-blind mode. The meaning never changes.
Example: WRONG vs CORRECT
// ❌ WRONG: Treating tokens like colors
<Button sx={{ bgcolor: '#7c3aed' }}>Click</Button>
// ✅ CORRECT: Using semantic intent
const theme = createDashTheme({
color: { intent: { primary: '#7c3aed' } }
});
<Button color="primary">Click</Button>Token Structure
Dashforge tokens are organized by purpose, not by color. Learn how to choose the right token for your use case.
Token Hierarchy
DashforgeTheme
├── color
│ ├── intent // Semantic colors (primary, success, etc.)
│ ├── surface // Background layers (canvas, elevated, overlay)
│ ├── text // Text colors (primary, secondary, muted, inverse)
│ └── border // Border colors
├── typography
│ ├── fontFamily
│ └── scale // Font sizes (xs, sm, base, lg, xl, etc.)
├── spacing
│ └── scale // Spacing values (1-12)
├── radius
│ └── scale // Border radius (xs, sm, md, lg, xl, full)
└── shadow
└── scale // Elevation shadows (sm, md, lg, xl)⚠️ Don't Overuse Primary
Common mistake: Using primary for everything that's not an error.
Reserve primary for brand identity and primary actions. Use info for neutral notifications, secondary for less prominent UI.
Choosing the Right Token
❌ Wrong
// Everything is primary <Button color="primary"> Save </Button> <Button color="primary"> Cancel </Button> <Alert severity="primary"> Info message </Alert> // No semantic hierarchy
✅ Correct
// Semantic intent <Button color="primary"> Save </Button> <Button color="secondary"> Cancel </Button> <Alert severity="info"> Info message </Alert> // Clear visual hierarchy
Quick Decision Guide
Brand or main action
primary
Sign Up button, brand logo color
Success or positive feedback
success
Form submitted, payment processed
Caution or reversible warning
warning
Unsaved changes, approaching limit
Error or destructive action
danger
Delete account, critical failure
Neutral information
info
Tip, system notification
Secondary or less prominent
secondary
Cancel button, muted accent
Remember: Tokens represent meaning, not aesthetics.
If you find yourself choosing a token because you like the color, you're doing it wrong. Choose based on what the UI element means to the user.
Semantic Intents in Action
See how semantic tokens enable multi-tenant theming. Same components, different brand identities.
This is not a theme demo.
This is how you build a white-label SaaS product without rewriting your UI.
Same components. Same logic. Different brand per tenant.
Each tenant below uses identical component code—only the Design Tokens change. This is white-label product architecture done right.
Tech Startup
Modern, energetic brand for a SaaS product
Branded content container
Financial Services
Professional, trustworthy brand for finance
Branded content container
Healthcare
Calm, caring brand for medical services
Branded content container
Implementation: Each tenant theme is created with createDashTheme() by overriding only color.intent.primary. All other tokens (success, warning, error, surfaces, typography, spacing) remain consistent across tenants.
Theme Adapter
Dashforge uses an adapter pattern to integrate with Material-UI. Always customize Dashforge tokens, never MUI directly.
⚠️ Do Not Override MUI Theme Directly
If you use createTheme() directly, you bypass Dashforge's semantic system.
Always use: createDashTheme() → createMuiThemeFromDashTheme()
❌ Wrong: Bypassing Dashforge
import { createTheme } from '@mui/material/styles';
// ❌ DO NOT DO THIS
const myTheme = createTheme({
palette: {
primary: {
main: '#7c3aed',
},
},
});
// You just broke semantic consistency✅ Correct: Using Dashforge Adapter
import { createDashTheme } from './theme/createDashTheme';
import { createMuiThemeFromDashTheme } from '@dashforge/theme-mui';
// ✅ DO THIS
const dashTheme = createDashTheme({
color: {
intent: {
primary: '#7c3aed',
},
},
});
const muiTheme = createMuiThemeFromDashTheme(dashTheme);
// Semantic meaning preserved, MUI integration automaticWhy This Matters:
- Consistency: All components interpret
primarythe same way - Multi-Tenant: Change one token, rebrand the entire app
- Type Safety: Dashforge tokens are strongly typed, preventing mistakes
- Future-Proof: When we add new tokens, your customizations still work
Bottom line: If you need to customize MUI beyond what Dashforge provides, open an issue. Do not work around the system—extend it correctly.
Customization Scenarios
Real-world examples: SaaS brand, multi-tenant, dark theme, high contrast
API Reference
Complete reference for all Dashforge tokens. Use these through createDashTheme()—avoid direct component-level overrides.
This API represents the semantic foundation of your UI.
Prefer token overrides over component-level styling. Always customize tokens through createDashTheme(). Do not override individual component styles directly unless absolutely necessary.
Color Intent Tokens
Semantic colors that communicate intent and meaning across your UI.
primary
Brand identity, primary actions
secondary
Secondary actions, less prominent UI
success
Successful operations, positive feedback
warning
Caution, reversible warnings
danger
Errors, destructive actions
info
Neutral information, tips
Surface Tokens
Background colors for surfaces at different elevation levels.
canvas
Base application background
elevated
Raised surfaces (cards, dialogs)
overlay
Modal overlays, backdrops
Text Tokens
Text colors for different hierarchy and prominence levels.
The quick brown fox jumps over the lazy dogprimary
The quick brown fox jumps over the lazy dogsecondary
The quick brown fox jumps over the lazy dogmuted
The quick brown fox jumps over the lazy doginverse
primary
Primary body text
secondary
Supporting text, labels
muted
Disabled text, placeholders
inverse
Text on dark backgrounds
Radius Scale
Border radius values for consistent rounded corners across components.
sm
4px - Small components
md
8px - Default rounding
lg
12px - Cards, panels
pill
999px - Pills, avatars
Full Type Reference
Complete TypeScript interface for the Dashforge theme system. All tokens are strongly typed.
export interface DashforgeTheme {
meta: {
name: string;
version: string;
mode: 'light' | 'dark';
};
color: {
intent: ColorIntent;
surface: ColorSurface;
text: ColorText;
border: string;
};
typography: {
fontFamily: string;
scale: TypographyScale;
};
spacing: {
scale: SpacingScale;
};
radius: {
scale: RadiusScale;
};
shadow: {
scale: ShadowScale;
};
}
export interface ColorIntent {
primary: string;
secondary: string;
success: string;
warning: string;
danger: string;
info: string;
}
export interface ColorSurface {
canvas: string;
elevated: string;
overlay: string;
}
export interface ColorText {
primary: string;
secondary: string;
muted: string;
inverse: string;
}
export interface RadiusScale {
xs: string;
sm: string;
md: string;
lg: string;
xl: string;
full: string;
}
export interface TypographyScale {
xs: string;
sm: string;
base: string;
lg: string;
xl: string;
'2xl': string;
'3xl': string;
'4xl': string;
}
export interface SpacingScale {
1: string;
2: string;
3: string;
4: string;
5: string;
6: string;
8: string;
10: string;
12: string;
}
export interface ShadowScale {
sm: string;
md: string;
lg: string;
xl: string;
}Type-Safe Customization
import { createDashTheme } from './theme/createDashTheme';
import type { DashforgeTheme } from '@dashforge/tokens';
// Partial overrides with type safety
const customTheme = createDashTheme({
color: {
intent: {
primary: '#7c3aed', // TypeScript ensures valid color string
success: '#059669',
},
surface: {
canvas: '#fafafa', // Light mode background
},
},
radius: {
scale: {
md: '12px', // TypeScript ensures valid CSS value
lg: '16px',
},
},
});
// Full theme is type-safe
const theme: DashforgeTheme = customTheme;Source of Truth: For the complete, up-to-date type definitions, see:
libs/dashforge/tokens/src/theme/types.ts
Common Mistakes & Best Practices
Learn what NOT to do. These mistakes break the semantic system.
❌
Using primary for everything
Reserve primary for brand identity and main actions. Using it everywhere destroys semantic hierarchy and makes your UI look like one big call-to-action.
❌
Hardcoding colors in components
Hardcoded colors break system consistency. Every hardcoded value is a future bug when you need to rebrand or support dark mode.
❌
Overriding MUI theme directly
Bypassing the Dashforge adapter breaks the semantic layer. Always use createDashTheme() + createMuiThemeFromDashTheme().
❌
Treating tokens as design variables
Tokens are not CSS variables you tweak for aesthetics. They represent meaning. Choose tokens based on intent, not appearance.
✅
Thinking in intent, not appearance
Ask "what does this UI element mean?" not "what color looks good?". Success means positive outcome. Danger means destructive action. Primary means brand identity.
When NOT to use tokens
Tokens are for system-level decisions. If you need a one-off color for a specific component (like a logo or illustration), use inline styles. Do not pollute the token system with component-specific values.