Using Chakra UI in Next.js (App)
A guide for installing Chakra UI with Next.js app directory
Compatibility
Chakra UI works with Next.js 15 and 16.
Chakra UI doesn't lock you to a specific Next.js major version. If your project uses supported React and Emotion versions, this guide applies.
The templates in this repo may pin an older Next.js major for stability. You can
upgrade next to the latest major in your app.
Templates
Use one of the following templates to get started quickly. The templates are configured correctly to use Chakra UI.
Installation
The minimum node version required is Node.20.x
Install dependencies
npm i @chakra-ui/react @emotion/reactAdd snippets
Snippets are pre-built components that you can use to build your UI faster.
Using the @chakra-ui/cli you can add snippets to your project.
npx @chakra-ui/cli snippet addUpdate tsconfig
If you're using TypeScript, you need to update the compilerOptions in the
tsconfig file to include the following options:
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"skipLibCheck": true,
"paths": {
"@/*": ["./src/*"]
}
}
}If you're using JavaScript, create a jsconfig.json file and add the above
code to the file.
Setup provider
Wrap your application with the Provider component generated in the
components/ui/provider component at the root of your application.
This provider composes the following:
ChakraProviderfrom@chakra-ui/reactfor the styling systemThemeProviderfromnext-themesfor color mode
app/layout.tsx
import { Provider } from "@/components/ui/provider"
export default function RootLayout(props: { children: React.ReactNode }) {
const { children } = props
return (
<html suppressHydrationWarning>
<body>
<Provider>{children}</Provider>
</body>
</html>
)
}Adding the suppressHydrationWarning prop to the html element is required
to prevent the warning about the next-themes library.
Optimize Bundle
We recommend using the experimental.optimizePackageImports feature in Next.js
to optimize your bundle size by loading only the modules that you are actually
using.
next.config.mjs
export default {
experimental: {
optimizePackageImports: ["@chakra-ui/react"],
},
}This also helps to resolve warnings like:
[webpack.cache.PackFileCacheStrategy] Serializing big strings (xxxkiB)Stream through Suspense (optional)
Skip this unless you stream UI through <Suspense>.
You need it when Chakra components first appear inside a streamed <Suspense>
chunk. If you enable
Cache Components
in Next.js 16, that is the default.
Install @emotion/cache and add this registry:
components/ui/emotion-registry.tsx
"use client"
import createCache from "@emotion/cache"
import { CacheProvider } from "@emotion/react"
import { useServerInsertedHTML } from "next/navigation"
import { useState } from "react"
export function EmotionRegistry({ children }: { children: React.ReactNode }) {
const [{ cache, flush }] = useState(() => {
const cache = createCache({ key: "css" })
cache.compat = true
const previousInsert = cache.insert
let inserted: string[] = []
cache.insert = (...args) => {
const serialized = args[1]
if (cache.inserted[serialized.name] === undefined) {
inserted.push(serialized.name)
}
return previousInsert(...args)
}
const flush = () => {
const previouslyInserted = inserted
inserted = []
return previouslyInserted
}
return { cache, flush }
})
useServerInsertedHTML(() => {
const names = flush()
if (names.length === 0) return null
const styles = names.map((name) => cache.inserted[name]).join("")
return (
<style
data-emotion={`${cache.key} ${names.join(" ")}`}
dangerouslySetInnerHTML={{ __html: styles }}
/>
)
})
return <CacheProvider value={cache}>{children}</CacheProvider>
}Then wrap Provider with it:
app/layout.tsx
import { EmotionRegistry } from "@/components/ui/emotion-registry"
import { Provider } from "@/components/ui/provider"
export default function RootLayout(props: { children: React.ReactNode }) {
return (
<html suppressHydrationWarning>
<body>
<EmotionRegistry>
<Provider>{props.children}</Provider>
</EmotionRegistry>
</body>
</html>
)
}The streaming sandbox is a repro you can run cold, not a copy of the layout above.
Hydration errors (Turbopack)
If the error looks like this:
+<div className="chakra-xxx">
-<style data-emotion="css-global xxx" data-s="">Turbopack is hydrating Emotion CSS incorrectly. Add --webpack to your dev
and build scripts:
- "dev": "next dev"
- "build": "next build"
+ "dev": "next dev --webpack"
+ "build": "next build --webpack"When this is fixed by the Next.js team, we'll update this guide.
Enjoy!
With the power of the snippets and the primitive components from Chakra UI, you can build your UI faster.
import { Button, HStack } from "@chakra-ui/react"
const Demo = () => {
return (
<HStack>
<Button>Click me</Button>
<Button>Click me</Button>
</HStack>
)
}