Setting Up Chakra UI

Front-end tooling has rapidly progressed, and projects like styled-system and Theme UI make it easy to create components that easily adhere to your design system.

Chakra UI, built on top of styled-system, provides a comprehensive component library allowing us to easily create components that adhere to a design system.

  • Since it uses styled-system under the hood, we can use style props
  • The theme is extendable, allowing us to change fonts and add icons easily
  • It includes a great set of accessible components out of the box
  • Works well with Next.js and supports dark mode

To install Chakra, let's add the required dependencies.

$ yarn add @chakra-ui/core@0.8.0 @emotion/core@10.0.28 @emotion/styled@10.0.27 emotion-theming@10.0.27

This course uses v0.8 of Chakra UI. You can read the docs for this version here. If you'd prefer to start from v1.0, you can read the migration guide here.

Chakra UI comes with a default theme containing values for colors, typography, and more. Let's extend the default and add a custom font.


import { theme as chakraTheme } from '@chakra-ui/core'
const theme = {
fonts: {
body: `Inter,-apple-system,BlinkMacSystemFont,"Segoe UI",Helvetica,Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol"`,
fontWeights: {
normal: 400,
medium: 600,
bold: 800,
export default theme

Now, we can add the theme to our application with ThemeProvider, passing the theme object as a prop. Let's modify pages/_app.js to make the theme available to all pages. Next.js uses the App component to initialize pages. You can override it and control the page initialization.


import { ThemeProvider, CSSReset } from '@chakra-ui/core'
import { AuthProvider } from '../lib/auth'
import theme from '../styles/theme'
const App = ({ Component, pageProps }) => {
return (
<ThemeProvider theme={theme}>
<CSSReset />
<Component {...pageProps} />
export default App

We also need to load the font Inter defined earlier. A custom Document is commonly used to augment your application's <html> and <body> tags. This is necessary because Next.js pages skip the definition of the surrounding document's markup.


import Document, { Html, Head, Main, NextScript } from 'next/document'
class MyDocument extends Document {
render() {
return (
<Main />
<NextScript />
export default MyDocument