Browse docs
Browse docs
The semantic token system that connects your brand identity to every component in Dashforge applications.
Design tokens are the foundational layer of the Dashforge theme system. Instead of styling components with raw color values, you define semantic meaning — "this is my primary brand color", "this is a success state" — and the system propagates those decisions everywhere automatically.
import { createDashTheme } from './theme/createDashTheme';
import { DashforgeThemeProvider } from '@dashforge/theme-mui';
const myTheme = createDashTheme({
color: {
intent: {
primary: '#7c3aed', // Brand purple
success: '#059669', // Emerald green
},
},
});
function App() {
return (
<DashforgeThemeProvider theme={myTheme}>
<MyApp />
</DashforgeThemeProvider>
);
}Override 2 tokens → 10+ components update instantly.
See how token changes propagate across multiple components consistently.
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
import { createDashTheme } from '@dashforge/tokens';
import { createMuiThemeFromDashTheme } from '@dashforge/theme-mui';
const customTheme = createDashTheme({
color: { intent: { primary: '#7c3aed' } },
});
const muiTheme = createMuiThemeFromDashTheme(customTheme);Design tokens solve three critical problems in product development.
Without Design Tokens
With Design Tokens
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.
You are not choosing colors. You are defining meaning.
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.
// ❌ 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>Dashforge tokens are organized by purpose, not by color. Learn how to choose the right token for your use case.
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, md, lg, xl)
├── spacing
│ └── unit // Base spacing unit (8px)
├── radius
│ └── sm/md/lg/pill // Border radius values
└── shadow
└── sm/md/lg // Elevation shadows❌ Wrong — everything is primary:
<Button color="primary">Save</Button>
<Button color="primary">Cancel</Button>
<Alert severity="info">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| Condition | Token | Example |
|---|---|---|
| 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 |
See how semantic tokens enable multi-tenant theming. Same components, different brand identities.
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.
Modern, energetic brand for a SaaS product
Branded content container
Professional, trustworthy brand for finance
Branded content container
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 remain consistent across tenants.
// Per-tenant theme: only 1 token changed
const tenantTheme = createDashTheme({
color: { intent: { primary: '#7c3aed' } },
});
// Same components, different brand
<ThemeProvider theme={createMuiThemeFromDashTheme(tenantTheme)}>
<Button variant="contained">Call to Action</Button>
</ThemeProvider>Dashforge uses an adapter pattern to integrate with Material-UI. Always customize Dashforge tokens, never MUI directly.
❌ 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 the Dashforge provider:
import { createDashTheme } from './theme/createDashTheme';
import { DashforgeThemeProvider } from '@dashforge/theme-mui';
const myTheme = createDashTheme({
color: {
intent: {
primary: '#7c3aed',
},
},
});
function App() {
return (
<DashforgeThemeProvider theme={myTheme}>
<MyApp />
</DashforgeThemeProvider>
);
}Why this matters:
primary the same wayComplete reference for all Dashforge tokens. Use these through createDashTheme() — avoid direct component-level overrides.
Semantic colors that communicate intent and meaning across your UI.
// Color intent tokens visualized
// dashTheme.color.intent.primary → #2563EB
// dashTheme.color.intent.success → #15803D
// dashTheme.color.intent.danger → #DC2626| Token | Description |
|---|---|
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 |
Background colors for surfaces at different elevation levels.
// Surface tokens visualized
// dashTheme.color.surface.canvas → #FFFFFF (base)
// dashTheme.color.surface.elevated → #F9FAFB (cards)
// dashTheme.color.surface.overlay → #FFFFFF (modals)| Token | Description |
|---|---|
canvas | Base application background |
elevated | Raised surfaces (cards, dialogs) |
overlay | Modal overlays, backdrops |
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
// Text tokens visualized
// dashTheme.color.text.primary → #111827
// dashTheme.color.text.secondary → #4B5563
// dashTheme.color.text.muted → #6B7280
// dashTheme.color.text.inverse → #FFFFFF| Token | Description |
|---|---|
primary | Primary body text |
secondary | Supporting text, labels |
muted | Disabled text, placeholders |
inverse | Text on dark backgrounds |
Border radius values for consistent rounded corners across components.
// Radius scale tokens visualized
// dashTheme.radius.sm → 4px
// dashTheme.radius.md → 8px
// dashTheme.radius.lg → 12px
// dashTheme.radius.pill → 999px| Token | Description |
|---|---|
sm | 4px — Small components |
md | 8px — Default rounding |
lg | 12px — Cards, panels |
pill | 999px — Pills, avatars |
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: {
primary: string;
secondary: string;
success: string;
warning: string;
danger: string;
info: string;
};
surface: {
canvas: string;
elevated: string;
overlay: string;
};
text: {
primary: string;
secondary: string;
muted: string;
inverse: string;
};
border: {
subtle: string;
default: string;
strong: string;
focus: string;
};
backdrop: { dim: string };
};
typography: {
fontFamily: string;
scale: { xs: string; sm: string; md: string; lg: string; xl: string };
};
radius: { sm: number; md: number; lg: number; pill: number };
shadow: { sm: string; md: string; lg: string };
spacing: { unit: number };
fieldLayout: {
stacked: { labelGap: number; helperGap: number };
inline: { labelWidth: number; controlGap: number; helperGap: number };
};
}import { createDashTheme } from './theme/createDashTheme';
// Partial overrides with full type safety
const customTheme = createDashTheme({
color: {
intent: {
primary: '#7c3aed', // TypeScript ensures valid color string
success: '#059669',
},
surface: {
canvas: '#fafafa', // Light mode background
},
},
radius: {
lg: 16, // TypeScript ensures valid number
},
});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() passed to DashforgeThemeProvider.
❌ 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.