Static CSS Generator
Bamboo can be used to generate a static set of utility classes for your project.
Bamboo can be used to generate a static set of utility classes for your project.
This is useful if you want to use Bamboo in an HTML project or you want absolute zero runtime.
Usage
To generate a static set of CSS classes, add them to your bamboo.config.js file:
export default {
staticCss: {
// the css properties you want to generate
css: [],
// the recipes you want to generate
recipes: {},
// the patterns you want to generate
patterns: {},
// the theme variants you want to generate
themes: [],
},
}
The staticCss property supports four properties:
css- an array of CSS rules you want to generate, each with theirconditionsrecipes- the component recipes you want to generate, or'*'for every recipe and every variantpatterns- the patterns you want to generate, keyed by pattern namethemes- the theme variants to include in the CSS output
Generating CSS Properties
The css property is an array of CSS properties you want to generate with their conditions.
You can specify the following options:
properties: an object mapping each CSS property to the array of values to generate for it.'*'stands for every value the tokens define; any other entry is generated as written.conditions: the CSS conditions or selectors you want to generate in addition to the default values. Values can belight, dark, etc.responsive: whether or not to generate responsive classes
export default {
staticCss: {
css: [
{
properties: {
margin: ['*'],
padding: ['*', '50px', '80px'],
},
responsive: true,
},
{
properties: {
color: ['*'],
backgroundColor: ['green.200', 'red.400'],
},
conditions: ['light', 'dark'],
},
],
},
}
Generating Recipes
The recipes property is an object of component recipes you want to generate with their conditions.
export default {
staticCss: {
recipes: {
button: [
{
size: ['sm', 'md'],
responsive: true,
},
{ variant: ['*'] },
],
// shorthand for all variants
tooltip: ['*'],
},
},
}
You can also directly specify a recipe's staticCss rules from inside a recipe config, e.g.:
import { defineRecipe } from '@bamboocss/dev'
const card = defineRecipe({
className: 'card',
base: { color: 'white' },
variants: {
size: {
small: { fontSize: '14px' },
large: { fontSize: '18px' },
},
},
staticCss: [{ size: ['*'] }],
})
would be the equivalent of defining it inside the main config:
import { defineConfig } from '@bamboocss/dev'
export default defineConfig({
// ...
staticCss: {
recipes: {
card: [{ size: ['*'] }],
},
},
})
Or you could even generate the CSS for every config recipe / slotRecipes (and each of their variants):
bamboo.config.ts
import { defineConfig } from '@bamboocss/dev'
export default defineConfig({
// ...
staticCss: {
recipes: '*',
},
})This is mostly useful for testing purposes with Storybook.
Generating Patterns
The patterns property is an object of patterns, each taking the same rules as css. The properties are the pattern's
own props rather than CSS properties, and '*' covers every prop the pattern declares.
export default {
staticCss: {
patterns: {
flex: [{ properties: { gap: ['*'], align: ['center'] } }],
// shorthand for every prop of the pattern
center: ['*'],
},
},
}
Generating Themes
themes lists the theme variants to emit. No theme variant reaches
the CSS output unless it is named here.
export default {
staticCss: {
themes: ['primary', 'secondary'],
},
}
Performance Considerations
Pre-generating large numbers of styles costs build time and CSS size. Only generate the styles you actually need.
Best Practices
❌ Avoid: Generating every possible combination
export default {
staticCss: {
css: [
{
conditions: ['hover', 'focus', 'active', 'disabled'],
properties: {
// This expands to ALL tokens - very expensive!
color: ['*'],
backgroundColor: ['*'],
borderColor: ['*'],
width: ['*'],
height: ['*'],
// ... 20+ more properties with wildcards
},
},
],
},
}
✅ Better: Only generate what you need
export default {
staticCss: {
css: [
{
conditions: ['_hover', '_focus'],
properties: {
// Only the colors you actually use
color: ['red.500', 'blue.500', 'gray.600'],
backgroundColor: ['white', 'gray.50', 'blue.50'],
borderColor: ['gray.200', 'blue.500'],
},
},
],
},
}
When to Use Wildcards
Wildcards (['*']) are appropriate when:
- Small token sets: Properties with < 20 values (e.g.,
fontWeight: ['*']) - Critical utilities: Styles you genuinely need in all variants
- Testing scenarios: Storybook or visual regression testing
Use Responsive Selectively
The responsive property multiplies the number of generated classes by your breakpoints. Only enable it for properties
that genuinely need responsive behavior.
Properties that commonly need responsive: true:
- Layout:
display,flexDirection,gridTemplateColumns - Sizing:
width,height,maxWidth - Spacing:
padding,margin,gap - Positioning:
position,top,left
Properties that rarely need responsive: true:
- Colors:
color,backgroundColor,borderColor - Typography:
fontWeight,textDecoration,fontFamily - Effects:
boxShadow,opacity,cursor
Removing unused CSS
Reach for prune first — it drops token declarations, @property registrations and
keyframes the finished stylesheet cannot reach, and preflight.prune drops
the parts of the reset that style elements you never render. These read the build's own output rather than guessing from
your markup, so they are safe in ways a selector scan is not.
Note that staticCss works against them: every rule it emits is a rule the pruning has to keep, along with whatever it
references. If you added a staticCss entry to stop a token category being pruned, use
prune.keepTokens instead — it keeps the declarations without emitting a
rule per value to hold them up.
For an even smaller css output size, you can utilize PurgeCSS (opens in a new tab) to treeshake and remove unused CSS. This tool will analyze your template and match selectors against your CSS.