customization
presets

Presets

Creating your own reusable preset for utilities and theme

By default, any configuration you add in your own panda.config.js file is smartly merged with the default presets, allowing you to override or extend specific parts of the configuration.

When to use a preset

Use a preset when you want to share tokens, theme, utilities, patterns, or recipes across projects:

  • Design system package — one npm package for your tokens and theme
  • Multiple apps — the same colors, spacing, and breakpoints everywhere
  • Component libraries — consumers add your preset in panda.config.ts (component library guide)

If the app does not use Panda, ship static CSS instead. See the component library guide for other options.

You can specify a preset in your panda.config.js file by using the presets option:

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

Creating a preset

Presets are also valid Panda configuration objects, taking a similar shape to the configuration you would add in your panda.config.ts file.

💡

Note: Every preset must have 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' }
        }
      }
    }
  }
})

You can then use this preset in your panda.config.ts file:

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

End-to-end example

This walks through publishing a preset and using it in an app. For library build details, see Ship a Panda preset.

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

@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 in your app

pnpm add -D @acme/preset

Add it to panda.config

Setting presets replaces the default @pandacss/preset-panda. Include it explicitly if you still want the default theme:

panda.config.ts

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

@pandacss/preset-base is still included automatically unless you set eject: true. See when each preset is included.

Extend the preset in the app

Use theme.extend to add or override tokens on top of the preset. Presets merge in order — later entries win on conflicts. See extend.

panda.config.ts

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

The available keys for a preset are:

Asynchronous presets

There are cases where you need to perform logic to determine the content of your preset, you'd call functions to do this. In cases where they're asynchronous; panda allows promises, given that they resolve 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
        }
      }
    }
  })
}

You can then use this preset in your panda.config.ts file:

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

What each built-in preset does

Panda ships two presets by default. They do different jobs, so it helps to know what you get from each before you drop one.

@pandacss/preset-base — utilities, conditions, and patterns

Gives you the styling vocabulary out of the box:

  • Utilities — the style props you write every day (bg, p, mx, rounded, display, …) and how they map to CSS. See utilities.
  • Conditions — the selectors behind pseudo-state props like _hover, _focus, _dark, and _disabled. See conditional styles.
  • Patterns — layout helpers like stack, hstack, grid, and container. See patterns.

It ships no design tokens (no colors, no spacing). Set eject: true to leave it out, then you define your own utilities, conditions, and patterns. See minimal setup.

@pandacss/preset-panda — the default theme

This is the opinionated design system: the tokens and theme Panda uses out of the box.

  • Tokens — colors, spacing, sizes, fonts, font sizes, radii, shadows, durations, easings, and more. See tokens.
  • Breakpoints (these power the responsive sm/md/lg conditions), keyframes, text styles, and container sizes.

Drop it if you bring your own design system, and keep it if you want sensible defaults to start from. Removing it only takes away these values — the styling engine (preset-base) keeps working.

When each preset is included

Visual helper

  • @pandacss/preset-base is always included unless you set eject: true.
  • @pandacss/preset-panda is included only when you don't set the presets option. Once you set presets, add it back yourself if you still want the default theme:
import pandaPreset from '@pandacss/preset-panda'
import { defineConfig } from '@pandacss/dev'
 
export default defineConfig({
  // ...
  presets: [pandaPreset, myCustomPreset]
})

Minimal setup

If you want to use Panda with the bare minimum, without any of the defaults, you can read more about it here