The Chakra UI theme system provides default design tokens, semantic tokens, component recipes, and configuration for customizing your application's appearance.
Pre-configured system and theme exports.
import {
defaultSystem,
defaultConfig,
system,
defaultBaseConfig,
defaultConditions,
defaultThemeConfig,
} from "@chakra-ui/react";
// Main system instance with default theme
const defaultSystem: SystemContext;
// Alias for defaultSystem
const system: SystemContext;
// Complete configuration with theme
const defaultConfig: SystemConfig;
// Base configuration without theme tokens
const defaultBaseConfig: SystemConfig;
// Default conditional styling conditions
const defaultConditions: Record<string, string>;
// Theme configuration object
const defaultThemeConfig: {
tokens: Tokens;
semanticTokens: SemanticTokens;
breakpoints: Record<string, string>;
keyframes: Record<string, CssKeyframes>;
recipes: Record<string, RecipeConfig>;
slotRecipes: Record<string, SlotRecipeConfig>;
textStyles: TextStyles;
layerStyles: LayerStyles;
animationStyles: AnimationStyles;
globalCss: GlobalStyleObject;
};Usage:
import { ChakraProvider, defaultSystem } from "@chakra-ui/react";
// Use default system
<ChakraProvider value={defaultSystem}>
<App />
</ChakraProvider>;
// Or create custom system
import { createSystem, defaultConfig } from "@chakra-ui/react";
const customSystem = createSystem({
...defaultConfig,
theme: {
...defaultConfig.theme,
tokens: {
...defaultConfig.theme?.tokens,
colors: {
...defaultConfig.theme?.tokens?.colors,
brand: {
50: { value: "#e6f2ff" },
500: { value: "#0066cc" },
// ...
},
},
},
},
});import type { Token, Tokens, TokenInterface } from "@chakra-ui/react";
interface Token<T = any> {
value: T;
description?: string;
}
interface Tokens {
colors?: Record<string, Token<string> | Record<string, Token<string>>>;
spacing?: Record<string, Token<string>>;
sizes?: Record<string, Token<string>>;
fonts?: Record<string, Token<string>>;
fontSizes?: Record<string, Token<string>>;
fontWeights?: Record<string, Token<number>>;
lineHeights?: Record<string, Token<string | number>>;
letterSpacings?: Record<string, Token<string>>;
radii?: Record<string, Token<string>>;
shadows?: Record<string, Token<string>>;
zIndex?: Record<string, Token<number>>;
borders?: Record<string, Token<string>>;
durations?: Record<string, Token<string>>;
easings?: Record<string, Token<string>>;
animations?: Record<string, Token<string>>;
blurs?: Record<string, Token<string>>;
spacing?: Record<string, Token<string>>;
breakpoints?: Record<string, Token<string>>;
assets?: Record<string, Token<string>>;
aspectRatios?: Record<string, Token<number>>;
opacity?: Record<string, Token<number>>;
}
// Token access interface
interface TokenInterface {
colors: Record<string, string>;
spacing: Record<string, string>;
sizes: Record<string, string>;
fonts: Record<string, string>;
fontSizes: Record<string, string>;
fontWeights: Record<string, number>;
lineHeights: Record<string, string | number>;
letterSpacings: Record<string, string>;
radii: Record<string, string>;
shadows: Record<string, string>;
zIndex: Record<string, number>;
borders: Record<string, string>;
durations: Record<string, string>;
easings: Record<string, string>;
// ... all token categories
}interface SemanticTokens {
colors?: Record<string, SemanticToken<string>>;
spacing?: Record<string, SemanticToken<string>>;
// ... same structure as Tokens
}
interface SemanticToken<T = any> {
value: T | { base?: T; _light?: T; _dark?: T; [condition: string]: T };
description?: string;
}Example:
const semanticTokens = {
colors: {
bg: {
value: { base: "{colors.white}", _dark: "{colors.gray.900}" },
},
text: {
value: { base: "{colors.gray.900}", _dark: "{colors.gray.100}" },
},
},
};All component recipes are available for customization.
import { recipes, slotRecipes } from "@chakra-ui/react/theme";
// Single-part component recipes
const recipes: {
badge: RecipeConfig;
button: RecipeConfig;
code: RecipeConfig;
heading: RecipeConfig;
input: RecipeConfig;
kbd: RecipeConfig;
link: RecipeConfig;
mark: RecipeConfig;
separator: RecipeConfig;
skeleton: RecipeConfig;
spinner: RecipeConfig;
text: RecipeConfig;
textarea: RecipeConfig;
// ... all single-part recipes
};
// Multi-part component recipes
const slotRecipes: {
accordion: SlotRecipeConfig;
actionBar: SlotRecipeConfig;
alert: SlotRecipeConfig;
avatar: SlotRecipeConfig;
blockquote: SlotRecipeConfig;
breadcrumb: SlotRecipeConfig;
card: SlotRecipeConfig;
checkbox: SlotRecipeConfig;
checkboxCard: SlotRecipeConfig;
clipboard: SlotRecipeConfig;
codeBlock: SlotRecipeConfig;
collapsible: SlotRecipeConfig;
colorPicker: SlotRecipeConfig;
combobox: SlotRecipeConfig;
dataList: SlotRecipeConfig;
dialog: SlotRecipeConfig;
drawer: SlotRecipeConfig;
editable: SlotRecipeConfig;
emptyState: SlotRecipeConfig;
field: SlotRecipeConfig;
fieldset: SlotRecipeConfig;
fileUpload: SlotRecipeConfig;
hoverCard: SlotRecipeConfig;
list: SlotRecipeConfig;
listbox: SlotRecipeConfig;
menu: SlotRecipeConfig;
nativeSelect: SlotRecipeConfig;
numberInput: SlotRecipeConfig;
pinInput: SlotRecipeConfig;
popover: SlotRecipeConfig;
progress: SlotRecipeConfig;
progressCircle: SlotRecipeConfig;
qrCode: SlotRecipeConfig;
radioCard: SlotRecipeConfig;
radioGroup: SlotRecipeConfig;
ratingGroup: SlotRecipeConfig;
scrollArea: SlotRecipeConfig;
segmentGroup: SlotRecipeConfig;
select: SlotRecipeConfig;
slider: SlotRecipeConfig;
stat: SlotRecipeConfig;
status: SlotRecipeConfig;
steps: SlotRecipeConfig;
switch: SlotRecipeConfig;
table: SlotRecipeConfig;
tabs: SlotRecipeConfig;
tag: SlotRecipeConfig;
timeline: SlotRecipeConfig;
toast: SlotRecipeConfig;
tooltip: SlotRecipeConfig;
treeView: SlotRecipeConfig;
// ... all multi-part recipes
};Individual recipes and slot recipes can be imported directly for custom usage or extension.
// Import individual single-part recipes
import {
badgeRecipe,
buttonRecipe,
checkmarkRecipe,
codeRecipe,
colorSwatchRecipe,
containerRecipe,
headingRecipe,
iconRecipe,
inputRecipe,
inputAddonRecipe,
kbdRecipe,
linkRecipe,
markRecipe,
radiomarkRecipe,
separatorRecipe,
skeletonRecipe,
skipNavLinkRecipe,
spinnerRecipe,
textareaRecipe,
} from "@chakra-ui/react/theme";
// Import individual slot recipes
import {
accordionSlotRecipe,
actionBarSlotRecipe,
alertSlotRecipe,
avatarSlotRecipe,
blockquoteSlotRecipe,
breadcrumbSlotRecipe,
cardSlotRecipe,
checkboxSlotRecipe,
checkboxCardSlotRecipe,
codeBlockSlotRecipe,
collapsibleSlotRecipe,
colorPickerSlotRecipe,
comboboxSlotRecipe,
dataListSlotRecipe,
dialogSlotRecipe,
drawerSlotRecipe,
editableSlotRecipe,
emptyStateSlotRecipe,
fieldSlotRecipe,
fieldsetSlotRecipe,
fileUploadSlotRecipe,
hoverCardSlotRecipe,
listSlotRecipe,
menuSlotRecipe,
nativeSelectSlotRecipe,
numberInputSlotRecipe,
pinInputSlotRecipe,
popoverSlotRecipe,
progressSlotRecipe,
progressCircleSlotRecipe,
qrCodeSlotRecipe,
radioCardSlotRecipe,
radioGroupSlotRecipe,
ratingGroupSlotRecipe,
scrollAreaSlotRecipe,
segmentGroupSlotRecipe,
selectSlotRecipe,
sliderSlotRecipe,
statSlotRecipe,
statusSlotRecipe,
stepsSlotRecipe,
switchSlotRecipe,
tableSlotRecipe,
tabsSlotRecipe,
tagSlotRecipe,
timelineSlotRecipe,
toastSlotRecipe,
tooltipSlotRecipe,
treeViewSlotRecipe,
} from "@chakra-ui/react/theme";
// Each recipe is a RecipeConfig or SlotRecipeConfig
type RecipeConfig = {
className: string;
base?: SystemStyleObject;
variants?: Record<string, Record<string, SystemStyleObject>>;
defaultVariants?: Record<string, string>;
};
type SlotRecipeConfig = {
className: string;
slots: string[];
base?: Record<string, SystemStyleObject>;
variants?: Record<string, Record<string, Record<string, SystemStyleObject>>>;
defaultVariants?: Record<string, string>;
};Usage Example:
import { buttonRecipe } from "@chakra-ui/react/theme";
import { createSystem } from "@chakra-ui/react";
// Extend the button recipe
const customButtonRecipe = {
...buttonRecipe,
variants: {
...buttonRecipe.variants,
visual: {
...buttonRecipe.variants.visual,
custom: { bg: "purple.500", color: "white" },
},
},
};
// Use in custom system
const customSystem = createSystem({
theme: {
recipes: {
button: customButtonRecipe,
},
},
});import { breakpoints } from "@chakra-ui/react/theme";
const breakpoints: {
sm: string; // "640px"
md: string; // "768px"
lg: string; // "1024px"
xl: string; // "1280px"
"2xl": string; // "1536px"
};import { keyframes } from "@chakra-ui/react/theme";
const keyframes: Record<string, CssKeyframes>;
interface CssKeyframes {
[key: string]: SystemStyleObject;
}import { textStyles } from "@chakra-ui/react/theme";
interface TextStyles {
xs: TextStyle;
sm: TextStyle;
md: TextStyle;
lg: TextStyle;
xl: TextStyle;
"2xl": TextStyle;
"3xl": TextStyle;
"4xl": TextStyle;
"5xl": TextStyle;
"6xl": TextStyle;
"7xl": TextStyle;
}
interface TextStyle {
fontSize: string;
lineHeight: string;
fontWeight?: string;
letterSpacing?: string;
}import { layerStyles } from "@chakra-ui/react/theme";
interface LayerStyles {
[key: string]: SystemStyleObject;
}import { animationStyles } from "@chakra-ui/react/theme";
interface AnimationStyles {
[key: string]: AnimationStyle;
}
interface AnimationStyle {
animationName: string;
animationDuration: string;
animationTimingFunction?: string;
animationDelay?: string;
animationIterationCount?: string | number;
animationDirection?: string;
animationFillMode?: string;
animationPlayState?: string;
}import { globalCss } from "@chakra-ui/react/theme";
const globalCss: GlobalStyleObject;
interface GlobalStyleObject {
[selector: string]: SystemStyleObject;
}interface SystemConfig {
preflight?: boolean;
cssVarsPrefix?: string;
cssVarsRoot?: string;
theme?: {
tokens?: Tokens;
semanticTokens?: SemanticTokens;
breakpoints?: Record<string, string>;
keyframes?: Record<string, CssKeyframes>;
recipes?: Record<string, RecipeConfig>;
slotRecipes?: Record<string, SlotRecipeConfig>;
textStyles?: TextStyles;
layerStyles?: LayerStyles;
animationStyles?: AnimationStyles;
globalCss?: GlobalStyleObject;
};
conditions?: Record<string, string>;
utilities?: Record<string, UtilityConfig>;
}import { cssVarsPrefix, cssVarsRoot } from "@chakra-ui/react/theme";
const cssVarsPrefix: string; // "chakra"
const cssVarsRoot: string; // ":where(:root, :host)"import type { ColorPalette } from "@chakra-ui/react";
type ColorPalette =
| "gray"
| "red"
| "orange"
| "yellow"
| "green"
| "teal"
| "blue"
| "cyan"
| "purple"
| "pink"
| "accent";import { createSystem, defaultConfig } from "@chakra-ui/react";
const customSystem = createSystem({
theme: {
tokens: {
colors: {
brand: {
50: { value: "#e6f2ff" },
100: { value: "#b3d9ff" },
200: { value: "#80c0ff" },
300: { value: "#4da6ff" },
400: { value: "#1a8cff" },
500: { value: "#0066cc" },
600: { value: "#0052a3" },
700: { value: "#003d7a" },
800: { value: "#002952" },
900: { value: "#001429" },
},
},
},
semanticTokens: {
colors: {
primary: {
value: "{colors.brand.500}",
},
},
},
},
});import { createSystem, defaultConfig } from "@chakra-ui/react";
const customSystem = createSystem({
theme: {
recipes: {
button: {
base: {
fontWeight: "bold",
borderRadius: "full",
},
variants: {
variant: {
custom: {
bg: "brand.500",
color: "white",
_hover: { bg: "brand.600" },
},
},
},
},
},
},
});Note: When extending defaultConfig, use optional chaining (?.) to safely access nested theme properties, as they may be undefined.
import { createSystem, defaultConfig } from "@chakra-ui/react";
const customSystem = createSystem({
...defaultConfig,
theme: {
...defaultConfig.theme,
tokens: {
...defaultConfig.theme?.tokens,
colors: {
...defaultConfig.theme?.tokens?.colors,
// Add custom colors while keeping defaults
brand: {
/* custom brand colors */
},
},
},
},
});Anatomy definitions for multi-part components, useful for advanced theming and custom slot recipes.
import {
accordionAnatomy,
actionBarAnatomy,
alertAnatomy,
avatarAnatomy,
blockquoteAnatomy,
breadcrumbAnatomy,
cardAnatomy,
checkboxAnatomy,
checkboxCardAnatomy,
clipboardAnatomy,
codeAnatomy,
collapsibleAnatomy,
colorPickerAnatomy,
comboboxAnatomy,
dataListAnatomy,
dialogAnatomy,
drawerAnatomy,
editableAnatomy,
emptyStateAnatomy,
fieldAnatomy,
fieldsetAnatomy,
fileUploadAnatomy,
hoverCardAnatomy,
inputAnatomy,
kbdAnatomy,
linkAnatomy,
listAnatomy,
markAnatomy,
menuAnatomy,
nativeSelectAnatomy,
paginationAnatomy,
pinInputAnatomy,
popoverAnatomy,
progressAnatomy,
progressCircleAnatomy,
radioCardAnatomy,
radioGroupAnatomy,
ratingGroupAnatomy,
scrollAreaAnatomy,
segmentGroupAnatomy,
selectAnatomy,
skeletonAnatomy,
sliderAnatomy,
statAnatomy,
statusAnatomy,
stepsAnatomy,
switchAnatomy,
tableAnatomy,
tabsAnatomy,
tagAnatomy,
textareaAnatomy,
timelineAnatomy,
toastAnatomy,
tooltipAnatomy,
treeViewAnatomy,
} from "@chakra-ui/react/anatomy";
// Each anatomy object has a parts() method that returns the part names
interface Anatomy {
parts(): string[];
}
// Example: Get dialog anatomy parts
const dialogParts = dialogAnatomy.parts();
// Returns: ["trigger", "backdrop", "positioner", "content", "title",
// "description", "closeTrigger", "header", "body", "footer"]Usage Example:
import { dialogAnatomy } from "@chakra-ui/react/anatomy";
import { createSystem } from "@chakra-ui/react";
// Use anatomy to create custom slot recipe
const customSystem = createSystem({
theme: {
slotRecipes: {
dialog: {
slots: dialogAnatomy.parts(),
base: {
backdrop: { bg: "blackAlpha.600" },
content: { borderRadius: "xl", boxShadow: "2xl" },
title: { fontSize: "2xl", fontWeight: "bold" },
},
},
},
},
});Available anatomies for all multi-part components including: Accordion, ActionBar, Alert, Avatar, Blockquote, Breadcrumb, Card, Checkbox, CheckboxCard, Clipboard, Code, Collapsible, ColorPicker, Combobox, DataList, Dialog, Drawer, Editable, EmptyState, Field, Fieldset, FileUpload, HoverCard, Input, Kbd, Link, List, Mark, Menu, NativeSelect, Pagination, PinInput, Popover, Progress, ProgressCircle, RadioCard, RadioGroup, RatingGroup, ScrollArea, SegmentGroup, Select, Skeleton, Slider, Stat, Status, Steps, Switch, Table, Tabs, Tag, Textarea, Timeline, Toast, Tooltip, and TreeView.