Config Functions
The define* helpers for authoring config, recipes, tokens, and themes in their own files with full type checking.
Use the define* helpers when you split your config across files. They give you autocomplete and type errors in files
that never import defineConfig.
Why wrap?
Inside defineConfig, TypeScript knows what shape each object should have. Move a recipe into its own file and that
knowledge is gone:
recipes/button.ts
// No autocomplete, and this mistake passes silently
export const button = {
variants: { size: { sm: {}, md: {} } },
defaultVariants: { size: 'lg' }
}Wrap it and the editor checks it again:
recipes/button.ts
import { defineRecipe } from '@pandacss/dev'
export const button = defineRecipe({
variants: { size: { sm: {}, md: {} } },
defaultVariants: { size: 'lg' } // ❌ '"lg"' is not assignable to '"sm" | "md"'
})Each helper returns its argument unchanged, so there's no runtime cost.
Config
defineConfig
Wraps the config object itself.
panda.config.ts
import { defineConfig } from '@pandacss/dev'
export default defineConfig({
theme: {},
include: ['src/**/*.{js,jsx,ts,tsx}']
})definePreset
For a preset.
import { definePreset } from '@pandacss/dev'
export const pandaPreset = definePreset({
theme: {
extend: {
tokens: {
colors: { primary: { value: 'blue.500' } }
}
}
}
})definePlugin
For a plugin that carries a shareable hooks map.
import { definePlugin } from '@pandacss/dev'
export const plugin = definePlugin({
name: 'css-report',
hooks: {
'cssgen:done': ({ path, content }) => {
console.log(`generated ${content.length} bytes`, path)
}
}
})Recipes and patterns
defineRecipe
For a config recipe.
import { defineRecipe } from '@pandacss/dev'
export const buttonRecipe = defineRecipe({
className: 'button',
description: 'The styles for the Button component',
base: {
display: 'flex'
},
variants: {
visual: {
funky: { bg: 'red.200', color: 'white' },
edgy: { border: '1px solid {colors.red.500}' }
}
},
defaultVariants: {
visual: 'funky'
}
})defineSlotRecipe
For a config slot recipe.
import { defineSlotRecipe } from '@pandacss/dev'
export const checkboxRecipe = defineSlotRecipe({
className: 'checkbox',
description: 'The styles for the Checkbox component',
slots: ['root', 'control', 'label'],
base: {
root: { display: 'flex', alignItems: 'center', gap: '2' },
control: { borderWidth: '1px', borderRadius: 'sm' },
label: { marginStart: '2' }
},
variants: {
size: {
sm: {
control: { width: '8', height: '8' },
label: { fontSize: 'sm' }
},
md: {
control: { width: '10', height: '10' },
label: { fontSize: 'md' }
}
}
},
defaultVariants: {
size: 'sm'
}
})defineStyles
For a style object you want to reuse. Spread it into each variant instead of repeating the properties:
recipes/button.ts
import { defineRecipe, defineStyles } from '@pandacss/dev'
const buttonVisualStyles = defineStyles({
borderRadius: 'lg',
boxShadow: 'sm'
})
export const buttonRecipe = defineRecipe({
// ...
variants: {
visual: {
funky: {
bg: 'red.200',
color: 'white',
...buttonVisualStyles
},
edgy: {
border: '1px solid {colors.red.500}',
...buttonVisualStyles
}
}
}
})definePattern
For a pattern.
import { definePattern } from '@pandacss/dev'
const visuallyHidden = definePattern({
transform(props) {
return {
srOnly: true,
...props
}
}
})Tokens
defineTokens
import { defineTokens } from '@pandacss/dev'
const theme = {
tokens: defineTokens({
colors: {
primary: { value: '#ff0000' }
}
})
}Keeping one category per file? Use defineTokens.colors(...) to check against just the colors shape:
tokens/colors.ts
import { defineTokens } from '@pandacss/dev'
export const colors = defineTokens.colors({
primary: { value: '#ff0000' }
})defineSemanticTokens
For tokens whose value depends on a condition, like color mode.
import { defineSemanticTokens } from '@pandacss/dev'
const theme = {
semanticTokens: defineSemanticTokens({
colors: {
primary: {
value: { _light: '{colors.blue.400}', _dark: '{colors.blue.200}' }
}
}
})
}The per-category form works here too:
tokens/colors.semantic.ts
import { defineSemanticTokens } from '@pandacss/dev'
export const colors = defineSemanticTokens.colors({
primary: {
value: { _light: '{colors.blue.400}', _dark: '{colors.blue.200}' }
}
})Theme and global styles
defineKeyframes
For @keyframes.
import { defineKeyframes } from '@pandacss/dev'
export const keyframes = defineKeyframes({
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' }
}
})defineGlobalStyles
For global styles.
import { defineGlobalStyles } from '@pandacss/dev'
const globalCss = defineGlobalStyles({
'html, body': {
color: 'gray.900',
lineHeight: '1.5'
}
})defineGlobalFontface
For globalFontface.
import { defineGlobalFontface } from '@pandacss/dev'
export const fonts = defineGlobalFontface({
Inter: {
src: 'url(/fonts/inter.woff2) format("woff2")',
fontWeight: 400,
fontStyle: 'normal'
}
})defineConditions
For custom conditions.
import { defineConditions } from '@pandacss/dev'
export const conditions = defineConditions({
groupHover: '.group:hover &',
cardHover: '[data-card]:hover &'
})defineUtility
For a custom utility.
import { defineUtility } from '@pandacss/dev'
export const br = defineUtility({
className: 'rounded',
values: 'radii',
transform(value) {
return { borderRadius: value }
}
})defineViewTransitions
For named view transitions.
import { defineViewTransitions } from '@pandacss/dev'
export const viewTransitions = defineViewTransitions({
slide: {
group: { animationDuration: '0.4s' },
old: { opacity: 0 },
new: { opacity: 1 }
}
})definePositionTry
For named position-try fallbacks.
import { definePositionTry } from '@pandacss/dev'
export const positionTry = definePositionTry({
bottom: {
top: 'anchor(bottom)',
insetInlineStart: 'anchor(start)'
}
})Text, layer, and animation styles
These have their own pages:
Multiple themes
defineThemeVariant
For a single theme variant, using the { tokens, semanticTokens } shape from
multi-theme tokens.
import { defineThemeVariant } from '@pandacss/dev'
export const darkTheme = defineThemeVariant({
tokens: {
colors: { bg: { value: '{colors.gray.900}' } }
}
})defineThemeContract
Declare the tokens every theme must provide. It returns a stricter defineThemeVariant that rejects a theme missing any
of them. See Theme contract.