guideline

Shipping less CSS

Tree-shake the design system to the components your app renders, and ship only the color families it uses, with the @pindoba/styled-system Panda plugin.

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: [] })],
});

What it does

  • Tree-shakes the components. It turns on Panda’s 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…).
  • Ships only the color families you use (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 pluginpindoba()pindoba({ families: [] })
Landing (4 components)98 KB38 KB27 KB
Form (8)98 KB61 KB49 KB
Dashboard (14)98 KB67 KB54 KB

The live measurements are in the token cost lab.

Options

OptionDefaultWhat it does
familiesevery familyColor families to ship besides the semantic tones. A family left out loses its tokens, its colorPalette class and its chart slots.
rastertrueThe 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.
treeshaketruefalse ships every component’s CSS, as without the plugin.
debugfalseLogs each file’s imported packages and how many recipes they keep.

What it can’t see

The plugin reads imports, so it misses what is chosen at runtime:

  • A file Panda doesn’t scan gets no CSS. Put every file that imports a pindoba component in include — .mdx and .vue too.
  • A component picked by name at runtime (a CMS block renderer) — list its package in keep.
  • A tone that comes from data (tone={label.color}) — list every family it can be in families.