Without help, Panda gives every app the CSS of every pindoba component, because
the design system ships its recipes pre-extracted. The
@pindoba/styled-system/plugin Panda plugin cuts that down to what the app
renders.
// panda.config.ts
import { defineConfig } from "@pandacss/dev";
import { pindoba } from "@pindoba/styled-system/plugin";
export default defineConfig({
designSystem: "@pindoba/styled-system",
include: ["./src/**/*.{ts,tsx,astro,svelte,vue,mdx}"],
plugins: [pindoba({ families: [] })],
});
optimize.treeshakeDesignSystem and, before Panda parses each file, adds
the import Panda needs for every @pindoba/* package the file imports — the
component’s recipe and every recipe it renders (a Select also brings ListBox,
Popover, Panel…).families). The five semantic
tones (primary, neutral, success, warning, danger) always ship,
with the families they are built on. Every other family — teal, violet,
the tinted grays, dynamic — ships only when listed.| App (Astro components, gzip) | Without the plugin | pindoba() | pindoba({ families: [] }) |
|---|---|---|---|
| Landing (4 components) | 98 KB | 38 KB | 27 KB |
| Form (8) | 98 KB | 61 KB | 49 KB |
| Dashboard (14) | 98 KB | 67 KB | 54 KB |
The live measurements are in the token cost lab.
| Option | Default | What it does |
|---|---|---|
families | every family | Color families to ship besides the semantic tones. A family left out loses its tokens, its colorPalette class and its chart slots. |
raster | true | The modular grid’s global rules (~24 KB). Set false when the app renders no Grid. |
keep | [] | @pindoba/* packages to ship even though no scanned file imports them. |
treeshake | true | false ships every component’s CSS, as without the plugin. |
debug | false | Logs each file’s imported packages and how many recipes they keep. |
The plugin reads imports, so it misses what is chosen at runtime:
include — .mdx and .vue too.keep.tone={label.color}) — list every family
it can be in families.