Installation
Add Pockets UI to a React app: install the package, point Panda CSS at the design system, generate the styled system, and start building.
1. Install the packages
@pockets-ui/components is the whole design system: the React components,
the tokens and recipes, and a generated Panda styled system. Panda CSS itself
is a dev dependency, plus the plugin for your bundler.
bun add @pockets-ui/components
bun add -D @pandacss/dev @pandacss/postcss@pockets-ui/components— the React components, built on React Aria, and the Panda design system they are styled with (css(), tokens, recipes, patterns).@pandacss/dev— Panda CSS (v2 or later; needs Node 22+). Generates the styled system and the CSS.@pandacss/postcss— emits the CSS at build time. Use@pandacss/viteor@pandacss/buninstead if that is your bundler.@pockets-ui/utils— framework utilities likecreatePocket, which wraps the React context boilerplate for compound-component state. Already a dependency of@pockets-ui/components; install it directly when you import from it yourself.
2. Point Panda at the design system
A panda.config.ts at your project root opts into the design system with
one line. You only declare where your own app code lives.
import { defineConfig } from "@pandacss/dev"
export default defineConfig({
designSystem: "@pockets-ui/components",
include: ["./app/**/*.{ts,tsx}", "./src/**/*.{ts,tsx}"],
})Do not list @pockets-ui/components in include, and do not set prefix,
hash, or separator — the design system owns those and Panda will refuse
the config.
Then wire up the rest of the consumer contract:
-
postcss.config.mjs— registers the Panda plugin:export default { plugins: { "@pandacss/postcss": {} } } -
package.json— a"prepare": "panda codegen"script (orpredev/prebuild) so the styled system regenerates on every install. -
app/globals.css— declares the cascade-layer order Panda emits into:@layer reset, base, tokens, recipes, utilities; -
data-pockets-theme="light"(or"dark","winter","christmas") on a root element such as<html>.
3. Generate the styled system
Codegen writes a thin styled-system/ folder into your app: your own
token-aware css() function and tokens, with jsx, recipes, and
patterns re-exported from @pockets-ui/components. The prepare script
runs it on install, but you can run it directly any time — for example after
upgrading @pockets-ui/components or editing panda.config.ts.
bunx panda codegen4. Use it
Import components from @pockets-ui/components and style your own elements
with css() from your app's styled-system/css. Every property is typed
against the token scales, and semantic tokens like bg and fg.subtle adapt
to light and dark mode automatically.
import { Button } from "@pockets-ui/components"
import { css } from "./styled-system/css"
const banner = css({
padding: "4",
borderRadius: "lg",
backgroundColor: "bg.subtle",
color: "fg",
})
export function Welcome() {
return (
<div className={banner}>
<Button variant="primary">Get started</Button>
</div>
)
}If your app extends nothing in the theme, css() from
@pockets-ui/components/css is the same function and skips the local
folder. The recipes are always available as @pockets-ui/components/recipes.
Extending the theme
panda.config.ts accepts the full Panda config surface, so app-level
additions — say, wiring your framework's font variables into the heading
and body font tokens — go under theme.extend. Re-run codegen after any
config change.
import { defineConfig } from "@pandacss/dev"
export default defineConfig({
designSystem: "@pockets-ui/components",
include: ["./app/**/*.{ts,tsx}", "./src/**/*.{ts,tsx}"],
theme: {
extend: {
tokens: {
fonts: {
heading: { value: "var(--font-funnel-display)" },
body: { value: "var(--font-instrument-sans)" },
},
},
},
},
})Without Panda
For an app with no Panda build step — a Rails view, a legacy bundle — the package ships a complete stylesheet with every recipe variant and text style pre-built:
import "@pockets-ui/components/styles.css"The components work as-is on this path. The one limit: css() and style
props on those components generate class names at runtime with no matching
CSS, so only recipe variants are styled.