dist/plugins/web-ui-chakra-ui/skills/web-ui-chakra-ui/SKILL.md
Accessible React component library with style props and theming
npx skillsauth add agents-inc/skills web-ui-chakra-uiInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Quick Guide: Chakra UI v3 is a composable, accessible React component library. Set up with
createSystem(defaultConfig)andChakraProvider. Style via props (bg,p,color), not className. Components are composable by default (Dialog.Root,Dialog.Content). Theme with design tokens and recipes viadefineConfig. Dark mode uses semantic tokens (bg.subtle,fg.muted) and_darkcondition. Removedframer-motionand@emotion/styleddeps from v2 -- uses CSS animations and recipes instead.
<critical_requirements>
All code must follow project conventions in CLAUDE.md (kebab-case, named exports, import ordering,
import type, named constants)
(You MUST wrap your app with ChakraProvider value={system} where system is created via createSystem(defaultConfig))
(You MUST use composable component patterns (Dialog.Root, Dialog.Content) -- v3 removed closed component APIs)
(You MUST use style props (bg, p, color) or the chakra factory for styling -- not raw className strings)
(You MUST prefer semantic tokens (bg.subtle, fg.muted) or _dark condition for dark mode -- avoid useColorModeValue when tokens suffice)
</critical_requirements>
Auto-detection: Chakra UI, @chakra-ui/react, ChakraProvider, createSystem, defaultConfig, chakra factory, style props, defineRecipe, defineSlotRecipe, colorPalette, semantic tokens, Ark UI
When to use:
When NOT to use:
Key patterns covered:
createSystem and ChakraProvider_dark conditionchakra factory for custom styled componentsChakra UI v3 is built on three pillars: Ark UI (headless component logic and accessibility), Panda CSS-inspired APIs (design tokens and recipes, powered by Emotion at runtime), and Park UI (default design system). Components are composable by default -- you compose Dialog.Root > Dialog.Content > Dialog.Body instead of passing everything as props to a single <Dialog>.
Key v3 principles:
bg.subtle adapts automatically, no conditional logicWhat Chakra UI handles vs what other skills handle:
Every Chakra v3 app needs createSystem and ChakraProvider. Add @layer directive for proper CSS ordering.
// theme.ts
import { createSystem, defaultConfig, defineConfig } from "@chakra-ui/react";
// Basic: use defaults
export const system = createSystem(defaultConfig);
// Custom: extend with your tokens
const config = defineConfig({
theme: {
tokens: {
colors: {
brand: {
50: { value: "#ffe5f1" },
500: { value: "#d53f8c" },
900: { value: "#521b41" },
},
},
},
},
});
export const system = createSystem(defaultConfig, config);
// app.tsx
import { ChakraProvider } from "@chakra-ui/react";
import { system } from "./theme";
export function App({ children }: { children: React.ReactNode }) {
return <ChakraProvider value={system}>{children}</ChakraProvider>;
}
/* Required CSS layer directive */
@layer reset, base, tokens, recipes;
Why good: createSystem merges your config with defaults, tokens become CSS variables, recipes generate atomic classes
See examples/core.md for framework-specific setup (SPA, SSR).
Style props are the primary way to style elements. They map directly to CSS properties with shorthand aliases and token values.
import { Box, Flex, Text } from "@chakra-ui/react";
// Style props with token values
<Box bg="blue.500" color="white" p="4" rounded="md" shadow="lg">
Styled via props
</Box>
// Shorthand aliases
<Box
mt="4" // marginTop
px="6" // paddingX (left + right)
w="full" // width: 100%
maxW="md" // maxWidth
mx="auto" // marginX: auto (centering)
/>
// Layout with Flex
<Flex gap="4" align="center" justify="between" wrap="wrap">
<Text fontSize="lg" fontWeight="bold">Title</Text>
<Text color="fg.muted">Subtitle</Text>
</Flex>
Why good: co-located styles, type-safe token values, responsive-ready, no separate CSS files
// BAD: using className strings with Chakra components
<Box className="bg-blue-500 p-4 rounded-md">Wrong approach</Box>
Why bad: bypasses token system, no type safety, loses dark mode adaptation
See examples/core.md for complete style prop reference.
Use object syntax (recommended) or array syntax for responsive values. Mobile-first with base as default.
// Object syntax (preferred) -- explicit breakpoint names
<Box
p={{ base: "4", md: "6", lg: "8" }}
fontSize={{ base: "sm", md: "md", lg: "lg" }}
display={{ base: "block", md: "flex" }}
/>
// Array syntax -- positional: [base, sm, md, lg, xl, 2xl]
<Box p={["4", "4", "6", "6", "8"]} />
// Skip breakpoints with undefined
<Text fontWeight={["medium", undefined, undefined, "bold"]} />
// Advanced: range targeting
<Text fontWeight={{ mdToXl: "bold" }} />
// Visibility helpers
<Box hideBelow="md">Desktop only</Box>
<Box hideFrom="md">Mobile only</Box>
Why good: mobile-first approach, named breakpoints are self-documenting, range targeting avoids repetition
v3 uses compound components with dot notation. All complex components follow Root > Trigger > Content > ... pattern.
import { Dialog, Button } from "@chakra-ui/react";
// Composable dialog
function ConfirmDialog() {
return (
<Dialog.Root>
<Dialog.Trigger asChild>
<Button>Open</Button>
</Dialog.Trigger>
<Dialog.Backdrop />
<Dialog.Content>
<Dialog.Header>Confirm Action</Dialog.Header>
<Dialog.Body>Are you sure?</Dialog.Body>
<Dialog.Footer>
<Dialog.CloseTrigger asChild>
<Button variant="outline">Cancel</Button>
</Dialog.CloseTrigger>
<Button colorPalette="red">Confirm</Button>
</Dialog.Footer>
</Dialog.Content>
</Dialog.Root>
);
}
// BAD: v2-style closed component API (removed in v3)
<Modal isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader>Title</ModalHeader>
<ModalBody>Content</ModalBody>
</ModalContent>
</Modal>
Why bad: v2 API removed in v3, isOpen/onClose replaced by open/onOpenChange, separate imports replaced by dot notation
See examples/composable-components.md for Menu, Popover, Drawer, and controlled patterns.
Recipes define reusable component styles with variants. Use defineRecipe for single-part, defineSlotRecipe for multi-part components.
import { defineRecipe } from "@chakra-ui/react";
const badgeRecipe = defineRecipe({
base: {
display: "inline-flex",
alignItems: "center",
fontWeight: "medium",
rounded: "full",
},
variants: {
variant: {
solid: { bg: "colorPalette.500", color: "white" },
outline: { borderWidth: "1px", borderColor: "colorPalette.500" },
subtle: { bg: "colorPalette.100", color: "colorPalette.800" },
},
size: {
sm: { px: "2", py: "0.5", fontSize: "xs" },
md: { px: "3", py: "1", fontSize: "sm" },
},
},
defaultVariants: { variant: "subtle", size: "sm" },
});
Register recipes in your system config via defineConfig({ theme: { recipes: { badge: badgeRecipe } } }).
Use with useRecipe hook or the chakra factory (recommended):
import { chakra } from "@chakra-ui/react";
const Badge = chakra("span", badgeRecipe);
// Usage
<Badge variant="solid" colorPalette="green" size="md">
Active
</Badge>;
See examples/theming.md for slot recipes, custom tokens, and semantic tokens.
Chakra v3 uses semantic tokens that adapt to color mode automatically. No conditional logic needed.
// RECOMMENDED: semantic tokens -- adapt automatically
<Box bg="bg.subtle" color="fg.default" borderColor="border.muted">
This adapts to light/dark mode automatically
</Box>
// Direct _dark condition for overrides
<Box bg="white" _dark={{ bg: "gray.800" }}>
Explicit dark mode override
</Box>
// Inline condition syntax
<Box bg={{ base: "white", _dark: "gray.800" }}>
Inline dark override
</Box>
Setup requires ColorModeProvider and the CLI snippet:
npx @chakra-ui/cli snippet add color-mode
import { ColorModeProvider } from "@/components/ui/color-mode";
import { ChakraProvider } from "@chakra-ui/react";
import { system } from "./theme";
function App({ children }: { children: React.ReactNode }) {
return (
<ChakraProvider value={system}>
<ColorModeProvider>{children}</ColorModeProvider>
</ChakraProvider>
);
}
Why good: semantic tokens are the cleanest approach, _dark condition for one-offs, avoids useColorModeValue boilerplate when tokens cover the use case
See examples/theming.md for theme toggle component and semantic token reference.
Use Field for form layout with labels, help text, and error messages. Works with any form library.
import { Field, Input, Button, Stack } from "@chakra-ui/react";
function LoginForm() {
return (
<Stack gap="4">
<Field.Root required>
<Field.Label>Email</Field.Label>
<Input type="email" placeholder="[email protected]" />
<Field.HelperText>We will never share your email.</Field.HelperText>
</Field.Root>
<Field.Root required invalid={!!errors?.password}>
<Field.Label>Password</Field.Label>
<Input type="password" />
{errors?.password && (
<Field.ErrorMessage>{errors.password}</Field.ErrorMessage>
)}
</Field.Root>
<Button type="submit" colorPalette="blue">
Sign In
</Button>
</Stack>
);
}
Why good: Field is form-library-agnostic, provides accessible labels and error messaging, composable structure
See examples/core.md for more form patterns.
</patterns>Detailed Resources:
<red_flags>
High Priority Issues:
isOpen/onClose props, useDisclosure, ChakraProvider without value prop, extendTheme are all removed@layer CSS directive -- without @layer reset, base, tokens, recipes; styles may not apply correctlyframer-motion -- removed in v3; use CSS animations or Chakra's built-in motion@emotion/styled -- removed in v3; use chakra factory or style props insteadMedium Priority Issues:
is prefix -- isDisabled is now disabled, isLoading is now loading, isInvalid is now invalidspacing prop on Stack -- renamed to gap to align with CSS@chakra-ui/icons -- removed in v3; use your preferred icon libraryuseColorModeValue when semantic tokens suffice -- prefer bg.subtle, fg.muted tokens or _dark condition; useColorModeValue still works but adds unnecessary boilerplateCommon Mistakes:
import { ListItem } is now List.Item via dot notationblue.500) or semantic tokens (colorPalette.500)asChild for composition -- the as prop has limited support; use asChild for polymorphismChakraProvider -- components silently fail without the provider contextGotchas & Edge Cases:
onOpenChange callback shape -- receives { open: boolean } object, not a plain boolean: onOpenChange={(details) => setOpen(details.open)}@layer reset, base, tokens, recipes; must be in your root CSSnpx @chakra-ui/cli snippet add), not installed packagescolorPalette prop -- swaps the entire color context for a component tree; affects all children using colorPalette.* tokensdefaultSystem shortcut -- for zero-config, import defaultSystem directly instead of calling createSystem</red_flags>
<critical_reminders>
All code must follow project conventions in CLAUDE.md
(You MUST wrap your app with ChakraProvider value={system} where system is created via createSystem(defaultConfig))
(You MUST use composable component patterns (Dialog.Root, Dialog.Content) -- v3 removed closed component APIs)
(You MUST use style props (bg, p, color) or the chakra factory for styling -- not raw className strings)
(You MUST prefer semantic tokens (bg.subtle, fg.muted) or _dark condition for dark mode -- avoid useColorModeValue when tokens suffice)
Failure to follow these rules will produce broken v2-style code that does not work with Chakra UI v3.
</critical_reminders>
development
Material Design component library for Vue 3
development
VitePress 1.x — Vue-powered static site generator for documentation sites, built on Vite
tools
Docusaurus 3.x documentation framework — site configuration, docs/blog plugins, sidebars, versioning, MDX, swizzling, and deployment
development
TanStack Form patterns - useForm, form.Field, validators, arrays, linked fields, createFormHook, type safety