Builds accessible React applications with Chakra UI v3 components, tokens, and recipes. Use when creating styled component systems, theming, or accessible form controls.
Builds accessible React apps using Chakra UI v3 components, tokens, and recipes. Use when creating styled component systems, theming, or accessible form controls with compound components.
/plugin marketplace add mgd34msu/goodvibes-plugin/plugin install goodvibes@goodvibes-marketThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/components.mdreferences/theming.mdAccessible React component library with built-in styling, theming, and design tokens.
npm i @chakra-ui/react @emotion/react
# Add pre-built component snippets
npx @chakra-ui/cli snippet add
// components/ui/provider.tsx (generated by CLI)
import { ChakraProvider, defaultSystem } from '@chakra-ui/react'
export function Provider({ children }: { children: React.ReactNode }) {
return <ChakraProvider value={defaultSystem}>{children}</ChakraProvider>
}
// app layout
import { Provider } from '@/components/ui/provider'
export default function RootLayout({ children }) {
return (
<html>
<body>
<Provider>{children}</Provider>
</body>
</html>
)
}
// Usage
import { Button, HStack, Text } from '@chakra-ui/react'
function Demo() {
return (
<HStack gap="4">
<Button colorPalette="blue">Primary</Button>
<Button variant="outline">Secondary</Button>
</HStack>
)
}
Chakra v3 uses compound components with dot notation:
import { Accordion } from '@chakra-ui/react'
function FAQ() {
return (
<Accordion.Root>
<Accordion.Item value="item-1">
<Accordion.ItemTrigger>
What is Chakra UI?
<Accordion.ItemIndicator />
</Accordion.ItemTrigger>
<Accordion.ItemContent>
A component library for React.
</Accordion.ItemContent>
</Accordion.Item>
</Accordion.Root>
)
}
Apply styles directly via props:
import { Box, Flex, Text } from '@chakra-ui/react'
<Box
bg="blue.500"
color="white"
p="4"
rounded="lg"
shadow="md"
_hover={{ bg: 'blue.600' }}
>
Styled box
</Box>
<Flex
direction={{ base: 'column', md: 'row' }}
gap="4"
align="center"
justify="space-between"
>
<Text fontSize="xl" fontWeight="bold">Title</Text>
<Text color="gray.500">Subtitle</Text>
</Flex>
| Prop | CSS Property | Example |
|---|---|---|
bg | background | bg="blue.500" |
color | color | color="gray.700" |
p, px, py | padding | p="4" px="6" |
m, mx, my | margin | m="auto" my="8" |
w, h | width, height | w="full" h="100vh" |
rounded | border-radius | rounded="lg" |
shadow | box-shadow | shadow="md" |
display | display | display="flex" |
gap | gap | gap="4" |
import { Button, ButtonGroup } from '@chakra-ui/react'
<Button colorPalette="blue">Solid</Button>
<Button colorPalette="blue" variant="outline">Outline</Button>
<Button colorPalette="blue" variant="ghost">Ghost</Button>
<Button colorPalette="blue" variant="subtle">Subtle</Button>
<Button size="xs">Extra Small</Button>
<Button size="sm">Small</Button>
<Button size="md">Medium</Button>
<Button size="lg">Large</Button>
<Button loading loadingText="Saving...">Submit</Button>
<Button disabled>Disabled</Button>
<ButtonGroup>
<Button>One</Button>
<Button>Two</Button>
<Button>Three</Button>
</ButtonGroup>
import { Field, Input, Textarea, NativeSelect } from '@chakra-ui/react'
<Field.Root>
<Field.Label>Email</Field.Label>
<Input placeholder="you@example.com" />
<Field.HelperText>We'll never share your email</Field.HelperText>
</Field.Root>
<Field.Root invalid>
<Field.Label>Password</Field.Label>
<Input type="password" />
<Field.ErrorText>Password is required</Field.ErrorText>
</Field.Root>
<Field.Root>
<Field.Label>Country</Field.Label>
<NativeSelect.Root>
<NativeSelect.Field>
<option value="">Select country</option>
<option value="us">United States</option>
<option value="uk">United Kingdom</option>
</NativeSelect.Field>
</NativeSelect.Root>
</Field.Root>
import { Button, Dialog, Portal } from '@chakra-ui/react'
import { useState } from 'react'
function ModalExample() {
const [open, setOpen] = useState(false)
return (
<Dialog.Root open={open} onOpenChange={(e) => setOpen(e.open)}>
<Dialog.Trigger asChild>
<Button>Open Dialog</Button>
</Dialog.Trigger>
<Portal>
<Dialog.Backdrop />
<Dialog.Positioner>
<Dialog.Content>
<Dialog.Header>
<Dialog.Title>Dialog Title</Dialog.Title>
</Dialog.Header>
<Dialog.Body>
Dialog content goes here.
</Dialog.Body>
<Dialog.Footer>
<Dialog.ActionTrigger asChild>
<Button variant="outline">Cancel</Button>
</Dialog.ActionTrigger>
<Button colorPalette="blue">Confirm</Button>
</Dialog.Footer>
<Dialog.CloseTrigger />
</Dialog.Content>
</Dialog.Positioner>
</Portal>
</Dialog.Root>
)
}
import { Button, Menu, Portal } from '@chakra-ui/react'
<Menu.Root>
<Menu.Trigger asChild>
<Button variant="outline">Actions</Button>
</Menu.Trigger>
<Portal>
<Menu.Positioner>
<Menu.Content>
<Menu.Item value="edit">Edit</Menu.Item>
<Menu.Item value="duplicate">Duplicate</Menu.Item>
<Menu.Separator />
<Menu.Item value="delete" color="red.500">Delete</Menu.Item>
</Menu.Content>
</Menu.Positioner>
</Portal>
</Menu.Root>
import { Tabs } from '@chakra-ui/react'
<Tabs.Root defaultValue="account">
<Tabs.List>
<Tabs.Trigger value="account">Account</Tabs.Trigger>
<Tabs.Trigger value="settings">Settings</Tabs.Trigger>
<Tabs.Trigger value="billing">Billing</Tabs.Trigger>
</Tabs.List>
<Tabs.Content value="account">Account settings...</Tabs.Content>
<Tabs.Content value="settings">App settings...</Tabs.Content>
<Tabs.Content value="billing">Billing info...</Tabs.Content>
</Tabs.Root>
import { Card, Button, Image, Text } from '@chakra-ui/react'
<Card.Root maxW="sm">
<Image src="/product.jpg" alt="Product" />
<Card.Body gap="2">
<Card.Title>Product Name</Card.Title>
<Card.Description>
High-quality product description here.
</Card.Description>
<Text textStyle="2xl" fontWeight="medium" mt="2">
$99.00
</Text>
</Card.Body>
<Card.Footer gap="2">
<Button colorPalette="blue">Buy Now</Button>
<Button variant="ghost">Add to Cart</Button>
</Card.Footer>
</Card.Root>
// theme.ts
import { createSystem, defaultConfig, defineConfig } from '@chakra-ui/react'
const config = defineConfig({
theme: {
tokens: {
colors: {
brand: {
50: { value: '#e6f2ff' },
100: { value: '#b3d9ff' },
200: { value: '#80bfff' },
300: { value: '#4da6ff' },
400: { value: '#1a8cff' },
500: { value: '#0073e6' },
600: { value: '#005cb3' },
700: { value: '#004480' },
800: { value: '#002d4d' },
900: { value: '#00161a' },
},
},
fonts: {
heading: { value: 'Inter, sans-serif' },
body: { value: 'Inter, sans-serif' },
},
},
semanticTokens: {
colors: {
brand: {
solid: { value: '{colors.brand.500}' },
contrast: { value: 'white' },
fg: { value: '{colors.brand.700}' },
muted: { value: '{colors.brand.100}' },
subtle: { value: '{colors.brand.50}' },
emphasized: { value: '{colors.brand.200}' },
focusRing: { value: '{colors.brand.500}' },
},
},
},
},
})
export const system = createSystem(defaultConfig, config)
// provider.tsx
import { ChakraProvider } from '@chakra-ui/react'
import { system } from './theme'
export function Provider({ children }) {
return <ChakraProvider value={system}>{children}</ChakraProvider>
}
Chakra v3 provides 7 semantic tokens per color palette:
| Token | Purpose |
|---|---|
solid | Background for solid buttons |
contrast | Text on solid backgrounds |
fg | Foreground/text color |
muted | Muted backgrounds |
subtle | Subtle backgrounds |
emphasized | Hover states |
focusRing | Focus ring color |
<Box bg="brand.subtle" color="brand.fg" p="4">
Semantic tokens adjust for light/dark mode
</Box>
import { useColorMode, ColorModeButton } from '@chakra-ui/react'
function ThemeToggle() {
const { colorMode, toggleColorMode } = useColorMode()
return (
<Button onClick={toggleColorMode}>
{colorMode === 'light' ? 'Dark' : 'Light'} Mode
</Button>
)
}
// Or use built-in button
<ColorModeButton />
import { defineRecipe } from '@chakra-ui/react'
const buttonRecipe = defineRecipe({
base: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
fontWeight: 'medium',
rounded: 'lg',
transition: 'all 0.2s',
},
variants: {
visual: {
solid: {
bg: 'brand.500',
color: 'white',
_hover: { bg: 'brand.600' },
},
outline: {
border: '2px solid',
borderColor: 'brand.500',
color: 'brand.500',
},
},
size: {
sm: { h: '8', px: '3', fontSize: 'sm' },
md: { h: '10', px: '4', fontSize: 'md' },
lg: { h: '12', px: '6', fontSize: 'lg' },
},
},
defaultVariants: {
visual: 'solid',
size: 'md',
},
})
import { defineSlotRecipe } from '@chakra-ui/react'
const cardRecipe = defineSlotRecipe({
slots: ['root', 'header', 'body', 'footer'],
base: {
root: {
bg: 'white',
rounded: 'xl',
shadow: 'md',
overflow: 'hidden',
},
header: {
p: '4',
borderBottom: '1px solid',
borderColor: 'gray.200',
},
body: {
p: '4',
},
footer: {
p: '4',
borderTop: '1px solid',
borderColor: 'gray.200',
},
},
variants: {
variant: {
elevated: {
root: { shadow: 'xl' },
},
outline: {
root: {
shadow: 'none',
border: '1px solid',
borderColor: 'gray.200',
},
},
},
},
})
// Object syntax
<Box
fontSize={{ base: 'sm', md: 'md', lg: 'lg' }}
p={{ base: '2', md: '4', lg: '6' }}
display={{ base: 'block', md: 'flex' }}
>
Responsive content
</Box>
// Array syntax (mobile-first)
<Box fontSize={['sm', 'md', 'lg', 'xl']}>
Responsive text
</Box>
Breakpoints: base (0px), sm (480px), md (768px), lg (992px), xl (1280px), 2xl (1536px)
import { Box, Flex, Grid, Stack, Container, Center } from '@chakra-ui/react'
// Flex layout
<Flex gap="4" wrap="wrap" justify="space-between">
<Box>Item 1</Box>
<Box>Item 2</Box>
</Flex>
// Grid layout
<Grid templateColumns="repeat(3, 1fr)" gap="4">
<Box>Cell 1</Box>
<Box>Cell 2</Box>
<Box>Cell 3</Box>
</Grid>
// Stack (vertical by default)
<Stack gap="4">
<Box>Item 1</Box>
<Box>Item 2</Box>
</Stack>
// HStack / VStack
<HStack gap="4">...</HStack>
<VStack gap="4">...</VStack>
// Container with max-width
<Container maxW="6xl" px="4">
Centered content
</Container>
// Center content
<Center h="100vh">
Centered both ways
</Center>
Dialog.Root, Dialog.Content over flat importsbrand.solid instead of brand.500 for theme flexibilitynpx @chakra-ui/cli snippet add for pre-built patternsThis skill should be used when the user asks to "create an agent", "add an agent", "write a subagent", "agent frontmatter", "when to use description", "agent examples", "agent tools", "agent colors", "autonomous agent", or needs guidance on agent structure, system prompts, triggering conditions, or agent development best practices for Claude Code plugins.
This skill should be used when the user asks to "create a slash command", "add a command", "write a custom command", "define command arguments", "use command frontmatter", "organize commands", "create command with file references", "interactive command", "use AskUserQuestion in command", or needs guidance on slash command structure, YAML frontmatter fields, dynamic arguments, bash execution in commands, user interaction patterns, or command development best practices for Claude Code.
This skill should be used when the user asks to "create a hook", "add a PreToolUse/PostToolUse/Stop hook", "validate tool use", "implement prompt-based hooks", "use ${CLAUDE_PLUGIN_ROOT}", "set up event-driven automation", "block dangerous commands", or mentions hook events (PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification). Provides comprehensive guidance for creating and implementing Claude Code plugin hooks with focus on advanced prompt-based hooks API.