Claude
Skills
Sign in
Back

chakra-ui-migrate

Included with Lifetime
$97 forever

Migrate Chakra UI projects from v2 to v3, covering package changes, codemods, provider setup, color mode, prop renaming, compound components, theming, recipes, and Next.js updates. Use this skill whenever a user is upgrading Chakra UI versions, encountering breaking changes after an upgrade, converting old v2 patterns (ColorModeScript, useColorModeValue, styleConfig, extendTheme, isDisabled, colorScheme, @chakra-ui/icons, framer-motion dependency), fixing compound component patterns, or asking about differences between Chakra UI v2 and v3 — even if they don't say "migrate" or "upgrade" explicitly.

Design

What this skill does


# Chakra UI Migration: 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.

---

## Step 1 — Inspect the project

Read these files to understand the current state:

```
package.json
```

Look for:

- Current `@chakra-ui/react` version (v2.x vs v3.x)
- Related packages: `@chakra-ui/icons`, `@chakra-ui/hooks`,
  `@chakra-ui/next-js`, `@emotion/styled`, `framer-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

---

## Step 2 — Update packages

### Remove v2-only dependencies

```bash
# 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` and `framer-motion` are no longer required in v3.

### Install v3 core packages

```bash
# npm
npm install @chakra-ui/react @emotion/react

# pnpm
pnpm add @chakra-ui/react @emotion/react

# yarn
yarn add @chakra-ui/react @emotion/react
```

### Replacements for removed packages

| Removed              | Replacement                                  |
| -------------------- | -------------------------------------------- |
| `@chakra-ui/icons`   | `lucide-react` or `react-icons`              |
| `@chakra-ui/hooks`   | `react-use` or `usehooks-ts`                 |
| `@chakra-ui/next-js` | `asChild` prop pattern (see Next.js section) |

---

## Step 3 — Run the 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 --dry
```

Review what it proposes. When satisfied:

```bash
npx @chakra-ui/codemod upgrade
```

After the codemod, commit the changes before making manual edits so you have a
clean diff to work from.

---

## Step 4 — Update the Provider

### Old v2 pattern

```tsx
// v2
import { ChakraProvider } from "@chakra-ui/react"
import theme from "./theme"

;<ChakraProvider theme={theme}>{children}</ChakraProvider>
```

### New v3 pattern (using Chakra CLI snippets)

Generate the provider and component snippets:

```bash
npx @chakra-ui/cli snippet add
```

This creates `components/ui/provider.tsx` (plus `toaster` and `tooltip`
snippets) and automatically installs required npm dependencies — including
`next-themes`. Import and use it:

```tsx
// 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 `Provider` file includes `"use client"` — do not add it to `layout.tsx`. See
the Next.js section for Pages Router placement.

### Custom theme in v3

Replace `extendTheme` with `createSystem`:

```ts
// 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 `system` to `ChakraProvider` via `value={system}`.

---

## Step 5 — Color mode migration

### Remove all v2 color mode patterns

```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} /> // ❌
```

### v3 color mode approach

Color mode is handled by `next-themes` via the generated `Provider`. Use
semantic tokens that automatically respond to the active color mode:

```tsx
// 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 `components/ui/color-mode.tsx`
snippet or `useColorMode` from `next-themes` directly.

---

## Step 6 — Prop renames

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.

### Boolean props

| v2                | v3              |
| ----------------- | --------------- |
| `isOpen`          | `open`          |
| `defaultIsOpen`   | `defaultOpen`   |
| `isDisabled`      | `disabled`      |
| `isInvalid`       | `invalid`       |
| `isRequired`      | `required`      |
| `isReadOnly`      | `readOnly`      |
| `isChecked`       | `checked`       |
| `isLoaded`        | `loaded`        |
| `isIndeterminate` | `indeterminate` |

### Style and layout props

| v2                | v3                          |
| ----------------- | --------------------------- |
| `colorScheme`     | `colorPalette`              |
| `noOfLines`       | `lineClamp`                 |
| `truncated`       | `truncate`                  |
| `spacing` (Stack) | `gap`                       |
| `apply`           | `textStyle` or `layerStyle` |

### 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" } }} />
```

---

## Step 7 — Component migrations

### Renamed components

| v2            | v3                                  |
| ------------- | ----------------------------------- |
| `Modal`       | `Dialog`                            |
| `FormControl` | `Field`                             |
| `Select`      | `NativeSelect`                      |
| `AlertDialog` | `AlertDialog` (compound, see below) |

`Modal` is the most common rename — every `<Modal>`, `<ModalOverlay>`,
`<ModalContent>`, `<ModalHeader>`, `<ModalBody>`, `<ModalFooter>`, and
`<ModalCloseButton>` becomes a `Dialog.*` compound part:

```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} colorSch
Files: 1
Size: 13.3 KB
Complexity: 22/100
Category: Design

Related in Design