Chakra UI Migration: v2 → v3
Du begleitest einen Entwickler bei der Migration seines Projekts von Chakra UI v2 nach v3. Arbeite die folgenden Schritte der Reihe nach ab. Untersuche zuerst das Projekt – rate niemals über die Paketversionen oder das Framework.
Node-Anforderung: Chakra UI v3 benötigt Node >= 20.x. Bestätige dies vor dem Fortfahren, falls die Umgebung nicht sicher ist.
Schritt 1 – Projekt inspizieren
Lies diese Dateien, um den aktuellen Zustand zu verstehen:
package.json
Suche nach:
- Aktuelle
@chakra-ui/react-Version (v2.x vs v3.x) - Verwandte Pakete:
@chakra-ui/icons,@chakra-ui/hooks,@chakra-ui/next-js,@emotion/styled,framer-motion - Framework: Next.js (App Router oder Pages Router), Vite, reines React
- Paketmanager (aus Lockfiles:
pnpm-lock.yaml,yarn.lock,bun.lock,package-lock.json)
Überprüfe bei Bedarf auch Schlüsseldateien:
- Provider-/Theme-Setup (
_app.tsx,layout.tsx,theme.ts) - Farbmodus-Nutzung (
ColorModeScript,useColorMode,useColorModeValue) - Komponentendateien, die starke v2-Muster zeigen
Schritt 2 – Pakete aktualisieren
Entferne v2-spezifische Abhängigkeiten
# 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 und framer-motion werden in v3 nicht mehr benötigt.
Installiere v3-Kernpakete
# npm
npm install @chakra-ui/react @emotion/react
# pnpm
pnpm add @chakra-ui/react @emotion/react
# yarn
yarn add @chakra-ui/react @emotion/react
Ersatz für entfernte Pakete
| Entfernt | Ersatz |
|---|---|
@chakra-ui/icons | lucide-react oder react-icons |
@chakra-ui/hooks | react-use oder usehooks-ts |
@chakra-ui/next-js | asChild-Prop-Muster (siehe Next.js-Abschnitt) |
Schritt 3 – Codemod ausführen
Der offizielle Codemod übernimmt die meisten mechanischen Änderungen: Komponenten-Umbenennungen, Prop-Updates, Import-Umschreibungen und Umstrukturierung zusammengesetzter Komponenten. Er ersetzt keine manuelle Überprüfung – plane eine Prüfung der Ausgabe ein.
Zuerst einen Probelauf durchführen (keine Dateien werden geändert):
npx @chakra-ui/codemod upgrade --dry
Überprüfe, was vorgeschlagen wird. Wenn du zufrieden bist:
npx @chakra-ui/codemod upgrade
Nach dem Codemod committe die Änderungen, bevor du manuelle Bearbeitungen vornimmst, damit du einen sauberen Diff hast.
Schritt 4 – Provider aktualisieren
Altes v2-Muster
// v2
import { ChakraProvider } from "@chakra-ui/react"
import theme from "./theme"
;<ChakraProvider theme={theme}>{children}</ChakraProvider>
Neues v3-Muster (mit Chakra CLI-Snippets)
Generiere die Provider- und Komponenten-Snippets:
npx @chakra-ui/cli snippet add
Dies erstellt components/ui/provider.tsx (plus toaster- und tooltip-Snippets) und installiert automatisch erforderliche npm-Abhängigkeiten – einschließlich next-themes. Importiere und verwende es:
// v3 — app/layout.tsx (Next.js App Router)
import { Provider } from "@/components/ui/provider"
;<html lang="en" suppressHydrationWarning>
<body>
<Provider>{children}</Provider>
</body>
</html>
Die Provider-Datei enthält "use client" – füge es nicht zu layout.tsx hinzu. Siehe den Next.js-Abschnitt für die Platzierung im Pages Router.
Benutzerdefiniertes Theme in v3
Ersetze extendTheme durch 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)
Übergib system an ChakraProvider via value={system}.
Schritt 5 – Farbmodus-Migration
Entferne alle v2-Farbmodus-Muster
// ENTFERNE diese v2-Importe und -Verwendungen:
import { ColorModeScript } from "@chakra-ui/react"
// ❌
import { useColorMode } from "@chakra-ui/react"
// ❌ (verwende next-themes)
import { useColorModeValue } from "@chakra-ui/react"
// ❌ (verwende CSS-Tokens)
import { DarkMode, LightMode } from "@chakra-ui/react"
// ❌
// Entferne auch aus _document.tsx:
;<ColorModeScript initialColorMode={theme.config.initialColorMode} /> // ❌
v3-Farbmodus-Ansatz
Der Farbmodus wird von next-themes über den generierten Provider verwaltet. Verwende semantische Tokens, die automatisch auf den aktiven Farbmodus reagieren:
// Verwende Chakra-semantische Tokens – sie wechseln automatisch im Dunkelmodus
<Box color="fg.default" bg="bg.subtle">
...
</Box>
Für einen Farbmodus-Umschalter verwende das generierte Snippet components/ui/color-mode.tsx oder useColorMode von next-themes direkt.
Schritt 6 – Prop-Umbenennungen
Diese booleschen und Style-Props wurden in v3 zur Konsistenz mit HTML und modernen React-Konventionen umbenannt. Der Codemod erfasst die meisten, aber überprüfe danach manuell.
Boolesche Props
| v2 | v3 |
|---|---|
isOpen | open |
defaultIsOpen | defaultOpen |
isDisabled | disabled |
isInvalid | invalid |
isRequired | required |
isReadOnly | readOnly |
isChecked | checked |
isLoaded | loaded |
isIndeterminate | indeterminate |
Style- und Layout-Props
| v2 | v3 |
|---|---|
colorScheme | colorPalette |
noOfLines | lineClamp |
truncated | truncate |
spacing (Stack) | gap |
apply | textStyle oder layerStyle |
Verschachtelte Style-Props
// v2 — sx mit verschachtelten Pseudo-Selektoren
<Box sx={{ "&:hover": { color: "blue.500" } }} />
// v3 — css-Prop mit "&"-Selektoren
<Box css={{ "&:hover": { color: "blue.500" } }} />
Schritt 7 – Komponenten-Migrationen
Umbenannte Komponenten
| v2 | v3 |
|---|---|
Modal | Dialog |
FormControl | Field |
Select | NativeSelect |
AlertDialog | AlertDialog (zusammengesetzt, siehe unten) |
Modal ist die häufigste Umbenennung – jedes <Modal>, <ModalOverlay>,
<ModalContent>, <ModalHeader>, <ModalBody>, <ModalFooter> und
<ModalCloseButton> wird zu einem zusammengesetzten Dialog.*-Teil:
// 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>
Umschreibung zusammengesetzter Komponenten
v3 verwendet eine konsistente API für zusammengesetzte Komponenten. Der Codemod übernimmt viele davon, aber komplexe benutzerdefinierte Nutzung erfordert manuelle Überprüfung.
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>
Alle FormControl-Unterteile werden auf Field.* abgebildet:
FormLabel→Field.LabelFormErrorMessage→Field.ErrorTextFormHelperText→Field.HelpTextFormControl-PropsisInvalid,isRequired,isDisabled→invalid,required,disabled
Dialog / Drawer / Menu / Tabs folgen dem gleichen zusammengesetzten Muster: Verwende ComponentName.Root, .Trigger, .Content, .Item usw. Überprüfe die Chakra-UI-v3-Dokumentation für die spezifische zusammengesetzte API für jede.
Next.js Image und Link (Ersatz für @chakra-ui/next-js)
// v2 — @chakra-ui/next-js
import { LinkOverlay } from "@chakra-ui/next-js"
// v3 — asChild-Muster
import NextLink from "next/link"
<ChakraLink asChild><NextLink href="/about">About</NextLink></ChakraLink>
import NextImage from "next/image"
<ChakraImage asChild><NextImage src="..." alt="..." /></ChakraImage>
Schritt 8 – Theming-Migration
styleConfig und multiStyleConfig → recipes
// v3 — einzelne Komponente (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 — slot recipe
import { defineSlotRecipe } from "@chakra-ui/react"
// v2 — multiStyleConfig (mehrteilige Komponente)
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 für benutzerdefinierte Tokens
Nach dem Hinzufügen benutzerdefinierter Tokens, semantischer Tokens, Recipes oder Slot-Recipes führe Typegen aus, um die TypeScript-Typen synchron zu halten:
npx @chakra-ui/cli typegen ./theme.ts
Komplexe Theme-Migrationen – wenn du ein großes v2-Theme mit vielen benutzerdefinierten Tokens, semantischen Tokens oder mehrteiligen Komponenten-Stilen migrierst, verwende die
chakra-ui-theming-Skill. Sie deckt die vollständige Token/Recipe/Slot-Recipe-API ausführlich ab und ist eine bessere Anleitung als dieser Abschnitt allein.
Schritt 9 – Next.js-Spezifika
App Router
- Platziere
<Provider>inapp/layout.tsx(Server-Komponente – kein"use client") - Die generierte
components/ui/provider.tsxhat bereits"use client" - Füge
suppressHydrationWarningzu<html>hinzu, um Farbmodus-Flackern zu verhindern - Ummantle nicht die gesamte App oder das Layout mit
"use client"
Pages Router
// pages/_app.js
import { Provider } from "@/components/ui/provider"
export default function App({ Component, pageProps }) {
return (
<Provider>
<Component {...pageProps} />
</Provider>
)
}
Entferne jeglichen ColorModeScript aus pages/_document.tsx – er wird in v3 nicht verwendet.
Schritt 10 – Validierungs-Checkliste
Arbeite diese Liste nach Abschluss der Migration durch:
- Abhängigkeiten neu installieren:
npm install/pnpm install - TypeScript:
npx tsc --noEmit– alle Typfehler beheben - Lint:
npm run lint - Build:
npm run build - Visuell überprüfen: Farbmodus-Umschalter (hell ↔ dunkel)
- Interaktive Komponenten testen: Dialog, Drawer, Menu, Tabs, Accordion
- Formularkomponenten testen: Checkbox, Select/NativeSelect, Input, Radio
- Auf visuelle Regressionen auf Schlüsselseiten prüfen
- Codebasis nach übriggebliebenen v2-Importen durchsuchen:
grep -r "ColorModeScript\|useColorModeValue\|extendTheme\|styleConfig\|@chakra-ui/icons\|@chakra-ui/next-js" src/
Rückfragen (wenn der Kontext unklar ist)
Wenn die Version des Benutzers, das Framework oder der Umfang mehrdeutig ist, frage nach:
- „Welche Version von
@chakra-ui/reactverwendest du derzeit?“ - „Verwendest du Next.js App Router, Pages Router, Vite oder reines React?“
- „Migrierst du die gesamte Codebasis oder nur bestimmte Komponenten?“
Lege Annahmen klar dar, wenn du ohne Nachfrage fortfährst.