apps/www/content/docs/get-started/ai/rules.mdx
Configure your AI coding assistants (like Cursor, GitHub Copilot, or Claude) by
adding these rules to your project's .cursorrules,
.github/copilot-instructions.md, or AI configuration file.
Create a file with the following rules in your project root:
---
description: Chakra UI v3 Development Rules
globs: "*.tsx"
alwaysApply: false
---
## Core Migration Rules
### Package Changes
# Removed Packages
- Remove @emotion/styled and framer-motion dependencies
- Icons: Use lucide-react or react-icons instead of @chakra-ui/icons
- Hooks: Use react-use or usehooks-ts instead of @chakra-ui/hooks
- Next.js: Use asChild prop instead of @chakra-ui/next-js package
### Import Sources
Always use correct import sources:
# From @chakra-ui/react:
Alert, Avatar, Button, Card, Field, Table, Input, NativeSelect, Tabs, Textarea,
Separator, useDisclosure, Box, Flex, Stack, HStack, VStack, Text, Heading, Icon
# From components/ui (relative imports):
Provider, Toaster, ColorModeProvider, Tooltip, PasswordInput
### Toast System
```tsx
// ✅ New v3 way
import { toaster } from "./components/ui/toaster"
// ❌ Old v2 way
const toast = useToast()
toast({
title: "Title",
status: "error",
isClosable: true,
position: "top-right",
})
toaster.create({
title: "Title",
type: "error", // status → type
meta: {
closable: true, // isClosable → meta.closable
},
placement: "top-end", // top-right → top-end
})
```
### Dialog (formerly Modal)
```tsx
// ❌ Old v2
<Modal isOpen={isOpen} onClose={onClose} isCentered>
<ModalOverlay />
<ModalContent>
<ModalHeader>Title</ModalHeader>
<ModalBody>Content</ModalBody>
</ModalContent>
</Modal>
// ✅ New v3
<Dialog.Root open={isOpen} onOpenChange={onOpenChange} placement="center">
<Dialog.Backdrop />
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Title</Dialog.Title>
</Dialog.Header>
<Dialog.Body>Content</Dialog.Body>
</Dialog.Content>
</Dialog.Root>
```
### Button Icons
```tsx
// ❌ Old v2
<Button leftIcon={<Mail />} rightIcon={<ChevronRight />}>
Email
</Button>
// ✅ New v3
<Button>
<Mail /> Email <ChevronRight />
</Button>
```
### Alert Structure
```tsx
// ❌ Old v2
<Alert variant="left-accent">
<AlertIcon />
<AlertTitle>Title</AlertTitle>
<AlertDescription>Description</AlertDescription>
</Alert>
// ✅ New v3
<Alert.Root borderStartWidth="4px" borderStartColor="colorPalette.solid">
<Alert.Indicator />
<Alert.Content>
<Alert.Title>Title</Alert.Title>
<Alert.Description>Description</Alert.Description>
</Alert.Content>
</Alert.Root>
```
### Tooltip
```tsx
// ❌ Old v2
<Tooltip label="Content" hasArrow placement="top">
<Button>Hover me</Button>
</Tooltip>
// ✅ New v3
import { Tooltip } from "./components/ui/tooltip"
<Tooltip content="Content" showArrow positioning={{ placement: "top" }}>
<Button>Hover me</Button>
</Tooltip>
```
### Input with Validation
```tsx
// ❌ Old v2
<Input isInvalid />
// ✅ New v3
<Field.Root invalid>
<Field.Label>Email</Field.Label>
<Input />
<Field.ErrorText>This field is required</Field.ErrorText>
</Field.Root>
```
### Table Structure
```tsx
// ❌ Old v2
<Table variant="simple">
<Thead>
<Tr>
<Th>Header</Th>
</Tr>
</Thead>
<Tbody>
<Tr>
<Td>Cell</Td>
</Tr>
</Tbody>
</Table>
// ✅ New v3
<Table.Root variant="line">
<Table.Header>
<Table.Row>
<Table.ColumnHeader>Header</Table.ColumnHeader>
</Table.Row>
</Table.Header>
<Table.Body>
<Table.Row>
<Table.Cell>Cell</Table.Cell>
</Table.Row>
</Table.Body>
</Table.Root>
```
### Tabs
```tsx
// ❌ Old v2
<Tabs>
<TabList>
<Tab>One</Tab>
</TabList>
<TabPanels>
<TabPanel>Content</TabPanel>
</TabPanels>
</Tabs>
// ✅ New v3
<Tabs.Root defaultValue="one" colorPalette="orange">
<Tabs.List>
<Tabs.Trigger value="one">One</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="one">Content</Tabs.Content>
</Tabs.Root>
```
### Menu
```tsx
// ❌ Old v2
<Menu>
<MenuButton as={Button}>Actions</MenuButton>
<MenuList>
<MenuItem>Download</MenuItem>
</MenuList>
</Menu>
// ✅ New v3
<Menu.Root>
<Menu.Trigger asChild>
<Button>Actions</Button>
</Menu.Trigger>
<Menu.Content>
<Menu.Item value="download">Download</Menu.Item>
</Menu.Content>
</Menu.Root>
```
### Popover
```tsx
// ❌ Old v2
<Popover>
<PopoverTrigger>
<Button>Click</Button>
</PopoverTrigger>
<PopoverContent>
<PopoverArrow />
<PopoverBody>Content</PopoverBody>
</PopoverContent>
</Popover>
// ✅ New v3
<Popover.Root positioning={{ placement: "bottom-end" }}>
<Popover.Trigger asChild>
<Button>Click</Button>
</Popover.Trigger>
<Popover.Content>
<PopoverArrow />
<Popover.Body>Content</Popover.Body>
</Popover.Content>
</Popover.Root>
```
### Select/NativeSelect
```tsx
// ❌ Old v2
<Select placeholder="Select option">
<option value="1">Option 1</option>
</Select>
// ✅ New v3
<NativeSelect.Root size="sm">
<NativeSelect.Field placeholder="Select option">
<option value="1">Option 1</option>
</NativeSelect.Field>
<NativeSelect.Indicator />
</NativeSelect.Root>
```
## Prop Name Rules
### Boolean Props
- `isOpen` → `open`
- `isDisabled` → `disabled`
- `isInvalid` → `invalid`
- `isRequired` → `required`
- `isActive` → `data-active`
- `isLoading` → `loading`
- `isChecked` → `checked`
- `isIndeterminate` → `indeterminate`
### Style Props
- `colorScheme` → `colorPalette`
- `spacing` → `gap`
- `noOfLines` → `lineClamp`
- `truncated` → `truncate`
- `thickness` → `borderWidth`
- `speed` → `animationDuration`
### Component-Specific
- Divider → Separator
- Modal → Dialog
- Collapse → Collapsible
- Tags → Badge
- useToast → toaster.create()
## Style System Rules
### Nested Styles
```tsx
// ❌ Old v2
<Box sx={{ svg: { color: "red.500" } }} />
// ✅ New v3 (the & is required)
<Box css={{ "& svg": { color: "red.500" } }} />
```
### Gradients
```tsx
// ❌ Old v2
<Box bgGradient="linear(to-r, red.200, pink.500)" />
// ✅ New v3
<Box bgGradient="to-r" gradientFrom="red.200" gradientTo="pink.500" />
```
### Theme Access
```tsx
// ❌ Old v2
const theme = useTheme()
const gray400 = theme.colors.gray["400"]
// ✅ New v3
const system = useChakra()
const gray400 = system.token("colors.gray.400")
```
Create a .cursorrules file in your project root. Then feel free to copy and
paste the rules above.
Here's an example:
---
description: Chakra UI v3 Development
globs: "*.tsx"
---
# Chakra UI v3 Rules
This project uses Chakra UI v3. Follow these rules:
1. Import from @chakra-ui/react: Alert, Avatar, Button, Card, Field, Table, etc.
2. Import from components/ui: Checkbox, Drawer, Radio, Menu, Dialog, Tooltip,
etc.
3. Use toaster.create() instead of useToast()
4. Modal is now Dialog with different props
5. Boolean props changed: isOpen → open, isDisabled → disabled
6. colorScheme → colorPalette
7. Button icons are children, not props
8. Always use VStack/HStack, not Stack
9. Use compound components for complex components
10. Check migration guide for component-specific changes