Chakra UI マイグレーション: v2 → v3 は何をしますか?
あなたは、開発者がプロジェクトを Chakra UI v2 から v3 に移行するのを支援します。以下の手順を順に進めてください。最初にプロジェクトを検査し、パッケージのバージョンやフレームワークを推測しないでください。
Node 要件: Chakra UI v3 には Node >= 20.x が必要です。環境が不明な場合は、先に進む前に確認してください。
ステップ 1 — プロジェクトの検査
以下のファイルを読み、現在の状態を把握します。
package.json
以下の項目を確認します。
- 現在の
@chakra-ui/reactのバージョン(v2.x か v3.x か) - 関連パッケージ:
@chakra-ui/icons、@chakra-ui/hooks、@chakra-ui/next-js、@emotion/styled、framer-motion - フレームワーク: Next.js(App Router または Pages Router)、Vite、プレーンな React
- パッケージマネージャー(ロックファイルから:
pnpm-lock.yaml、yarn.lock、bun.lock、package-lock.json)
また、必要に応じて以下の主要ファイルをチェックします。
- プロバイダー / テーマ設定(
_app.tsx、layout.tsx、theme.ts) - カラーモードの使用法(
ColorModeScript、useColorMode、useColorModeValue) - v2 パターンが多く使われているコンポーネントファイル
ステップ 2 — パッケージの更新
v2 専用の依存関係を削除
# npm
npm uninstall @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
# pnpm
pnpm remove @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
# yarn
yarn remove @chakra-ui/icons @chakra-ui/hooks @chakra-ui/next-js @emotion/styled framer-motion
@emotion/styled と framer-motion は v3 では不要になりました。
v3 コアパッケージをインストール
# npm
npm install @chakra-ui/react @emotion/react
# pnpm
pnpm add @chakra-ui/react @emotion/react
# yarn
yarn add @chakra-ui/react @emotion/react
削除されたパッケージの代替
| 削除されたパッケージ | 代替パッケージ |
|---|---|
@chakra-ui/icons | lucide-react または react-icons |
@chakra-ui/hooks | react-use または usehooks-ts |
@chakra-ui/next-js | asChild プロップパターン(Next.js セクションを参照) |
ステップ 3 — codemod の実行
公式 codemod は、コンポーネント名の変更、プロップの更新、インポートの書き換え、複合コンポーネントの再構築など、ほとんどの機械的な変更を処理します。ただし、手動でのレビューを置き換えるものではありません。出力を監査する予定を立ててください。
まずドライランを実行します(ファイルは変更されません):
npx @chakra-ui/codemod upgrade --dry
提案内容を確認します。問題がなければ次を実行します。
npx @chakra-ui/codemod upgrade
codemod の後、手動編集を行う前に変更をコミットして、クリーンな差分を残してください。
ステップ 4 — プロバイダーの更新
古い v2 パターン
// v2
import { ChakraProvider } from "@chakra-ui/react"
import theme from "./theme"
;<ChakraProvider theme={theme}>{children}</ChakraProvider>
新しい v3 パターン(Chakra CLI スニペットを使用)
プロバイダーとコンポーネントスニペットを生成します。
npx @chakra-ui/cli snippet add
これにより、components/ui/provider.tsx(および toaster、tooltip スニペット)が作成され、必要な npm 依存関係(next-themes を含む)が自動的にインストールされます。これをインポートして使用します。
// 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.tsx に追加しないでください。Pages Router への配置については、Next.js のセクションを参照してください。
v3 でのカスタムテーマ
extendTheme を createSystem に置き換えます。
// 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)
system を ChakraProvider に value={system} として渡します。
ステップ 5 — カラーモードの移行
v2 のカラーモードパターンをすべて削除
// 以下の v2 のインポートと使用法を削除:
import { ColorModeScript } from "@chakra-ui/react" // ❌
import { useColorMode } from "@chakra-ui/react" // ❌(next-themes を使用)
import { useColorModeValue } from "@chakra-ui/react" // ❌(CSS トークンを使用)
import { DarkMode, LightMode } from "@chakra-ui/react" // ❌
// さらに _document.tsx からも削除:
;<ColorModeScript initialColorMode={theme.config.initialColorMode} /> // ❌
v3 のカラーモードアプローチ
カラーモードは、生成された Provider を介して next-themes によって処理されます。アクティブなカラーモードに自動的に応答するセマンティックトークンを使用します。
// Chakra セマンティックトークンを使用 — ダークモードで自動的に切り替わる
<Box color="fg.default" bg="bg.subtle">
...
</Box>
カラーモード切り替えには、生成された components/ui/color-mode.tsx スニペットを使用するか、next-themes の useColorMode を直接使用します。
ステップ 6 — プロップ名の変更
これらのブール値およびスタイルプロップは、v3 で HTML および最新の React 規則との一貫性のために名前が変更されました。codemod はこれらのほとんどをキャッチしますが、その後手動で確認してください。
ブール値プロップ
| v2 | v3 |
|---|---|
isOpen | open |
defaultIsOpen | defaultOpen |
isDisabled | disabled |
isInvalid | invalid |
isRequired | required |
isReadOnly | readOnly |
isChecked | checked |
isLoaded | loaded |
isIndeterminate | indeterminate |
スタイルとレイアウトのプロップ
| v2 | v3 |
|---|---|
colorScheme | colorPalette |
noOfLines | lineClamp |
truncated | truncate |
spacing(Stack) | gap |
apply | textStyle または layerStyle |
ネストされたスタイルプロップ
// v2 — sx によるネストされた擬似セレクター
<Box sx={{ "&:hover": { color: "blue.500" } }} />
// v3 — css プロップと "&" セレクター
<Box css={{ "&:hover": { color: "blue.500" } }} />
ステップ 7 — コンポーネントの移行
名前が変更されたコンポーネント
| v2 | v3 |
|---|---|
Modal | Dialog |
FormControl | Field |
Select | NativeSelect |
AlertDialog | AlertDialog(複合、後述参照) |
Modal が最も一般的な名前変更です。すべての <Modal>、<ModalOverlay>、<ModalContent>、<ModalHeader>、<ModalBody>、<ModalFooter>、<ModalCloseButton> は Dialog.* 複合パーツになります。
// 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>
複合コンポーネントの書き換え
v3 は一貫した複合コンポーネント API を採用しています。codemod はこれらの多くを処理しますが、複雑なカスタム使用法は手動でのレビューが必要です。
Checkbox
// 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
// v2
<Progress value={60} colorScheme="blue" />
// v3
<Progress.Root value={60} colorPalette="blue">
<Progress.Track><Progress.Range /></Progress.Track>
</Progress.Root>
Accordion
// 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
// 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>
すべての FormControl サブパーツは Field.* にマッピングされます。
FormLabel→Field.LabelFormErrorMessage→Field.ErrorTextFormHelperText→Field.HelpTextFormControlのプロップisInvalid、isRequired、isDisabled→invalid、required、disabled
Dialog / Drawer / Menu / Tabs も同じ複合パターンに従います。ComponentName.Root、.Trigger、.Content、.Item などを使用します。各コンポーネントの具体的な複合 API については、Chakra UI v3 のドキュメントを確認してください。
Next.js の Image と Link(@chakra-ui/next-js の置き換え)
// 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>
ステップ 8 — テーマ設定の移行
styleConfig と multiStyleConfig → recipes
// 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" },
})
// 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" } },
})
カスタムトークンの型生成
カスタムトークン、セマンティックトークン、レシピ、スロットレシピを追加した後、型生成を実行して TypeScript の型を最新に保ちます。
npx @chakra-ui/cli typegen ./theme.ts
複雑なテーマの移行 — 多くのカスタムトークン、セマンティックトークン、またはマルチパートコンポーネントスタイルを含む大規模な v2 テーマを移行する場合は、
chakra-ui-themingスキルを使用してください。このスキルはトークン/レシピ/スロットレシピ API 全体を詳細にカバーしており、このセクション単独よりも優れたガイドとなります。
ステップ 9 — Next.js 固有の設定
App Router
<Provider>をapp/layout.tsx(サーバーコンポーネント —"use client"は不要)に配置します。- 生成された
components/ui/provider.tsxにはすでに"use client"が含まれています。 - カラーモードのちらつきを防ぐために、
<html>にsuppressHydrationWarningを追加します。 - アプリ全体またはレイアウトを
"use client"でラップしないでください。
Pages Router
// pages/_app.js
import { Provider } from "@/components/ui/provider"
export default function App({ Component, pageProps }) {
return (
<Provider>
<Component {...pageProps} />
</Provider>
)
}
pages/_document.tsx から ColorModeScript を削除してください — v3 では使用されません。
ステップ 10 — 検証チェックリスト
移行が完了したら、以下の項目を確認します。
- 依存関係の再インストール:
npm install/pnpm install - TypeScript:
npx tsc --noEmit— すべての型エラーを解決します - Lint:
npm run lint - ビルド:
npm run build - カラーモードの切り替え(ライト ↔ ダーク)を視覚的に確認します
- インタラクティブコンポーネントのテスト: Dialog、Drawer、Menu、Tabs、Accordion
- フォームコンポーネントのテスト: Checkbox、Select/NativeSelect、Input、Radio
- 主要ページ間で視覚的なリグレッションがないか確認します
- コードベースに残っている v2 のインポートを検索:
grep -r "ColorModeScript\|useColorModeValue\|extendTheme\|styleConfig\|@chakra-ui/icons\|@chakra-ui/next-js" src/
確認質問(コンテキストが不明瞭な場合)
ユーザーのバージョン、フレームワーク、または範囲が曖昧な場合は、以下を質問してください。
- 「現在お使いの
@chakra-ui/reactのバージョンはいくつですか?」 - 「Next.js App Router、Pages Router、Vite、またはプレーンな React のどれをお使いですか?」
- 「コードベース全体を移行するのですか、それとも特定のコンポーネントだけですか?」
質問せずに進める場合は、前提条件を明確に述べてください。