Fix: Panda CSS Not Working — Styles Not Applying, Tokens Not Resolving, or Build Errors
Quick Answer
How to fix Panda CSS issues — PostCSS setup, panda.config.ts token system, recipe and pattern definitions, conditional styles, responsive design, and integration with Next.js and Vite.
The Problem
You write Panda CSS styles but nothing appears:
import { css } from '../styled-system/css';
function Button() {
return (
<button className={css({ bg: 'blue.500', color: 'white', p: '4' })}>
Click me
</button>
);
}
// Button renders with no styles — plain unstyled HTMLOr a token value doesn’t resolve:
css({ color: 'primary' })
// TypeScript error: Type '"primary"' is not assignable to type...Or the build fails:
Error: Cannot find module '../styled-system/css'Why This Happens
Panda CSS is a build-time CSS-in-JS library. It scans your source files at build time, extracts style function calls, and generates a static CSS file. No runtime JavaScript:
- The
styled-systemdirectory must be generated first — runningnpx panda codegencreates thestyled-system/directory withcss,cva,sva, and other utilities. Without this step, imports fail. The codegen must re-run whenever you changepanda.config.ts. - Panda scans specific file paths — the
includearray inpanda.config.tstells Panda which files to scan for style usage. Files outside this glob pattern are invisible to Panda, and their styles won’t appear in the generated CSS. - Token values must exist in the theme —
color: 'blue.500'works becauseblue.500is a default token.color: 'primary'only works if you defineprimaryin thetheme.tokensortheme.semanticTokensconfig. Unrecognized values cause type errors. - Generated CSS must be imported — Panda generates a CSS file that you must import in your app’s entry point. Without this import, the generated styles exist but aren’t loaded.
Fix 1: Set Up Panda CSS
npm install -D @pandacss/dev
npx panda init// panda.config.ts
import { defineConfig } from '@pandacss/dev';
export default defineConfig({
// Enable CSS reset
preflight: true,
// Files to scan for styles
include: [
'./src/**/*.{ts,tsx,js,jsx}',
'./app/**/*.{ts,tsx,js,jsx}', // Next.js App Router
'./pages/**/*.{ts,tsx,js,jsx}', // Next.js Pages Router
'./components/**/*.{ts,tsx,js,jsx}',
],
// Files to exclude
exclude: [],
// Theme customization
theme: {
extend: {
tokens: {
colors: {
primary: { value: '#3b82f6' },
secondary: { value: '#64748b' },
},
fonts: {
body: { value: 'Inter, sans-serif' },
heading: { value: 'Cal Sans, sans-serif' },
},
},
semanticTokens: {
colors: {
// Tokens that change with color mode
text: {
value: { base: '{colors.gray.900}', _dark: '{colors.gray.100}' },
},
bg: {
value: { base: 'white', _dark: '{colors.gray.900}' },
},
accent: {
value: { base: '{colors.primary}', _dark: '{colors.blue.400}' },
},
},
},
},
},
// Output directory for generated code
outdir: 'styled-system',
// JSX framework
jsxFramework: 'react', // 'react' | 'solid' | 'vue' | 'qwik'
});# Generate the styled-system directory
npx panda codegen
# Add to package.json scripts
# "prepare": "panda codegen"// postcss.config.mjs — required
export default {
plugins: {
'@pandacss/dev/postcss': {},
},
};/* src/index.css or app/globals.css — import generated styles */
@layer reset, base, tokens, recipes, utilities;// Import CSS in your entry point
// app/layout.tsx (Next.js) or src/main.tsx (Vite)
import './globals.css';Fix 2: Use the css() Function and Utilities
import { css } from '../styled-system/css';
import { flex, center, stack, grid } from '../styled-system/patterns';
// Basic styles
function Card() {
return (
<div
className={css({
bg: 'white',
borderRadius: 'lg',
boxShadow: 'md',
p: '6',
// Shorthand properties
mx: 'auto', // marginInline
mt: '4', // marginTop
w: 'full', // width
maxW: 'lg', // maxWidth
})}
>
<h2 className={css({
fontSize: '2xl',
fontWeight: 'bold',
color: 'gray.900',
mb: '2',
})}>
Card Title
</h2>
<p className={css({ color: 'gray.600', lineHeight: 'relaxed' })}>
Card content here.
</p>
</div>
);
}
// Responsive styles — mobile-first breakpoints
function ResponsiveLayout() {
return (
<div
className={css({
display: 'flex',
flexDirection: 'column',
gap: '4',
// Responsive: sm, md, lg, xl, 2xl
md: {
flexDirection: 'row',
gap: '8',
},
lg: {
maxW: '6xl',
mx: 'auto',
},
})}
>
<aside className={css({ w: { base: 'full', md: '1/4' } })}>Sidebar</aside>
<main className={css({ w: { base: 'full', md: '3/4' } })}>Content</main>
</div>
);
}
// Patterns — pre-built layout utilities
function PatternExamples() {
return (
<>
{/* Flex layout */}
<div className={flex({ gap: '4', align: 'center', justify: 'between' })}>
<span>Left</span>
<span>Right</span>
</div>
{/* Center content */}
<div className={center({ h: '64' })}>
<p>Centered vertically and horizontally</p>
</div>
{/* Stack (vertical flex) */}
<div className={stack({ gap: '4', direction: 'column' })}>
<div>Item 1</div>
<div>Item 2</div>
</div>
{/* Grid */}
<div className={grid({ columns: { base: 1, md: 2, lg: 3 }, gap: '6' })}>
<div>Cell 1</div>
<div>Cell 2</div>
<div>Cell 3</div>
</div>
</>
);
}Fix 3: Recipes — Reusable Component Variants
// styled-system recipes (defined in panda.config.ts)
// panda.config.ts
import { defineConfig } from '@pandacss/dev';
export default defineConfig({
theme: {
extend: {
recipes: {
button: {
className: 'button',
description: 'Button component styles',
base: {
display: 'inline-flex',
alignItems: 'center',
justifyContent: 'center',
borderRadius: 'md',
fontWeight: 'semibold',
cursor: 'pointer',
transition: 'all 0.2s',
_disabled: {
opacity: '0.5',
cursor: 'not-allowed',
},
},
variants: {
variant: {
solid: {
bg: 'primary',
color: 'white',
_hover: { bg: 'blue.600' },
},
outline: {
border: '2px solid',
borderColor: 'primary',
color: 'primary',
_hover: { bg: 'blue.50' },
},
ghost: {
color: 'primary',
_hover: { bg: 'blue.50' },
},
},
size: {
sm: { px: '3', py: '1.5', fontSize: 'sm' },
md: { px: '4', py: '2', fontSize: 'md' },
lg: { px: '6', py: '3', fontSize: 'lg' },
},
},
defaultVariants: {
variant: 'solid',
size: 'md',
},
},
},
},
},
});// Usage after running npx panda codegen
import { button } from '../styled-system/recipes';
function Button({ variant, size, children, ...props }) {
return (
<button className={button({ variant, size })} {...props}>
{children}
</button>
);
}
// Or use cva() for inline recipe definitions
import { cva } from '../styled-system/css';
const badge = cva({
base: {
px: '2',
py: '0.5',
borderRadius: 'full',
fontSize: 'xs',
fontWeight: 'bold',
},
variants: {
status: {
success: { bg: 'green.100', color: 'green.800' },
warning: { bg: 'yellow.100', color: 'yellow.800' },
error: { bg: 'red.100', color: 'red.800' },
},
},
});
<span className={badge({ status: 'success' })}>Active</span>Fix 4: Conditional and Dynamic Styles
import { css, cx } from '../styled-system/css';
// Conditional styles — use conditions (pseudo-classes, states)
function InteractiveCard() {
return (
<div
className={css({
bg: 'white',
p: '4',
borderRadius: 'lg',
border: '1px solid',
borderColor: 'gray.200',
transition: 'all 0.2s',
// Hover state
_hover: {
borderColor: 'primary',
boxShadow: 'lg',
transform: 'translateY(-2px)',
},
// Focus-within (when child is focused)
_focusWithin: {
borderColor: 'primary',
ring: '2',
ringColor: 'blue.200',
},
// Dark mode
_dark: {
bg: 'gray.800',
borderColor: 'gray.700',
},
// First/last child
_first: { mt: '0' },
_last: { mb: '0' },
})}
>
Interactive card
</div>
);
}
// Dynamic styles based on props
function Alert({ type }: { type: 'info' | 'warning' | 'error' }) {
return (
<div
className={css({
p: '4',
borderRadius: 'md',
// Dynamic value based on prop
bg: type === 'info' ? 'blue.50' : type === 'warning' ? 'yellow.50' : 'red.50',
color: type === 'info' ? 'blue.800' : type === 'warning' ? 'yellow.800' : 'red.800',
borderLeft: '4px solid',
borderColor: type === 'info' ? 'blue.400' : type === 'warning' ? 'yellow.400' : 'red.400',
})}
>
Alert content
</div>
);
}
// Merging class names — use cx()
function MergedStyles({ className }: { className?: string }) {
return (
<div className={cx(
css({ bg: 'white', p: '4' }),
css({ borderRadius: 'lg' }),
className, // External classes merge correctly
)}>
Merged styles
</div>
);
}Fix 5: JSX Style Props (Type-Safe)
Panda generates typed JSX components for style props:
// panda.config.ts — enable JSX
export default defineConfig({
jsxFramework: 'react',
jsxStyleProps: 'all', // Enable style props on JSX components
});// After codegen — use styled components
import { styled } from '../styled-system/jsx';
import { flex, center } from '../styled-system/patterns';
// styled.div — type-safe style props
function StyledExample() {
return (
<styled.div bg="white" p="6" borderRadius="lg" shadow="md">
<styled.h1 fontSize="2xl" fontWeight="bold" mb="4">
Title
</styled.h1>
<styled.p color="gray.600" lineHeight="relaxed">
Paragraph with style props.
</styled.p>
</styled.div>
);
}
// Pattern JSX components
import { Flex, Center, Stack, Grid } from '../styled-system/jsx';
function LayoutExample() {
return (
<Stack gap="4">
<Flex justify="between" align="center">
<styled.span fontWeight="bold">Title</styled.span>
<styled.button bg="primary" color="white" px="4" py="2" borderRadius="md">
Action
</styled.button>
</Flex>
<Grid columns={{ base: 1, md: 3 }} gap="6">
<styled.div p="4" bg="gray.50" borderRadius="md">Cell 1</styled.div>
<styled.div p="4" bg="gray.50" borderRadius="md">Cell 2</styled.div>
<styled.div p="4" bg="gray.50" borderRadius="md">Cell 3</styled.div>
</Grid>
</Stack>
);
}Fix 6: Integration with Next.js and Vite
Next.js App Router:
// postcss.config.mjs
export default {
plugins: {
'@pandacss/dev/postcss': {},
},
};// app/layout.tsx
import '../styled-system/styles.css';
// Or if using a custom global CSS file:
// import './globals.css'; // which contains @layer reset, base, tokens, recipes, utilities;
export default function RootLayout({ children }) {
return <html><body>{children}</body></html>;
}Vite:
// postcss.config.mjs — same PostCSS config
export default {
plugins: {
'@pandacss/dev/postcss': {},
},
};// src/main.tsx
import '../styled-system/styles.css';
// Or: import './index.css';// package.json — auto-generate on dev/build
{
"scripts": {
"prepare": "panda codegen",
"dev": "panda codegen && vite",
"build": "panda codegen && vite build"
}
}Still Not Working?
Styles appear in dev but not in production — the CSS file might not be included in the production build. Verify the @layer import is in your CSS entry point and that it’s imported in your app. Also run npx panda codegen before building — some CI environments skip the prepare script.
TypeScript can’t find styled-system imports — add the path to your tsconfig.json: "paths": { "styled-system/*": ["./styled-system/*"] }. Also ensure styled-system/ is not in .gitignore (or add it and run codegen in CI).
Dynamic values don’t work — Panda is build-time, not runtime. css({ color: someVariable }) where someVariable is computed at runtime won’t work because Panda can’t scan dynamic values. Use conditional objects or recipes for variant-based styling. For truly dynamic values (e.g., user-selected color), use inline style attribute.
Hot reload doesn’t pick up new tokens — changes to panda.config.ts require running npx panda codegen to regenerate the styled-system/ directory. The PostCSS plugin watches for style changes in components but doesn’t watch config changes.
For related CSS issues, see Fix: Tailwind CSS Not Working and Fix: styled-components Not Working.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: UnoCSS Not Working — Classes Not Generating, Presets Missing, or Attributify Mode Broken
How to fix UnoCSS issues — Vite plugin setup, preset configuration, attributify mode, icons preset, shortcuts, custom rules, and integration with Next.js, Nuxt, and Astro.
Fix: CSS Container Query Not Working — @container and container-type Issues
How to fix CSS container queries not working — setting container-type correctly, understanding containment scope, fixing @container syntax, and handling browser support and specificity issues.
Fix: CodeMirror Not Working — Editor Not Rendering, Extensions Not Loading, or React State Out of Sync
How to fix CodeMirror 6 issues — basic setup, language and theme extensions, React integration, vim mode, collaborative editing, custom keybindings, and read-only mode.
Fix: GSAP Not Working — Animations Not Playing, ScrollTrigger Not Firing, or React Cleanup Issues
How to fix GSAP animation issues — timeline and tween basics, ScrollTrigger setup, React useGSAP hook, cleanup and context, SplitText, stagger animations, and Next.js integration.