Que fait Migration Chakra UI : v2 → v3 ?
Vous guidez un développeur dans la migration de son projet de Chakra UI v2 vers v3. Suivez les étapes ci-dessous dans l'ordre. Inspectez d'abord le projet — ne devinez jamais les versions des packages ou le framework.
Prérequis Node : Chakra UI v3 nécessite Node >= 20.x. Confirmez avant de continuer si l'environnement est incertain.
Étape 1 — Inspecter le projet
Lisez ces fichiers pour comprendre l'état actuel :
package.json
Recherchez :
- Version actuelle de
@chakra-ui/react(v2.x vs v3.x) - Packages associés :
@chakra-ui/icons,@chakra-ui/hooks,@chakra-ui/next-js,@emotion/styled,framer-motion - Framework : Next.js (App Router ou Pages Router), Vite, React simple
- Gestionnaire de packages (d'après les lockfiles :
pnpm-lock.yaml,yarn.lock,bun.lock,package-lock.json)
Vérifiez aussi ponctuellement les fichiers clés lorsque c'est utile :
- Configuration Provider / thème (
_app.tsx,layout.tsx,theme.ts) - Utilisation du mode couleur (
ColorModeScript,useColorMode,useColorModeValue) - Tout fichier de composant montrant des motifs v2 lourds
Étape 2 — Mettre à jour les packages
Supprimer les dépendances spécifiques à 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 et framer-motion ne sont plus nécessaires dans v3.
Installer les packages principaux 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
Remplacements pour les packages supprimés
| Supprimé | Remplacement |
|---|---|
@chakra-ui/icons | lucide-react ou react-icons |
@chakra-ui/hooks | react-use ou usehooks-ts |
@chakra-ui/next-js | Prop asChild (voir section Next.js) |
Étape 3 — Exécuter le codemod
Le codemod officiel gère la plupart des changements mécaniques : renommage de composants, mise à jour des props, réécriture des imports, et restructuration des composants composites. Il ne remplace pas une vérification manuelle — prévoyez d'auditer le résultat.
D'abord un essai à blanc (aucun fichier modifié) :
npx @chakra-ui/codemod upgrade --dry
Examinez ce qu'il propose. Une fois satisfait :
npx @chakra-ui/codemod upgrade
Après le codemod, validez les changements avant de faire des modifications manuelles afin d'avoir un diff propre à partir duquel travailler.
Étape 4 — Mettre à jour le Provider
Ancien motif v2
// v2
import { ChakraProvider } from "@chakra-ui/react"
import theme from "./theme"
;<ChakraProvider theme={theme}>{children}</ChakraProvider>
Nouveau motif v3 (en utilisant les snippets CLI Chakra)
Générez le provider et les snippets de composants :
npx @chakra-ui/cli snippet add
Ceci crée components/ui/provider.tsx (ainsi que les snippets toaster et tooltip) et installe automatiquement les dépendances npm nécessaires — y compris next-themes. Importez-le et utilisez-le :
// v3 — app/layout.tsx (Next.js App Router)
import { Provider } from "@/components/ui/provider"
;<html lang="en" suppressHydrationWarning>
<body>
<Provider>{children}</Provider>
</body>
</html>
Le fichier Provider inclut "use client" — ne l'ajoutez pas à layout.tsx. Voir la section Next.js pour le placement dans Pages Router.
Thème personnalisé dans v3
Remplacez extendTheme par 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)
Passez system à ChakraProvider via value={system}.
Étape 5 — Migration du mode couleur
Supprimer tous les motifs de mode couleur v2
// SUPPRIMEZ ces imports et utilisations v2 :
import { ColorModeScript } from "@chakra-ui/react"
// ❌
import { useColorMode } from "@chakra-ui/react"
// ❌ (utilisez next-themes)
import { useColorModeValue } from "@chakra-ui/react"
// ❌ (utilisez les tokens CSS)
import { DarkMode, LightMode } from "@chakra-ui/react"
// ❌
// Supprimez aussi de _document.tsx :
;<ColorModeScript initialColorMode={theme.config.initialColorMode} /> // ❌
Approche du mode couleur dans v3
Le mode couleur est géré par next-themes via le Provider généré. Utilisez les tokens sémantiques qui répondent automatiquement au mode couleur actif :
// Utilisez les tokens sémantiques Chakra — ils basculent automatiquement en mode sombre
<Box color="fg.default" bg="bg.subtle">
...
</Box>
Pour un bouton de bascule de mode couleur, utilisez le snippet généré components/ui/color-mode.tsx ou useColorMode de next-themes directement.
Étape 6 — Renommage des props
Ces props booléennes et de style ont été renommées dans v3 pour une cohérence avec les conventions HTML et React modernes. Le codemod détecte la plupart d'entre elles, mais vérifiez manuellement après.
Props booléennes
| v2 | v3 |
|---|---|
isOpen | open |
defaultIsOpen | defaultOpen |
isDisabled | disabled |
isInvalid | invalid |
isRequired | required |
isReadOnly | readOnly |
isChecked | checked |
isLoaded | loaded |
isIndeterminate | indeterminate |
Props de style et disposition
| v2 | v3 |
|---|---|
colorScheme | colorPalette |
noOfLines | lineClamp |
truncated | truncate |
spacing (Stack) | gap |
apply | textStyle ou layerStyle |
Props de style imbriquées
// v2 — sx avec pseudo-sélecteurs imbriqués
<Box sx={{ "&:hover": { color: "blue.500" } }} />
// v3 — prop css avec sélecteurs "&"
<Box css={{ "&:hover": { color: "blue.500" } }} />
Étape 7 — Migrations des composants
Composants renommés
| v2 | v3 |
|---|---|
Modal | Dialog |
FormControl | Field |
Select | NativeSelect |
AlertDialog | AlertDialog (composite, voir ci-dessous) |
Modal est le renommage le plus courant — chaque <Modal>, <ModalOverlay>, <ModalContent>, <ModalHeader>, <ModalBody>, <ModalFooter>, et <ModalCloseButton> devient une partie composite Dialog.* :
// v2
<Modal isOpen={open} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Titre</ModalHeader>
<ModalBody>Corps</ModalBody>
<ModalFooter><Button onClick={onClose}>Fermer</Button></ModalFooter>
</ModalContent>
</Modal>
// v3
<Dialog.Root open={open} onOpenChange={({ open }) => setOpen(open)}>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Header><Dialog.Title>Titre</Dialog.Title></Dialog.Header>
<Dialog.Body>Corps</Dialog.Body>
<Dialog.Footer><Button onClick={() => setOpen(false)}>Fermer</Button></Dialog.Footer>
<Dialog.CloseTrigger />
</Dialog.Content>
</Dialog.Positioner>
</Dialog.Root>
Réécriture des composants composites
v3 adopte une API composite cohérente. Le codemod gère beaucoup de ces transformations, mais une utilisation personnalisée complexe nécessite une vérification manuelle.
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>Nous ne partagerons jamais votre email.</FormHelperText>
</FormControl>
// v3
<Field.Root invalid={!!error} required>
<Field.Label>Email</Field.Label>
<Input type="email" />
<Field.ErrorText>{error}</Field.ErrorText>
<Field.HelpText>Nous ne partagerons jamais votre email.</Field.HelpText>
</Field.Root>
Toutes les sous-parties de FormControl correspondent à Field.* :
FormLabel→Field.LabelFormErrorMessage→Field.ErrorTextFormHelperText→Field.HelpText- Props de
FormControlisInvalid,isRequired,isDisabled→invalid,required,disabled
Dialog / Drawer / Menu / Tabs suivent le même motif composite : utilisez ComponentName.Root, .Trigger, .Content, .Item, etc. Consultez la documentation Chakra UI v3 pour l'API composite spécifique de chacun.
Image et Link Next.js (remplaçant @chakra-ui/next-js)
// v2 — @chakra-ui/next-js
import { LinkOverlay } from "@chakra-ui/next-js"
// v3 — motif asChild
import NextLink from "next/link"
<ChakraLink asChild><NextLink href="/about">À propos</NextLink></ChakraLink>
import NextImage from "next/image"
<ChakraImage asChild><NextImage src="..." alt="..." /></ChakraImage>
Étape 8 — Migration du thème
styleConfig et multiStyleConfig → recettes
// v3 — composant unique (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 (composant à plusieurs parties)
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 pour les tokens personnalisés
Après avoir ajouté des tokens personnalisés, des tokens sémantiques, des recettes ou des slot recipes, exécutez typegen pour garder les types TypeScript synchronisés :
npx @chakra-ui/cli typegen ./theme.ts
Migrations de thème complexes — si vous déplacez un thème v2 volumineux avec de nombreux tokens personnalisés, tokens sémantiques ou styles de composants multi-parties, utilisez la compétence
chakra-ui-theming. Elle couvre en profondeur l'API complète des tokens/recettes/slot-recettes et constitue un meilleur guide que cette section seule.
Étape 9 — Spécificités Next.js
App Router
- Placez
<Provider>dansapp/layout.tsx(Composant Serveur — pas de"use client") - Le fichier généré
components/ui/provider.tsxa déjà"use client" - Ajoutez
suppressHydrationWarningà<html>pour éviter le scintillement du mode couleur - N'enveloppez pas toute l'application ou le layout dans
"use client"
Pages Router
// pages/_app.js
import { Provider } from "@/components/ui/provider"
export default function App({ Component, pageProps }) {
return (
<Provider>
<Component {...pageProps} />
</Provider>
)
}
Supprimez tout ColorModeScript de pages/_document.tsx — il n'est pas utilisé dans v3.
Étape 10 — Checklist de validation
Passez en revue ceci une fois la migration terminée :
- Réinstaller les dépendances :
npm install/pnpm install - TypeScript :
npx tsc --noEmit— résoudre toutes les erreurs de type - Lint :
npm run lint - Build :
npm run build - Vérifier visuellement la bascule du mode couleur (clair ↔ sombre)
- Tester les composants interactifs : Dialog, Drawer, Menu, Tabs, Accordion
- Tester les composants de formulaire : Checkbox, Select/NativeSelect, Input, Radio
- Vérifier les régressions visuelles sur les pages clés
- Rechercher dans le codebase les imports v2 restants :
grep -r "ColorModeScript\|useColorModeValue\|extendTheme\|styleConfig\|@chakra-ui/icons\|@chakra-ui/next-js" src/
Questions de clarification (quand le contexte est flou)
Si la version, le framework ou la portée de l'utilisateur sont ambigus, demandez :
- "Quelle version de
@chakra-ui/reactutilisez-vous actuellement ?" - "Utilisez-vous Next.js App Router, Pages Router, Vite ou React simple ?"
- "Migrez-vous l'intégralité du codebase ou seulement des composants spécifiques ?"
Énoncez clairement les hypothèses si vous procédez sans demander.