chakra-ui-migrate
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseChakra UI Migration: v2 → v3
Chakra UI 迁移指南:v2 → v3
You are guiding a developer through migrating their project from Chakra UI v2 to
v3. Work through the steps below in order. Inspect the project first — never
guess the package versions or framework.
Node requirement: Chakra UI v3 requires Node >= 20.x. Confirm before proceeding if the environment is uncertain.
你将引导开发者完成项目从Chakra UI v2到v3的迁移,请按以下步骤依次操作。首先检查项目情况——切勿猜测包版本或框架。
Node版本要求: Chakra UI v3要求Node >= 20.x。若环境不确定,请先确认版本。
Step 1 — Inspect the project
步骤1 — 检查项目状态
Read these files to understand the current state:
package.jsonLook for:
- Current version (v2.x vs v3.x)
@chakra-ui/react - Related packages: ,
@chakra-ui/icons,@chakra-ui/hooks,@chakra-ui/next-js,@emotion/styledframer-motion - Framework: Next.js (App Router or Pages Router), Vite, plain React
- Package manager (from lockfiles: ,
pnpm-lock.yaml,yarn.lock,bun.lock)package-lock.json
Also spot-check key files when helpful:
- Provider / theme setup (,
_app.tsx,layout.tsx)theme.ts - Color mode usage (,
ColorModeScript,useColorMode)useColorModeValue - Any component files showing heavy v2 patterns
读取以下文件以了解当前项目情况:
package.json重点查看:
- 当前版本(v2.x 或 v3.x)
@chakra-ui/react - 相关依赖包:、
@chakra-ui/icons、@chakra-ui/hooks、@chakra-ui/next-js、@emotion/styledframer-motion - 使用的框架:Next.js(App Router或Pages Router)、Vite、原生React
- 包管理器(从锁文件判断:、
pnpm-lock.yaml、yarn.lock、bun.lock)package-lock.json
必要时抽查关键文件:
- Provider/主题配置文件(、
_app.tsx、layout.tsx)theme.ts - 颜色模式使用情况(、
ColorModeScript、useColorMode)useColorModeValue - 包含大量v2模式的组件文件
Step 2 — Update packages
步骤2 — 更新依赖包
Remove v2-only dependencies
移除仅v2版本依赖
bash
undefinedbash
undefinednpm
npm
npm uninstall @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
npm uninstall @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
pnpm
pnpm
pnpm remove @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
pnpm remove @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
yarn
yarn
yarn remove @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
`@emotion/styled` and `framer-motion` are no longer required in v3.yarn remove @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
`@emotion/styled`和`framer-motion`在v3中不再是必需依赖。Install v3 core packages
安装v3核心包
bash
undefinedbash
undefinednpm
npm
npm install @chakra-ui/react @emotion/react
npm install @chakra-ui/react @emotion/react
pnpm
pnpm
pnpm add @chakra-ui/react @emotion/react
pnpm add @chakra-ui/react @emotion/react
yarn
yarn
yarn add @chakra-ui/react @emotion/react
undefinedyarn add @chakra-ui/react @emotion/react
undefinedReplacements for removed packages
已移除包的替代方案
| Removed | Replacement |
|---|---|
| |
| |
| |
| 已移除包 | 替代方案 |
|---|---|
| |
| |
| |
Step 3 — Run the codemod
步骤3 — 运行codemod
The official codemod handles most mechanical changes: component renames, prop
updates, import rewrites, and compound component restructuring. It does not
replace manual review — plan to audit the output.
Dry run first (no files changed):
bash
npx @chakra-ui/codemod upgrade --dryReview what it proposes. When satisfied:
bash
npx @chakra-ui/codemod upgradeAfter the codemod, commit the changes before making manual edits so you have a
clean diff to work from.
官方codemod可处理大部分机械性变更:组件重命名、属性更新、导入路径改写、复合组件结构调整。但仍需手动审核输出结果,不可完全依赖。
先执行试运行(不修改文件):
bash
npx @chakra-ui/codemod upgrade --dry查看变更建议,确认无误后执行正式迁移:
bash
npx @chakra-ui/codemod upgrade运行codemod后,先提交变更,再进行手动编辑,以便清晰查看差异。
Step 4 — Update the Provider
步骤4 — 更新Provider配置
Old v2 pattern
v2旧模式
tsx
// v2
import { ChakraProvider } from "@chakra-ui/react"
import theme from "./theme"
;<ChakraProvider theme={theme}>{children}</ChakraProvider>tsx
// v2
import { ChakraProvider } from "@chakra-ui/react"
import theme from "./theme"
;<ChakraProvider theme={theme}>{children}</ChakraProvider>New v3 pattern (using Chakra CLI snippets)
v3新模式(使用Chakra CLI代码片段)
Generate the provider and component snippets:
bash
npx @chakra-ui/cli snippet addThis creates (plus and
snippets) and automatically installs required npm dependencies — including
. Import and use it:
components/ui/provider.tsxtoastertooltipnext-themestsx
// v3 — app/layout.tsx (Next.js App Router)
import { Provider } from "@/components/ui/provider"
;<html lang="en" suppressHydrationWarning>
<body>
<Provider>{children}</Provider>
</body>
</html>The file includes — do not add it to . See
the Next.js section for Pages Router placement.
Provider"use client"layout.tsx生成Provider和组件代码片段:
bash
npx @chakra-ui/cli snippet add此命令会创建(同时生成toaster和tooltip代码片段),并自动安装所需npm依赖——包括。导入并使用该Provider:
components/ui/provider.tsxnext-themestsx
// v3 — app/layout.tsx(Next.js App Router)
import { Provider } from "@/components/ui/provider"
;<html lang="en" suppressHydrationWarning>
<body>
<Provider>{children}</Provider>
</body>
</html>Provider"use client"layout.tsxCustom theme in v3
v3自定义主题
Replace with :
extendThemecreateSystemts
// v2
import { extendTheme } from "@chakra-ui/react"
// v3
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
export const theme = extendTheme({ colors: { brand: { 500: "#2196f3" } } })
const config = defineConfig({
theme: { tokens: { colors: { brand: { 500: { value: "#2196f3" } } } } },
})
export const system = createSystem(defaultConfig, config)Pass to via .
systemChakraProvidervalue={system}将替换为:
extendThemecreateSystemts
// v2
import { extendTheme } from "@chakra-ui/react"
// v3
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react"
export const theme = extendTheme({ colors: { brand: { 500: "#2196f3" } } })
const config = defineConfig({
theme: { tokens: { colors: { brand: { 500: { value: "#2196f3" } } } } },
})
export const system = createSystem(defaultConfig, config)通过将传递给。
value={system}systemChakraProviderStep 5 — Color mode migration
步骤5 — 颜色模式迁移
Remove all v2 color mode patterns
移除所有v2颜色模式相关代码
tsx
// REMOVE these v2 imports and usages:
import { ColorModeScript } from "@chakra-ui/react"
// ❌
import { useColorMode } from "@chakra-ui/react"
// ❌ (use next-themes)
import { useColorModeValue } from "@chakra-ui/react"
// ❌ (use CSS tokens)
import { DarkMode, LightMode } from "@chakra-ui/react"
// ❌
// Also remove from _document.tsx:
;<ColorModeScript initialColorMode={theme.config.initialColorMode} /> // ❌tsx
// 移除以下v2导入及用法:
import { ColorModeScript } from "@chakra-ui/react"
// ❌
import { useColorMode } from "@chakra-ui/react"
// ❌(使用next-themes替代)
import { useColorModeValue } from "@chakra-ui/react"
// ❌(使用CSS tokens替代)
import { DarkMode, LightMode } from "@chakra-ui/react"
// ❌
// 同时移除_document.tsx中的以下代码:
;<ColorModeScript initialColorMode={theme.config.initialColorMode} /> // ❌v3 color mode approach
v3颜色模式实现方式
Color mode is handled by via the generated . Use
semantic tokens that automatically respond to the active color mode:
next-themesProvidertsx
// Use Chakra semantic tokens — they flip automatically in dark mode
<Box color="fg.default" bg="bg.subtle">
...
</Box>For a color mode toggle, use the generated
snippet or from directly.
components/ui/color-mode.tsxuseColorModenext-themes颜色模式由通过生成的处理。使用语义化tokens,可自动适配当前颜色模式:
next-themesProvidertsx
// 使用Chakra语义化tokens——会在暗黑模式下自动切换
<Box color="fg.default" bg="bg.subtle">
...
</Box>如需颜色模式切换按钮,可使用生成的代码片段,或直接使用的。
components/ui/color-mode.tsxnext-themesuseColorModeStep 6 — Prop renames
步骤6 — 属性重命名
These boolean and style props were renamed in v3 for consistency with HTML and
modern React conventions. The codemod catches most of these, but verify manually
afterward.
为了与HTML和现代React规范保持一致,v3中部分布尔值和样式属性已重命名。codemod会处理大部分此类变更,但仍需手动验证。
Boolean props
布尔属性
| v2 | v3 |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| v2 | v3 |
|---|---|
| |
| |
| |
| |
| |
| |
| |
| |
| |
Style and layout props
样式与布局属性
| v2 | v3 |
|---|---|
| |
| |
| |
| |
| |
| v2 | v3 |
|---|---|
| |
| |
| |
| |
| |
Nested style props
嵌套样式属性
tsx
// v2 — sx with nested pseudo-selectors
<Box sx={{ "&:hover": { color: "blue.500" } }} />
// v3 — css prop with "&" selectors
<Box css={{ "&:hover": { color: "blue.500" } }} />tsx
// v2 — 使用sx和嵌套伪选择器
<Box sx={{ "&:hover": { color: "blue.500" } }} />
// v3 — 使用css和"&"选择器
<Box css={{ "&:hover": { color: "blue.500" } }} />Step 7 — Component migrations
步骤7 — 组件迁移
Renamed components
重命名组件
| v2 | v3 |
|---|---|
| |
| |
| |
| |
Modal<Modal><ModalOverlay><ModalContent><ModalHeader><ModalBody><ModalFooter><ModalCloseButton>Dialog.*tsx
// v2
<Modal isOpen={open} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Title</ModalHeader>
<ModalBody>Body</ModalBody>
<ModalFooter><Button onClick={onClose}>Close</Button></ModalFooter>
</ModalContent>
</Modal>
// v3
<Dialog.Root open={open} onOpenChange={({ open }) => setOpen(open)}>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Header><Dialog.Title>Title</Dialog.Title></Dialog.Header>
<Dialog.Body>Body</Dialog.Body>
<Dialog.Footer><Button onClick={() => setOpen(false)}>Close</Button></Dialog.Footer>
<Dialog.CloseTrigger />
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>| v2 | v3 |
|---|---|
| |
| |
| |
| |
Modal<Modal><ModalOverlay><ModalContent><ModalHeader><ModalBody><ModalFooter><ModalCloseButton>Dialog.*tsx
// v2
<Modal isOpen={open} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Title</ModalHeader>
<ModalBody>Body</ModalBody>
<ModalFooter><Button onClick={onClose}>Close</Button></ModalFooter>
</ModalContent>
</Modal>
// v3
<Dialog.Root open={open} onOpenChange={({ open }) => setOpen(open)}>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Header><Dialog.Title>Title</Dialog.Title></Dialog.Header>
<Dialog.Body>Body</Dialog.Body>
<Dialog.Footer><Button onClick={() => setOpen(false)}>Close</Button></Dialog.Footer>
<Dialog.CloseTrigger />
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>Compound component rewrites
复合组件重构
v3 adopts a consistent compound component API. The codemod handles many of
these, but complex custom usage needs manual review.
Checkbox
tsx
// v2
<Checkbox isChecked={val} onChange={fn}>Label</Checkbox>
// v3
<Checkbox.Root checked={val} onCheckedChange={fn}>
<Checkbox.Control><Checkbox.Indicator /></Checkbox.Control>
<Checkbox.Label>Label</Checkbox.Label>
</Checkbox.Root>Progress
tsx
// v2
<Progress value={60} colorScheme="blue" />
// v3
<Progress.Root value={60} colorPalette="blue">
<Progress.Track><Progress.Range /></Progress.Track>
</Progress.Root>Accordion
tsx
// v2
<Accordion><AccordionItem><AccordionButton /><AccordionPanel /></AccordionItem></Accordion>
// v3
<Accordion.Root>
<Accordion.Item value="item-1">
<Accordion.ItemTrigger />
<Accordion.ItemContent />
</Accordion.Item>
</Accordion.Root>FormControl → Field
tsx
// v2
<FormControl isInvalid={!!error} isRequired>
<FormLabel>Email</FormLabel>
<Input type="email" />
<FormErrorMessage>{error}</FormErrorMessage>
<FormHelperText>We'll never share your email.</FormHelperText>
</FormControl>
// v3
<Field.Root invalid={!!error} required>
<Field.Label>Email</Field.Label>
<Input type="email" />
<Field.ErrorText>{error}</Field.ErrorText>
<Field.HelpText>We'll never share your email.</Field.HelpText>
</Field.Root>All sub-parts map to :
FormControlField.*- →
FormLabelField.Label - →
FormErrorMessageField.ErrorText - →
FormHelperTextField.HelpText - props
FormControl,isInvalid,isRequired→isDisabled,invalid,requireddisabled
Dialog / Drawer / Menu / Tabs follow the same compound pattern: use
, , , , etc. Check the Chakra UI
v3 docs for the specific compound API for each.
ComponentName.Root.Trigger.Content.Itemv3采用统一的复合组件API。codemod会处理大部分此类变更,但复杂的自定义用法需手动审核。
Checkbox
tsx
// v2
<Checkbox isChecked={val} onChange={fn}>Label</Checkbox>
// v3
<Checkbox.Root checked={val} onCheckedChange={fn}>
<Checkbox.Control><Checkbox.Indicator /></Checkbox.Control>
<Checkbox.Label>Label</Checkbox.Label>
</Checkbox.Root>Progress
tsx
// v2
<Progress value={60} colorScheme="blue" />
// v3
<Progress.Root value={60} colorPalette="blue">
<Progress.Track><Progress.Range /></Progress.Track>
</Progress.Root>Accordion
tsx
// v2
<Accordion><AccordionItem><AccordionButton /><AccordionPanel /></AccordionItem></Accordion>
// v3
<Accordion.Root>
<Accordion.Item value="item-1">
<Accordion.ItemTrigger />
<Accordion.ItemContent />
</Accordion.Item>
</Accordion.Root>FormControl → Field
tsx
// v2
<FormControl isInvalid={!!error} isRequired>
<FormLabel>Email</FormLabel>
<Input type="email" />
<FormErrorMessage>{error}</FormErrorMessage>
<FormHelperText>We'll never share your email.</FormHelperText>
</FormControl>
// v3
<Field.Root invalid={!!error} required>
<Field.Label>Email</Field.Label>
<Input type="email" />
<Field.ErrorText>{error}</Field.ErrorText>
<Field.HelpText>We'll never share your email.</Field.HelpText>
</Field.Root>所有子组件均对应:
FormControlField.*- →
FormLabelField.Label - →
FormErrorMessageField.ErrorText - →
FormHelperTextField.HelpText - 的
FormControl、isInvalid、isRequired属性 →isDisabled、invalid、requireddisabled
Dialog / Drawer / Menu / Tabs遵循相同的复合组件模式:使用、、、等。具体API可查看Chakra UI v3官方文档。
ComponentName.Root.Trigger.Content.ItemNext.js Image and Link (replacing @chakra-ui/next-js)
Next.js Image和Link(替代@chakra-ui/next-js)
tsx
// v2 — @chakra-ui/next-js
import { LinkOverlay } from "@chakra-ui/next-js"
// v3 — asChild pattern
import NextLink from "next/link"
<ChakraLink asChild><NextLink href="/about">About</NextLink></ChakraLink>
import NextImage from "next/image"
<ChakraImage asChild><NextImage src="..." alt="..." /></ChakraImage>tsx
// v2 — 使用@chakra-ui/next-js
import { LinkOverlay } from "@chakra-ui/next-js"
// v3 — 使用asChild模式
import NextLink from "next/link"
<ChakraLink asChild><NextLink href="/about">About</NextLink></ChakraLink>
import NextImage from "next/image"
<ChakraImage asChild><NextImage src="..." alt="..." /></ChakraImage>Step 8 — Theming migration
步骤8 — 主题迁移
styleConfig and multiStyleConfig → recipes
styleConfig和multiStyleConfig → recipes
ts
// v3 — single component (recipe)
import { defineRecipe } from "@chakra-ui/react"
// v2
const buttonStyle = {
baseStyle: { fontWeight: "bold" },
variants: { solid: { bg: "blue.500" } },
defaultProps: { variant: "solid" },
}
const buttonRecipe = defineRecipe({
base: { fontWeight: "bold" },
variants: { variant: { solid: { bg: "blue.500" } } },
defaultVariants: { variant: "solid" },
})ts
// v3 — slot recipe
import { defineSlotRecipe } from "@chakra-ui/react"
// v2 — multiStyleConfig (multi-part component)
const cardStyle = multiStyleConfig({
parts: ["root", "header"],
baseStyle: { root: { bg: "white" }, header: { fontWeight: "bold" } },
})
const cardSlotRecipe = defineSlotRecipe({
slots: ["root", "header"],
base: { root: { bg: "white" }, header: { fontWeight: "bold" } },
})ts
// v3 — 单组件(recipe)
import { defineRecipe } from "@chakra-ui/react"
// v2
const buttonStyle = {
baseStyle: { fontWeight: "bold" },
variants: { solid: { bg: "blue.500" } },
defaultProps: { variant: "solid" },
}
const buttonRecipe = defineRecipe({
base: { fontWeight: "bold" },
variants: { variant: { solid: { bg: "blue.500" } } },
defaultVariants: { variant: "solid" },
})ts
// v3 — 插槽recipe
import { defineSlotRecipe } from "@chakra-ui/react"
// v2 — multiStyleConfig(多部分组件)
const cardStyle = multiStyleConfig({
parts: ["root", "header"],
baseStyle: { root: { bg: "white" }, header: { fontWeight: "bold" } },
})
const cardSlotRecipe = defineSlotRecipe({
slots: ["root", "header"],
base: { root: { bg: "white" }, header: { fontWeight: "bold" } },
})Typegen for custom tokens
自定义tokens类型生成
After adding custom tokens, semantic tokens, recipes, or slot recipes, run
typegen to keep TypeScript types in sync:
bash
npx @chakra-ui/cli typegen ./theme.tsComplex theme migrations — if you're moving a large v2 theme with many custom tokens, semantic tokens, or multi-part component styles, use theskill. It covers the full token/recipe/slot-recipe API in depth and is a better guide than this section alone.chakra-ui-theming
添加自定义tokens、语义化tokens、recipes或插槽recipes后,运行typegen以保持TypeScript类型同步:
bash
npx @chakra-ui/cli typegen ./theme.ts复杂主题迁移 — 若迁移包含大量自定义tokens、语义化tokens或多部分组件样式的大型v2主题,请使用技能。该技能深入讲解完整的token/recipe/插槽recipe API,比本节内容更具指导意义。chakra-ui-theming
Step 9 — Next.js specifics
步骤9 — Next.js专属配置
App Router
App Router
- Place in
<Provider>(Server Component — noapp/layout.tsx)"use client" - The generated already has
components/ui/provider.tsx"use client" - Add to
suppressHydrationWarningto prevent color mode flicker<html> - Do not wrap the entire app or layout in
"use client"
- 将放置在
<Provider>中(Server Component——无需添加app/layout.tsx)"use client" - 生成的已包含
components/ui/provider.tsx"use client" - 为添加
<html>以避免颜色模式闪烁suppressHydrationWarning - 请勿将整个应用或布局包裹在中
"use client"
Pages Router
Pages Router
tsx
// pages/_app.js
import { Provider } from "@/components/ui/provider"
export default function App({ Component, pageProps }) {
return (
<Provider>
<Component {...pageProps} />
</Provider>
)
}Remove any from — it is not used in v3.
ColorModeScriptpages/_document.tsxtsx
// pages/_app.js
import { Provider } from "@/components/ui/provider"
export default function App({ Component, pageProps }) {
return (
<Provider>
<Component {...pageProps} />
</Provider>
)
}移除中的所有——v3不再使用该组件。
pages/_document.tsxColorModeScriptStep 10 — Validation checklist
步骤10 — 验证清单
Work through this after the migration is complete:
- Reinstall dependencies: /
npm installpnpm install - TypeScript: — resolve all type errors
npx tsc --noEmit - Lint:
npm run lint - Build:
npm run build - Visually verify color mode toggle (light ↔ dark)
- Test interactive components: Dialog, Drawer, Menu, Tabs, Accordion
- Test form components: Checkbox, Select/NativeSelect, Input, Radio
- Check for visual regressions across key pages
- Search codebase for leftover v2 imports:
bash
grep -r "ColorModeScript\|useColorModeValue\|extendTheme\|styleConfig\|@chakra-ui/icons\|@chakra-ui/next-js" src/
迁移完成后,请逐一检查以下内容:
- 重新安装依赖:/
npm installpnpm install - TypeScript检查:——解决所有类型错误
npx tsc --noEmit - 代码 lint:
npm run lint - 项目构建:
npm run build - 视觉验证颜色模式切换(亮色 ↔ 暗色)
- 测试交互式组件:Dialog、Drawer、Menu、Tabs、Accordion
- 测试表单组件:Checkbox、Select/NativeSelect、Input、Radio
- 检查关键页面是否存在视觉回归
- 搜索代码库中残留的v2导入:
bash
grep -r "ColorModeScript\|useColorModeValue\|extendTheme\|styleConfig\|@chakra-ui/icons\|@chakra-ui/next-js" src/
Clarifying questions (when context is unclear)
澄清问题(上下文不明确时)
If the user's version, framework, or scope is ambiguous, ask:
- "What version of are you on right now?"
@chakra-ui/react - "Are you using Next.js App Router, Pages Router, Vite, or plain React?"
- "Are you migrating the full codebase or just specific components?"
State assumptions clearly if you proceed without asking.
若用户的版本、框架或迁移范围不明确,请询问:
- "你当前使用的版本是多少?"
@chakra-ui/react - "你使用的是Next.js App Router、Pages Router、Vite还是原生React?"
- "你是迁移整个代码库还是仅特定组件?"
若未询问便继续操作,请明确说明你的假设。