Customize Theme

By default, all Chakra components inherit values from the default theme. In some scenarios, you might need to customize the theme tokens to match your design requirements.

Here are some options depending on your goals:

  • Customize the theme tokens like colors, font sizes, line heights, etc.
  • Customize the component styles, changing the base styles, sizes, or variants.
  • Customize the global styles.

Customizing theme tokens#

To extend or override a token in the default theme, import the extendTheme function and add the keys you'd like to override. You can also add new values to the theme.

For example, if you'd like to update the colors in the theme to include your brand colors, here's what you'll do:

// 1. Import `extendTheme`
import { extendTheme } from "@chakra-ui/react"
// 2. Call `extendTheme` and pass your custom values
const theme = extendTheme({
colors: {
brand: {
100: "#f7fafc",
// ...
900: "#1a202c",
},
},
})
// 3. Pass the new theme to `ChakraProvider`
<ChakraProvider theme={theme}>
<App />
</ChakraProvider>
// 4. Now you can use these colors in your components
function Usage() {
return <Box bg="brand.100">Welcome</Box>
}

You can also use the color for the colorScheme prop like this:

<Button colorScheme="brand">Click me</Button>

If you're curious as to what theme styles you can override, please reference the default theme foundation style files.

Customizing component styles#

Chakra has a specific approach or API for styling components. The main idea is most components have default or base styles (baseStyle), styles for different sizes (sizes), and styles for different visual variants (variants).

It is important to understand this so you can override any component style effectively.

You're not limited to the component styles that Chakra provides, you can also create your own custom component styles. Learn more.

Customizing single components#

As we mentioned earlier, a component style consists of baseStyles, sizes, variants and an optional defaultProps to denote the default size or variant.

Here's what the component style object looks like:

const ComponentStyle = {
// style object for base or default style
baseStyle: {},
// styles for different sizes ("sm", "md", "lg")
sizes: {},
// styles for different visual variants ("outline", "solid")
variants: {},
// default values for `size` and `variant`
defaultProps: {
size: "",
variant: "",
},
}

For example, let's override the component styles for Chakra's Button component.

// theme.js
import { extendTheme } from "@chakra-ui/react"
const theme = extendTheme({
components: {
Button: {
// 1. We can update the base styles
baseStyle: {
fontWeight: "bold", // Normally, it is "semibold"
},
// 2. We can add a new button size or extend existing
sizes: {
xl: {
h: "56px",
fontSize: "lg",
px: "32px",
},
},
// 3. We can add a new visual variant
variants: {
"with-shadow": {
bg: "red.400",
boxShadow: "0 0 2px 2px #efdfde",
},
// 4. We can override existing variants
solid: (props) => ({
bg: props.colorMode === "dark" ? "red.300" : "red.500",
}),
},
},
},
})
export default theme

That's it! When you use the Button from Chakra, these updates will be automatically applied.

<Button size="xl" variant="with-shadow">
Welcome
</Button>

If you're curious as to what component styles you can override, please reference the default component style files.

Customizing global styles#

Global styles are theme-aware styles you can apply to any html element globally.

To add global styles, update the theme.styles.global key in the theme. Global styles can be a style object or a function that returns a style object.

// theme.js
import { extendTheme } from "@chakra-ui/react"
import { mode } from "@chakra-ui/theme-tools"
// Version 1: Using objects
const theme = extendTheme({
styles: {
global: {
// styles for the `body`
body: {
bg: "gray.400",
color: "white",
},
// styles for the `a`
a: {
color: "teal.500",
_hover: {
textDecoration: "underline",
},
},
},
},
})
// Version 2: Using functions
const overrides = extendTheme({
styles: {
global: (props) => ({
body: {
fontFamily: "body",
color: mode("gray.800", "whiteAlpha.900")(props),
bg: mode("white", "gray.800")(props),
lineHeight: "base",
},
}),
},
})

Scaling out your project#

As your project grows in size, it is best to keep things organized. We highly suggest that instead of using a single theme.js (or theme.ts) file, you create a /theme folder in its place. Inside this folder, you could have a directory structure that looks like this:

📁 theme
📄 index.js # my main theme entrypoint
📄 styles.js # all my global style overrides
📁 foundations
📄 borders.js # all my border overrides
📁 components
📄 button.js # all my button overrides

This way, you can structure your main theme entrypoint file to be much cleaner, like this:

// theme.js
import { extendTheme } from "@chakra-ui/react"
// Global style overrides
import styles from "./styles"
// Foundational style overrides
import borders from "./foundations/borders"
// Component style overrides
import Button from "./components/button"
const overrides = {
styles,
borders,
// Other foundational style overrides go here
components: {
Button,
// Other components go here
},
}
export default extendTheme(overrides)

None of these is strictly required to use Chakra - but we've learned some hard lessons on the "right" way and the "wrong" way to write styles. The above is our best suggestion on how to write style overrides and organize your custom theme.

Using Theme extensions#

v1.6.0

The extendTheme function allows you to pass multiple overrides or extensions:

import {
extendTheme,
withDefaultColorScheme,
theme as baseTheme,
} from "@chakra-ui/react"
const customTheme = extendTheme(
{
colors: {
brand: baseTheme.colors.red,
},
components: {
Alert: {
defaultProps: {
colorScheme: "blue",
},
},
},
},
withDefaultColorScheme({ colorScheme: "brand" }),
)

The order of overrides is from left to right. E.g. the second extension overrides the first one, and so on.

Please note that you can pass a base theme as last parameter. If no base theme is provided, we use the Chakra UI default theme

extendTheme(
withFirstExtension,
withSecondExtension,
withThirdExtension,
optionalBaseTheme,
)

Theme Extension: withDefaultColorScheme#

You can apply a default color scheme to all components.

import { extendTheme, withDefaultColorScheme } from "@chakra-ui/react"
const customTheme = extendTheme(withDefaultColorScheme({ colorScheme: "red" }))

Or pass the component names you want to apply a default colorScheme to. This lets you apply different color schemes to a group of components.

import { extendTheme, withDefaultColorScheme } from "@chakra-ui/react"
const customTheme = extendTheme(
withDefaultColorScheme({
colorScheme: "red",
components: ["Button", "Badge"],
}),
withDefaultColorScheme({
colorScheme: "blue",
components: ["Alert", "Table"],
}),
)

Theme Extension: withDefaultSize#

You can apply a default size to all components.

import { extendTheme, withDefaultSize } from "@chakra-ui/react"
const customTheme = extendTheme(
withDefaultSize({
size: "lg",
components: ["Button", "Badge"],
}),
)

Theme Extension: withDefaultVariant#

You can apply a default variant to all components.

import { extendTheme, withDefaultVariant } from "@chakra-ui/react"
const customTheme = extendTheme(
withDefaultVariant({
variant: "outline",
components: ["Input", "NumberInput", "PinInput"],
}),
)

Theme Extension: withDefaultProps#

You can apply default props to all components.

import { extendTheme, withDefaultProps } from "@chakra-ui/react"
const customTheme = extendTheme(
withDefaultProps({
defaultProps: {
variant: "outline",
size: "lg",
},
components: ["Input", "NumberInput", "PinInput"],
}),
)

In the next section, we'll show some examples of how to create custom component styles and use them in your components!

Proudly made inNigeria by Segun Adebayo