Skip to Content
DocumentationUI LibrariesChakra UI

Chakra UI — Complete Usage & Design System Guide

Chakra UI is a design-system–first React framework built on a modern architecture that includes a styling engine, tokens, recipes, semantic theming, and headless primitives. It enables predictable styling, scalable theme customization, and a consistent development experience for large applications.


1. Installation

Install Chakra UI:

npm install @chakra-ui/react

To use Chakra components, wrap your application with ChakraProvider in your root layout:

import { createSystem, defaultConfig, ChakraProvider } from '@chakra-ui/react' const system = createSystem(defaultConfig) export function RootLayout({ children }) { return ( <html lang="en"> <body> <ChakraProvider value={system}>{children}</ChakraProvider> </body> </html> ) }

2. What Are Snippets?

Snippets in Chakra UI are pre-built, ready-to-use code templates generated through the CLI. They help you configure common patterns that usually require setup or repeated boilerplate.

Snippets help with:

  • Color mode system (light/dark mode)
  • Tooltips
  • Toaster notifications
  • Password input behaviors
  • Provider setups
  • Component recipes & patterns

Why use snippets?

✔ Faster development ✔ Fewer configuration mistakes ✔ Built-in best practices ✔ Consistent architecture across the app


3. Snippet: Color Mode

Color mode is essential for:

  • Light/Dark theme switching
  • Conditional styles using _dark / _light
  • Semantic tokens mapped to color schemes

Install the color-mode snippet:

npx @chakra-ui/cli snippet add color-mode

Use ColorModeProvider in your root layout:

export function RootLayout({ children }) { return ( <html lang="en"> <body> <ColorModeProvider>{children}</ColorModeProvider> </body> </html> ) }

Provides:

✔ Persisted color preference ✔ Auto-applied dark/light CSS variables ✔ Enables conditional styling (e.g. _dark)


4. Optional Useful Snippets

There are many other snippets you can use theme such as:

4.1 Tooltip

Install:

npx @chakra-ui/cli snippet add tooltip

Use tooltips for icons, actions, or short hints:

<Tooltip content="Delete item"> <IconButton icon={<Trash />} /> </Tooltip>

4.2 Toaster

Use for notifications (success, error, info).

Install:

npx @chakra-ui/cli snippet add toaster
import { Toaster, toaster } from '@chakra-ui/react' ;<Toaster /> // place in root layout // Notify toaster.success('Saved!')

4.3 Password Input

Install:

npx @chakra-ui/cli snippet add password-input

Usage:

<PasswordInput placeholder="Enter password" />

5. Chakra Core Components

Chakra components combine:

  • System props
  • Styled primitives
  • Recipes & slots
  • Theme tokens

Box

Most basic building block:

<Box p={4} bg="gray.100" rounded="lg" />

Flex

Same as Box but with display: flex:

<Flex justify="space-between" align="center" />

Stack / HStack / VStack

Flex (horizontally or vertically) with some gap:

<Stack> <Box>1</Box> <Box>2</Box> </Stack>

Button

Supports states, variants, sizes, recipes:

<Button variant="solid">Save</Button>

And there are many other components you can see them in documentation and customize them in the theme.ts


6. Customizing the Theme System

You can fully override and extend Chakra by creating your own system configuration:

import { createSystem, defaultConfig, defineConfig } from '@chakra-ui/react' const config = defineConfig({ theme: { // customizations here } }) export const system = createSystem(defaultConfig, config)

Then apply it:

<ChakraProvider value={system} />

6.1 Tokens

Tokens are the foundation of Chakra’s design system.

Why tokens?

  • Global consistency
  • Auto-generated CSS variables
  • Work seamlessly with recipes and conditional styles
  • Scale well in large applications

Example:

tokens: { colors: { brand: { 500: '#5A31F4' } } }

6.2 Semantic Tokens

Semantic tokens represent meaning, not raw colors.

semanticTokens: { colors: { bg: { default: "white", _dark: "gray.900", }, text: { default: "gray.900", _dark: "gray.100", }, }, }

Why semantic tokens?

✔ One label works for both light/dark ✔ Centralized decision-making ✔ Cleaner, scalable design ✔ Easier refactoring

6.3 Other config

In the defineConfig there are many of configuration such as defining backgrounds and keyframes, You can find details of them in the documentation.


6.4 Recipes (Component Style Definitions)

Recipes define reusable component styles—almost like Tailwind components with variants.

Example:

import { defineRecipe } from '@chakra-ui/react' export const buttonRecipe = defineRecipe({ key: 'button', base: { borderRadius: 'md', fontWeight: '500' }, variants: { variant: { solid: { bg: 'brand.500', color: 'white', _hover: { bg: 'brand.600' } }, outline: { border: '1px solid', borderColor: 'brand.500' } }, size: { sm: { px: 3, py: 2 }, md: { px: 4, py: 3 } } }, defaultVariants: { variant: 'solid', size: 'md' } })

Register (this will change the recipe of Chakra ui Button):

theme: { recipes: { button: buttonRecipe } }

Or you can use it like this:

const recipe = useRecipe({ key: 'button' }) const styles = recipe({ size, variant }) return <button styles={styles}>Save</button>

6.4 Slot Recipes

Used for multi-part components (Card, Modal, Alert, etc.).

const cardRecipe = defineSlotRecipe({ key: 'new-card', slots: ['root', 'title', 'description'], base: { root: { p: 5, rounded: 'lg', shadow: 'md' }, title: { fontSize: 'xl', fontWeight: 'bold' }, description: { color: 'gray.600' } } })

Register (this will change the recipe of Chakra ui Card):

theme: { slotRecipes: { card: cardRecipe } }

Or you can use it like this:

const recipe = useRecipe({ key: 'new-card' }) const styles = recipe({}) export const Card = { Root: (...props) => <Box css={styles.root} {...props} />, Title: (...props) => <Text css={styles.title} {...props} />, Description: (...props) => <Text css={styles.description} {...props} /> }

6.5 Context Slot Recipes (Advanced)

These allow the root component to pass props into child slots automatically and use the compound variants.

Example: Action menu

'use client' import { createSlotRecipeContext, HTMLChakraProps, IconButtonProps, MenuContentProps, MenuItemProps, MenuTriggerProps } from '@chakra-ui/react' import { IconButton, Menu } from '@chakra-ui/react' import { EditPencil, Eye, MoreHoriz, Trash } from 'iconoir-react' import Link from 'next/link' import DeleteButton from '../delete-button' import { actionMenuRecipe } from './recipe' const { withProvider, withContext, usePropsContext, PropsProvider } = createSlotRecipeContext({ recipe: actionMenuRecipe }) interface ActionMenuRootProps extends HTMLChakraProps<'div'> { label?: string } const ActionMenuRoot = withProvider<HTMLDivElement, ActionMenuRootProps>( Menu.Root, 'root', { wrapElement: (el, props) => ( <PropsProvider value={props}>{el}</PropsProvider> ), defaultProps: { label: 'Item' } } ) const ActionMenuTrigger = withContext<MenuTriggerProps, IconButtonProps>( ({ children, ...props }) => ( <Menu.Trigger asChild> {children || ( <IconButton size="xs" variant="ghost" {...props}> <MoreHoriz /> </IconButton> )} </Menu.Trigger> ), 'trigger' ) const ActionMenuContent = withContext<MenuContentProps, HTMLChakraProps<'div'>>( props => ( <Menu.Positioner> <Menu.Content {...props} /> </Menu.Positioner> ), 'content' ) const ActionMenuItem = withContext<MenuItemProps, HTMLChakraProps<'div'>>( Menu.Item, 'item' ) export interface ActionMenuViewItemProps extends Omit<MenuItemProps, 'value'> { href?: string } const ActionMenuViewItem = withContext<MenuItemProps, ActionMenuViewItemProps>( props => { const { label } = usePropsContext() return ( <Menu.Item as={props.href ? Link : 'div'} value="view" {...props}> <Eye /> View {label} </Menu.Item> ) }, 'viewItem' ) export interface ActionMenuDeleteItemProps extends Omit<MenuItemProps, 'value'> { href?: string } const ActionMenuEditItem = withContext< MenuItemProps, ActionMenuDeleteItemProps >(props => { const { label } = usePropsContext() return ( <Menu.Item as={props.href ? Link : 'div'} value="edit" {...props}> <EditPencil /> Edit {label} </Menu.Item> ) }, 'editItem') export interface ActionMenuDeleteItemProps extends Omit<MenuItemProps, 'value'> { onDelete?: (props?: any) => any } const ActionMenuDeleteItem = withContext< MenuItemProps, ActionMenuDeleteItemProps >(({ onDelete, ...props }) => { const { label } = usePropsContext() return ( <DeleteButton onDelete={onDelete}> <Menu.Item value="delete" closeOnSelect={false} {...props}> <Trash /> Delete {label} </Menu.Item> </DeleteButton> ) }, 'deleteItem') export const ActionMenu = { Root: ActionMenuRoot, Trigger: ActionMenuTrigger, Content: ActionMenuContent, Item: ActionMenuItem, ViewItem: ActionMenuViewItem, EditItem: ActionMenuEditItem, DeleteItem: ActionMenuDeleteItem }

Usage:

<ActionMenu.Root> <ActionMenu.Trigger /> <ActionMenu.Content> <ActionMenu.Item /> {/** other items */} </ActionMenu.Content> </ActionMenu.Root>

This creates an usable action menu and can be customized easily.


6.6 Compound Variants

Apply styles based on multiple variants together.

compoundVariants: [ { variant: 'outline', size: 'lg', css: { borderWidth: '3px' } } ]

7. Changing Default Font

Define fonts with tokens:

tokens: { fonts: { body: { value: "Inter, sans-serif" }, heading: { value: "Poppins, sans-serif" }, } }

8. Defining Global CSS

Defined in the system:

globalCss: { 'html, body': { bg: 'bg', color: 'text', fontFamily: 'body', }, a: { color: 'brand.500', }, }

9. Conditional Styles (Dark/Light Mode)

Option 1: Component-level condition:

<Box bg={{ base: 'white', _dark: 'gray.800' }} />

Option 2: Semantic token:

<Box bg="bg" color="text" />

10. Locale provider

If you are using i18n for localizing so you may provide an locale provider to force chakra component to some locale.

<LocaleProvider locale={currentLocale}>{children}</LocaleProvider>

11. References

Official Docs: https://chakra-ui.com/docs/components/concepts/overview 


12. Summary Checklist

TopicKey Points
Installnpm install @chakra-ui/react
Core ComponentsBox, Flex, Stack, Button
SnippetsCLI-based templates for common patterns
Required SnippetColor mode setup
Optional SnippetsTooltip, Toaster, Password Input
ProviderWrap your app with ChakraProvider
SystemCustomize via tokens, recipes, semantic tokens
RecipesDefine component styles with variants
Slot RecipesMulti-part component styling
Context Slot RecipesPass root props to child slots
FontsToken-based font definitions
Global CSSDefined in globalCss
Dark/Light_dark, _light, or semantic tokens