Skip to content

Want to skip the docs? Check out pandamastery.com - the best way to learn Panda CSS

Customization

Presets

Package your tokens, theme, and utilities as a preset other projects can install.

A preset is a Panda config packaged for reuse. List one in presets, and Panda merges it into your own config before your own settings apply.

When to use a preset

Reach for a preset when tokens, theme, utilities, patterns, or recipes need to exist in more than one place:

  • A design language. Tokens, recipes, conditions. No components. This page.
  • Multiple apps, one look. The same colors, spacing, and breakpoints everywhere, defined once.

Shipping components plus that language is a design system. Apps that do not run Panda need a stylesheet, not a preset.

List a preset by package name:

import { defineConfig } from '@pandacss/dev'
 
export default defineConfig({
  presets: ['@acmecorp/panda-preset']
})

Creating a preset

A preset is a valid Panda config object, wrapped in definePreset for the type inference. It needs a unique name:

// my-preset.js
import { definePreset } from '@pandacss/dev'
 
export default definePreset({
  name: 'my-preset',
  theme: {
    tokens: {
      colors: {
        rose: {
          50: { value: '#fff1f2' },
          // ...
          800: { value: '#9f2233' }
        }
      }
    }
  }
})

Then list it like any other preset:

// panda.config.ts
import { defineConfig } from '@pandacss/dev'
import myPreset from './my-preset'
 
export default defineConfig({
  presets: [myPreset]
})

End to end: publish a preset, use it in an app

Create the preset package

@acme/preset/src/index.ts

import { definePreset } from '@pandacss/dev'
 
export const acmePreset = definePreset({
  name: '@acme/preset',
  theme: {
    extend: {
      tokens: {
        colors: {
          brand: { value: '#2563eb' }
        }
      }
    }
  }
})

Build and publish it

@acme/preset/package.json

{
  "name": "@acme/preset",
  "exports": {
    ".": {
      "import": "./dist/index.js",
      "require": "./dist/index.cjs"
    }
  }
}
pnpm tsup src/index.ts --format esm,cjs --dts
pnpm publish

Install it in the app

pnpm add -D @acme/preset

Add it to panda.config

presets is the exact list Panda uses, nothing extra is added for you. If you want the defaults, list @pandacss/preset-base (utilities and patterns) and @pandacss/preset-panda (tokens and text styles) explicitly, then your own preset after:

panda.config.ts

import { defineConfig } from '@pandacss/dev'
import basePreset from '@pandacss/preset-base'
import pandaPreset from '@pandacss/preset-panda'
import { acmePreset } from '@acme/preset'
 
export default defineConfig({
  presets: [basePreset, pandaPreset, acmePreset],
  include: ['./src/**/*.{js,jsx,ts,tsx}']
})

See which presets get included for what happens if you skip one.

Extend on top, from the app

theme.extend layers app-specific tokens on top of every preset. Presets merge in the order you list them, and the app's own config is applied last, so it always wins a conflict:

panda.config.ts

export default defineConfig({
  presets: [basePreset, pandaPreset, acmePreset],
  theme: {
    extend: {
      tokens: {
        colors: {
          brand: { value: '#1d4ed8' }
        }
      }
    }
  }
})

A preset can define any of these keys:

For components plus this preset, see Build a design system.

Async presets

A preset can be a function that returns a promise, useful when building the preset needs an await somewhere (reading colors from a design tool's API, say). Panda resolves it before merging, as long as it eventually resolves to a valid preset object:

// my-preset.js
export default async function myPreset() {
  const roseColors = await getRoseColors()
 
  return definePreset({
    name: 'my-preset',
    theme: {
      tokens: {
        colors: {
          rose: roseColors
        }
      }
    }
  })
}

Call it, don't just reference it, in the presets array:

// panda.config.ts
import { defineConfig } from '@pandacss/dev'
import myPreset from './my-preset'
 
export default defineConfig({
  presets: [myPreset()]
})

Which presets are included by default

None. Panda includes exactly what's in your presets array, nothing more.

  • @pandacss/preset-base: default utilities, conditions, and patterns. Only present if you list it.
  • @pandacss/preset-panda: default tokens, breakpoints, and text styles. Only present if you list it.

List both for the usual defaults, then your own preset after:

import basePreset from '@pandacss/preset-base'
import pandaPreset from '@pandacss/preset-panda'
import { defineConfig } from '@pandacss/dev'
 
export default defineConfig({
  presets: [basePreset, pandaPreset, myCustomPreset]
})

For a system with no defaults at all, presets: [].

Edit this page on GitHubView as markdown
Last updated on