Material UI theming and design tokens
Version 1.0.0
Note: This document is for agents and LLMs implementing themes and design tokens with Material UI. Grounded in
docs/data/material/customization/(theming, palette, dark-mode, css-theme-variables, typography, spacing, shape).
Abstract
A Material UI theme is a single object of design tokens (palette, typography, spacing, shape, breakpoints, etc.) plus optional per-component defaults (theme.components). Apps typically call createTheme once (or in composed steps), pass the result to ThemeProvider near the root, and read values with useTheme, sx, or styled. For system-driven light/dark, prefer colorSchemes and related APIs over a static palette.mode-only setup when you need toggling, tab sync, and SSR-friendly behavior; enable cssVariables when you want theme.vars, fewer theme nests for dark regions, and clearer debugging via --mui-* CSS variables.
Table of contents
- Core setup
- Where tokens live (design token map)
- Palette quick facts
- Color schemes vs palette-only dark
- CSS theme variables (
cssVariables: true) - Typography and spacing
- Composing and merging themes
- Nesting
ThemeProvider - Custom tokens (brand-specific design keys)
- Further reading
Core setup
import { createTheme, ThemeProvider } from '@mui/material/styles'(Material UI default theme).- Build a theme with
createTheme({ ... }); wrap the app in<ThemeProvider theme={theme}>so descendants receive context. - Use
<CssBaseline />inside the provider when you want baseline element styles and correct dark background behavior (see Dark mode).
Access in components: useTheme() from @mui/material/styles.
Where tokens live (design token map)
| Area | Role | Doc |
|---|---|---|
palette | Semantic colors (primary, secondary, error, …), text, background, divider, action | Palette |
typography | fontFamily, fontSize, variants (h1 through body2, button, …) | Typography |
spacing | theme.spacing(n) scale (default 8px per unit) | Spacing |
shape | borderRadius (default 4); optional extra radii need TypeScript augmentation | Shape |
breakpoints | Responsive keys for sx / media queries | Breakpoints |
zIndex | Layering tokens | z-index |
transitions | Duration / easing helpers | Transitions |
components | defaultProps, styleOverrides, variants per Mui* key | Themed components |
Full defaults: Default theme explorer.
Palette quick facts
- Each palette color is usually
main,light,dark,contrastText. Supplyingmainalone is often enough;createThemecan derive the rest. - Use
@mui/material/colors(for examplepurple[500]) for Material Design hues when building a palette. palette.mode: 'dark'forces a dark palette for the whole theme; if you use a fully custom palette with dark mode, ensure values match the mode (see Dark mode).
Color schemes vs palette-only dark
colorSchemes(for examplecolorSchemes: { dark: true }) enables built-in behavior: system preference, tab sync, optional transition disable on scheme change, storage, etc. Docs recommend it over the older, narrower palette-only approach for those features.- If both
colorSchemesandpaletteare set,palettetakes precedence. Avoid accidental overrides. useColorSchemereads/updates mode for toggling.modecan beundefinedon the first render; handle that to avoid hydration mismatches.ThemeProvidersupportsstorageManager,disableTransitionOnChange,noSsr, etc., for color-scheme UX and SSR (see Dark mode).
CSS theme variables (cssVariables: true)
- Set
cssVariables: trueincreateThemeso components usevar(--mui-...)values. Prefertheme.varsin style callbacks when variables are enabled (mirrors palette/typography as CSS var references). See Usage. - Do not pass a custom
varskey intocreateTheme. That key is reserved and autogenerated for this feature. - For dark-specific styles with CSS variables, use
theme.applyStyles('dark', { ... })rather than branching ontheme.palette.modein ways that cause flicker (see docs warning in Usage and Configuration). InitColorSchemeScript: place before any rendered content to prevent the initial color-scheme flash. App Router: inside<body>before{children}inapp/layout.tsx. Pages Router: in_document.tsxbefore<Main />. See Preventing SSR flickering.- Trade-offs: larger HTML (both schemes' variables), possible FCP impact; benefits include less JavaScript work on scheme switch and better SSR dark experience. See Overview.
CssVarsProvideris superseded byThemeProviderwith the same capabilities. UseThemeProvider.
Typography and spacing
- Typography uses
rem; default root sizing is documented on Typography. Adjusttypography.fontSizeor per-variant sizes as needed;responsiveFontSizes(theme)can scale typography across breakpoints. theme.spacing(k)follows the configured scale;sxspacing shorthands use the same system. Array-basedspacingin the theme has limitations (negative / fractional /'auto'). Prefer a function if you need full expressiveness (see Spacing).
Composing and merging themes
- When one token should derive from another, build in steps: call
createThemewith base options, thencreateTheme(theme, { ... })using the first result (see Theming—Using theme options to define other options). - Avoid relying on multiple arguments to
createThemefor merging; only the first argument is formally processed. Deep-merge yourself (for exampledeepmergefrom@mui/utils) and pass a single object for forward compatibility (see Theming—createTheme(options, ...args)).
Nesting ThemeProvider
Inner provider overrides outer. Pass theme={(outer) => createTheme({ ...outer, ... })}-style functions only when intentionally extending the parent theme (see Theming—Nesting the theme).
Custom tokens (brand-specific design keys)
Add keys on the theme (for example status.danger) inside createTheme, then augment TypeScript with declare module '@mui/material/styles' on Theme and ThemeOptions (see Theming—Custom variables). For extra palette fields, follow Palette customization patterns.
Do not use theme.vars as a custom property name; it is private to CSS variables support.
Further reading
| Topic | Link |
|---|---|
| Theming overview & API | Theming |
| Dark mode & toggling | Dark mode |
| CSS variables overview | CSS theme variables |
| Color tool / brand hues | Color |
| TypeScript theme customization | TypeScript—Customization of Theme |
TypeScript snippet templates: reference.md.