Skip to content

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

Ship the library

Monorepo workflow

Watch panda lib in the package. Never put a manifest package in include.

The design system and the app are workspace packages. Run panda lib --watch in the library. The app points at it with designSystem.

my-design-system/
├── packages/
│   ├── ds/
│   └── app/
├── package.json
└── pnpm-workspace.yaml

pnpm-workspace.yaml

packages:
  - 'packages/*'

packages/app/package.json

{
  "dependencies": {
    "@acme/ds": "workspace:*"
  }
}

packages/app/panda.config.ts

export default defineConfig({
  designSystem: '@acme/ds',
  include: ['src/**/*.{ts,tsx}']
})

Do not include the library source

A package that already ran panda lib has a manifest (dist/panda/lib.json). It belongs in designSystem, not include.

packages/app/panda.config.ts

export default defineConfig({
  designSystem: '@acme/ds',
  // ❌ errors: design_system_in_include
  include: ['src/**/*.{ts,tsx}', '@acme/ds']
})

A path glob into the package does not error. It re-extracts source the manifest already covers, so remove it too:

packages/app/panda.config.ts

export default defineConfig({
  designSystem: '@acme/ds',
  include: [
    'src/**/*.{ts,tsx}',
    // ⚠️ no error, but wasted work: buildinfo.json already has these styles
    './node_modules/@acme/ds/src/**/*.{ts,tsx}'
  ]
})

The app replays the styles recorded in buildinfo.json. It does not re-scan the library source.

Watch the library

packages/ds/package.json

{
  "scripts": {
    "watch": "panda codegen && panda lib --watch"
  }
}
pnpm --filter @acme/ds watch
pnpm --filter @acme/app dev

panda lib --watch rewrites dist/panda/ when tokens, recipes, or components change. It does not rerun panda codegen. If a change updates generated styled-system files, run panda codegen again, or keep a second codegen watcher.

Panda watches the app's include plus the library's manifest and build-info paths. Editing library source updates JS through your bundler. CSS can lag until panda lib finishes. That is a known limit.

When CSS does not update

  1. Confirm the library watcher is running and dist/panda/buildinfo.json is rewriting.
  2. Confirm the app lists designSystem: '@acme/ds', not the library in include.
  3. Run the app with --log-level debug and save again.
  4. If Panda rewrote CSS but the browser did not, the bundler is not watching the workspace package. Vite often skips node_modules (including workspace links).

packages/app/vite.config.ts

export default defineConfig({
  server: {
    watch: {
      ignored: ['!**/node_modules/@acme/ds/**']
    }
  }
})

Exact Vite / webpack flags depend on the app. The symptom is the same: files on disk are new, the dev server is not.

Build order

Start the library watcher first. The app's first panda codegen needs dist/panda/ (or a workspace:* source export) to resolve.

package.json

{
  "scripts": {
    "dev": "pnpm --filter @acme/ds watch & pnpm --filter @acme/app dev"
  }
}

See also

Edit this page on GitHubView as markdown
Last updated on