Configuring Panda
Customize how Panda works via the `panda.config.ts` file in your project.
Customize how Panda works via the panda.config.ts file in your project.
import { defineConfig } from '@pandacss/dev'
export default defineConfig({
// your configuration options here...
})
Output css options
presets
Type: (string | Preset | Promise<Preset>)[]
Default: []
The set of reusable and shareable configuration presets. Presets are explicit — Panda does not auto-inject any preset.
For the default utilities, tokens, and conditions, add @pandacss/preset-base and @pandacss/preset-panda yourself
(panda init scaffolds this for you). Without them you get a bare system.
Each preset you add is smartly merged with your config, with your own config acting as a set of overrides and extensions.
{
"presets": ["@pandacss/preset-base", "@pandacss/preset-panda"]
}
preflight
Type: boolean | { scope: string; }
Default: false
Whether to enable css reset styles. See also Global styles for how reset interacts with global variables and layering.
Enable preflight:
{
"preflight": true
}
You can also scope the preflight; Especially useful for being able to scope the CSS reset to only a part of the app for some reason.
Enable preflight and customize the scope:
{
"preflight": { "scope": ".extension" }
}
The resulting reset css would look like this:
.extension button,
.extension select {
text-transform: none;
}
.extension table {
text-indent: 0;
border-color: inherit;
border-collapse: collapse;
}
You can also set the level to element (defaults to parent) to only reset the elements that have the scope class
assigned.
{
"preflight": { "scope": ".extension", "level": "element" }
}
The resulting reset css would look like this:
button.extension,
select.extension {
text-transform: none;
}
table.extension {
text-indent: 0;
border-color: inherit;
border-collapse: collapse;
}
prefix
Type: string | { cssVar?: string; className?: string }
The namespace prefix for the generated css classes and css variables. Pass a string to prefix both, or an object to set the css variable and class name prefixes separately.
Ex: when using a prefix of panda-
{
"prefix": "panda"
}
import { css } from '../styled-system/css'
const App = () => {
return <div className={css({ color: 'blue.500' })} />
}
would result in:
.panda-text_blue\.500 {
color: var(--panda-colors-blue-500);
}
layers
Type: Partial<Layer>
Cascade layers used in generated css.
Ex: when customizing the utilities layer
{
"layers": {
"utilities": "panda_utilities"
}
}
import { css } from '../styled-system/css'
const App = () => {
return <div className={css({ color: 'blue.500' })} />
}
would result in:
@layer panda_utilities {
.text_blue\.500 {
color: var(--colors-blue-500);
}
}
You should update the layer in your root css also.
separator
Type: '_' | '=' | '-'
Default: '_'
The separator for the generated css classes.
{
"separator": "_"
}
Using a = with:
import { css } from '../styled-system/css'
const App = () => {
return <div className={css({ color: 'blue.500' })} />
}
would result in:
.text\=blue\.500 {
color: var(--colors-blue-500);
}
minify
Type: boolean
Default: false
Whether to minify the generated css. This can be set to true to reduce the size of the generated css.
Often enabled only in production. See Environment-specific config.
{
"minify": false
}
hash
Type: boolean | { cssVar: boolean; className: boolean }
Default: false
Whether to hash the generated class names / css variables. This is useful if want to shorten the class names or css variables.
Often enabled only in production. See Environment-specific config.
Hash the class names and css variables:
{
"hash": true
}
This
import { css } from '../styled-system/css'
const App = () => {
return <div className={css({ color: 'blue.500' })} />
}
would result in something that looks like:
.dOFUTE {
color: var(--cgpxvS);
}
You can also hash them individually.
E.g. only hash the css variables:
{
"hash": { "cssVar": true, "className": false }
}
Then the result looks like this:
.text_blue\.500 {
color: var(--cgpxvS);
}
Now only hash the class names:
{
"hash": { "cssVar": false, "className": true }
}
Then the result looks like this:
.dOFUTE {
color: var(--colors-blue-500);
}
optimize
Type: OptimizeOptions
Default: {}
CSS emission optimizations. Every optimization is opt-in.
{
"optimize": {
"removeUnusedTokens": true,
"removeUnusedKeyframes": true,
"smartCompoundVariants": true,
"treeshakeDesignSystem": true,
"propertyFallback": true
}
}
removeUnusedTokens— remove unused token declarations based on extracted project usage.removeUnusedKeyframes— remove unused keyframes based on extracted project usage.smartCompoundVariants— narrow compound variant CSS to the variant combinations you actually use, instead of emitting every permutation.treeshakeDesignSystem— hydrate only the build-info modules for the design-system exports your app imports. Namespace and side-effect imports still hydrate everything.propertyFallback— also seed@propertyregistrations as plain declarations, for engines that ignore@property(Safari < 16.4, Firefox < 128) and would otherwise drop declarations that read an unregistered variable.
removeUnusedTokens and removeUnusedKeyframes replace the cleanup people used to do in a cssgen:done hook.
File system options
cwd
Type: string
Default: process.cwd()
The current working directory.
{
"cwd": "src"
}
outdir
Type: string
Default: styled-system
The output directory for the generated css.
{
"outdir": "styled-system"
}
importMap
Type: string | Partial<OutdirImportMap> | Array<string | Partial<OutdirImportMap>>
Default:
{ "css": "styled-system/css", "recipes": "styled-system/recipes", "patterns": "styled-system/patterns", "jsx": "styled-system/jsx" }
Allows you to customize the import paths for the generated outdir.
{
"importMap": {
"css": "@acme/styled-system",
"recipes": "@acme/styled-system",
"patterns": "@acme/styled-system",
"jsx": "@acme/styled-system"
}
}
You can also use a string to customize the base import path and keep the default entrypoints:
{
"importMap": "@scope/styled-system"
}
is the equivalent of:
{
"importMap": {
"css": "@scope/styled-system/css",
"recipes": "@scope/styled-system/recipes",
"patterns": "@scope/styled-system/patterns",
"jsx": "@scope/styled-system/jsx"
}
}
Pass an array to match imports from more than one root, for example a shared design system package alongside the
app's own local styled-system output:
{
"importMap": ["@acme/styled-system", "./styled-system"]
}
Individual fields also accept an array of paths when only some categories need more than one root:
{
"importMap": {
"css": ["@acme/styled-system/css", "./styled-system/css"],
"recipes": "@acme/styled-system/recipes"
}
}
Check out Shared styled-system in a monorepo for a full example of
using multiple importMap roots, or the Component Library guide for the
external-package case.
designSystem
Type: string
Consume a published design system. Point this at the package and Panda resolves its manifest, merges its preset, and
applies its build info — you don't set importMap or list build info in include.
{
"designSystem": "@acme/design-system"
}
Check out Consuming a design system for the full workflow.
include
Type: string[]
Default: []
List of files glob to watch for changes.
{
"include": ["./src/**/*.{js,jsx,ts,tsx}", "./pages/**/*.{js,jsx,ts,tsx}"]
}
exclude
Type: string[]
Default: []
List of files glob to ignore.
{
"exclude": []
}
dependencies
Type: string[]
Default: []
Explicit list of config related files that should trigger a context reload on change.
We automatically track the config file and (transitive) files imported by the config file as much as possible, but sometimes we might miss some. You can use this option as a workaround for those edge cases.
{
"dependencies": ["path/to/files/**.ts"]
}
outExtension
Type: 'ts' | 'js' | 'mjs'
Default: js
File extension for generated javascript files.
{
"outExtension": "js"
}
forceImportExtension
Type: boolean
Default: false
Whether generated import specifiers include the runtime file extension. When outExtension is mjs, this also emits
.d.mts instead of .d.ts.
{
"forceImportExtension": true
}
syntax
Type: 'object-literal' | 'template-literal'
Default: object-literal
Decides which syntax to use when writing CSS. For existing projects, you might need to run the panda codegen --clean.
{
"syntax": "template-literal"
}
Ex object-literal:
const styles = css({
backgroundColor: 'gainsboro',
padding: '10px 15px'
})
Ex template-literal:
const Container = styled.div`
background-color: gainsboro;
padding: 10px 15px;
`
polyfill
Type: boolean
Default: false
Polyfill CSS @layers at-rules for older browsers.
{
"polyfill": true
}
Design token options
shorthands
Type: boolean
Default: true
Whether to allow shorthand properties
{
"shorthands": true
}
Ex true:
const styles = css({
bgColor: 'gainsboro',
p: '10px 15px'
})
Ex false:
const styles = css({
backgroundColor: 'gainsboro',
padding: '10px 15px'
})
cssVarRoot
Type: string
Default: :where(:host, :root)
The root selector for the css variables.
{
"cssVarRoot": ":where(:host, :root)"
}
conditions
Type: Extendable<Conditions>
Default: {}
The css selectors or media queries shortcuts.
{
"conditions": { "hover": "&:hover" }
}
globalCss
Type: Extendable<GlobalStyleObject>
Default: {}
The global styles for your project.
{
"globalCss": {
"html, body": {
"margin": 0,
"padding": 0
}
}
}
theme
Type: Extendable<Theme>
Default: {}
The theme configuration for your project.
{
"theme": {
"tokens": {
"colors": {
"red": { "value": "#EE0F0F" },
"green": { "value": "#0FEE0F" }
}
},
"semanticTokens": {
"colors": {
"danger": { "value": "{colors.red}" },
"success": { "value": "{colors.green}" }
}
}
}
}
themes
Type: Extendable<ThemeVariantsMap>
Default: {}
The theme variants configuration for your project.
{
"themes": {
"primary": {
"tokens": {
"colors": {
"text": { "value": "red" }
}
},
"semanticTokens": {
"colors": {
"muted": { "value": "{colors.red.200}" },
"body": {
"value": {
"base": "{colors.red.600}",
"_osDark": "{colors.red.400}"
}
}
}
}
},
"secondary": {
"tokens": {
"colors": {
"text": { "value": "blue" }
}
},
"semanticTokens": {
"colors": {
"muted": { "value": "{colors.blue.200}" },
"body": {
"value": {
"base": "{colors.blue.600}",
"_osDark": "{colors.blue.400}"
}
}
}
}
}
}
}
utilities
Type: Extendable<UtilityConfig>
Default: {}
The css utility definitions.
{
"utilities": {
extend: {
borderX: {
values: ['1px', '2px', '4px'],
shorthand: 'bx', // `bx` or `borderX` can be used
transform(value, token) {
return {
borderInlineWidth: value,
borderColor: token('colors.red.200'), // read the css variable for red.200
}
},
},
},
}
}
patterns
Type: Extendable<Record<string, AnyPatternConfig>>
Default: {}
Common styling or layout patterns for your project.
{
"patterns": {
extend: {
// Extend the default `flex` pattern
flex: {
properties: {
// only allow row and column
direction: { type: 'enum', value: ['row', 'column'] },
},
},
},
},
}
staticCss
Type: StaticCssOptions
Default: {}
Used to generate css utility classes for your project.
{
"staticCss": {
css: [
{
properties: {
margin: ['*'],
padding: ['*', '50px', '80px'],
},
responsive: true,
},
{
properties: {
color: ['*'],
backgroundColor: ['green.200', 'red.400'],
},
conditions: ['light', 'dark'],
},
],
},
}
strictTokens
Type: boolean
Default: false
Only allow token values and prevent custom or raw CSS values. Will only affect properties that have config tokens, such
as color, bg, borderColor, etc. Learn more.
{
"strictTokens": false
}
strictPropertyValues
Type: boolean
Default: false
Only use valid CSS values for properties that do have a predefined list of values. Will throw for properties that do not
have config tokens, such as display, content, willChange, etc.
Learn more.
{
"strictPropertyValues": false
}
globalFontface
Type: GlobalFontfaceDefinition
Default: {}
Global font face definitions.
{
"globalFontface": {
"Inter": {
"src": "url(/fonts/inter.woff2) format('woff2')",
"fontWeight": "400",
"fontStyle": "normal"
},
"Roboto": {
"src": "url(/fonts/roboto.woff2) format('woff2')",
"fontWeight": "400",
"fontStyle": "normal"
}
}
}
Check out the Custom Fonts guide for more information on how to use the
globalFontface option.
globalVars
Type: Extendable<GlobalVarsDefinition>
Default: {}
The global CSS variables for your project. A plain string emits the variable directly; an object registers it with
@property, and only reaches the output if the stylesheet reads or writes it.
{
"globalVars": {
"--some-color": "red",
"--button-color": {
"syntax": "<color>",
"inherits": false,
"initialValue": "blue"
}
}
}
globalPositionTry
Type: Extendable<GlobalPositionTry>
Default: {}
Global @position-try fallbacks for anchor positioning, keyed by the fallback name.
{
"globalPositionTry": {
"--bottom": {
"top": "anchor(bottom)"
}
}
}
JSX options
jsxFramework
Type: 'react' | 'solid' | 'preact' | 'vue' | 'qwik' | (string & {})
JS Framework for generated JSX elements.
{
"jsxFramework": "react"
}
jsxFactory
Type: string
The factory name of the element
{
"jsxFactory": "panda"
}
Ex:
<panda.button marginTop="40px">Click me</panda.button>
jsxStyleProps
Type: all | minimal | none
Default: all
The style props allowed on generated JSX components
- When set to 'all', all style props are allowed.
- When set to 'minimal', only the
cssprop is allowed. - When set to 'none', no style props are allowed and therefore the
jsxFactorywill not be usable as a component:<styled.div />andstyled("div")aren't valid- but the recipe usage is still valid
styled("div", { base: { color: "red.300" }, variants: { ...} })
Ex with 'all':
<styled.button marginTop="40px">Click me</styled.button>
Ex with 'minimal':
<styled.button css={{ marginTop: '40px' }}>Click me</styled.button>
Ex with 'none':
<button className={css({ marginTop: '40px' })}>Click me</button>
Documentation options
log level
Type: 'debug' | 'info' | 'warn' | 'error' | 'silent'
Default: info
The log level for the built-in logger.
{
"logLevel": "info"
}
validation
Type: 'none' | 'warn' | 'error'
Default: warn
The validation strictness to use when validating the config.
- When set to 'none', no validation will be performed.
- When set to 'warn', warnings will be logged when validation fails.
- When set to 'error', errors will be thrown when validation fails.
{
"validation": "error"
}
Other options
plugins
Type: PandaPlugin[]
Plugins are simple objects that contain a name and a hooks object. Hooks live on plugins — there is no root-level
hooks config option. Check the Hooks docs for the full list of callbacks.
Plugins are called in sequence in the order they are defined in the plugins array, with the user's config called last.
import { defineConfig } from '@pandacss/dev'
export default defineConfig({
// ...
plugins: [
{
name: 'local',
hooks: {
'cssgen:done': ({ content, path }) => {
report({ bytes: content.length, path })
}
}
}
]
})