---
title: Why Bamboo
description: From the endless list of CSS-in-JS libraries, why should you choose Bamboo?
---

## Styles that resolve before they ship

Bamboo is a build-time CSS-in-JS engine. You write style objects; the Vite compiler resolves them into globally shared
atoms and replaces every style-producing call with a literal or finite lookup. Open runtime styling is rejected. Nothing
generates styles in the browser or injects them into the `<head>`.

Three things follow from that, and they are what Bamboo is for.

### The call disappears

Every class name comes from a function call the compiler can see. There is no JSX factory, no template literal syntax
and no style props, so the compiler can [remove the call entirely](/docs/guides/source-transformation):

```tsx
// you write
export const title = css({ fontSize: 'lg', fontWeight: 'bold' })

// the bundle gets
export const title = 'fs_lg fw_bold'
```

A style that varies uses a declared, finite recipe axis. Bamboo precompiles every reachable StyleSet and leaves only a
small decision table behind. An open value such as `css({ color: tone })` is rejected because no finite stylesheet can
back every value it might produce.

The payoff is larger than the CPU saved per call. Recipe configs and the style engine disappear from the production
graph, while identical declarations from every recipe and `css()` call share one atom and one CSS rule.

### A green build means a complete stylesheet

Static extraction's characteristic failure is silence. A file the parser threw on, a call to a pattern a preset dropped,
a `background: 'accent.default'` naming a token that does not exist — each contributes no rule, and nothing downstream
objects, because a stylesheet missing rules is still a valid stylesheet. The class the component asks for simply has
nothing behind it, and it surfaces much later as "this colour never applied", a long way from the edit that caused it.

Bamboo treats that as a build failure rather than a fact of life:

```
ERR_BAMBOO_DEAD_IMPORT: 12 call(s) name a binding that does not exist:

`stack` is not a pattern — `../styled-system/patterns` does not export it.
  12 file(s): src/modal.tsx, src/drawer.tsx, src/sheet.tsx, … and 9 more
```

[Build diagnostics](/docs/concepts/build-diagnostics) lists what is checked, what each check costs, and which of them
you can grade.

### You ship what you use

The token layer declares every token in your theme while an app uses a fraction of them, so
[pruning](/docs/references/config#prune) what nothing can reach is usually the largest single saving in render-blocking
CSS — 36% to 78% of `styles.css` on the example apps in this repository. The same applies to `@keyframes` a preset
declares and your app never animates, and to the parts of the reset that style elements your source never renders.

## Built at scale

Bamboo is the styling engine behind [Contra](https://contra.com), whose UI has more than 20,000 `css()` call sites. At
that scale everything a styling library spends per call site – bytes emitted, work at runtime, time in the build – is
multiplied by five figures, so optimizations too small to notice elsewhere are plainly measurable. Bamboo exists to
chase them further than a general-purpose library reasonably would.

It began as a fork of [Panda CSS](https://panda-css.com/) and keeps its authoring primitives: `css`, `cva`, `sva`, `cx`,
patterns and recipes. The API is smaller and several behaviours differ — analyzable `cx` calls compose StyleSets,
recipes share global atoms, and slot selections compile directly to per-slot atom strings — so if you are coming from
Panda, read [what changed](/docs/overview/faq#how-is-bamboo-css-different-from-panda-css) before you
[migrate](/docs/migration/panda).

## When to use Bamboo?

Bamboo suits an app whose stylesheet is starting to track the size of its design system rather than the size of its own
UI, and a team that would rather have an extraction failure stop the build than find it in a diff of the output. It asks
for something in return: styles are written one way, as objects passed to a call, and dynamic values have to be
reachable statically or say so.

### Styling engine

Bamboo runs anywhere PostCSS does, and there is a [CLI](/docs/installation/cli) for anywhere it does not.

```jsx
import { css } from '../styled-system/css'
import { center, flex } from '../styled-system/patterns'

function App() {
  return (
    <div
      className={flex({
        direction: 'row',
        gap: '8px',
        p: '4',
        rounded: 'md',
        shadow: 'lg',
        bg: 'white',
      })}
    >
      <div className={center({ size: '5rem', borderRadius: 'full', overflow: 'hidden' })}>
        <img src="https://via.placeholder.com/150" alt="avatar" />
      </div>
      <div className={css({ mt: '4', fontSize: 'xl', fontWeight: 'semibold' })}>John Doe</div>
      <div className={css({ mt: '2', fontSize: 'sm', color: 'gray.600' })}>john@doe.com</div>
    </div>
  )
}
```

### Token generator

Bamboo has first-class support for design tokens. It provides a way to express raw and semantic tokens for your project.
The generator can be used to create a set of CSS variables for your design tokens.

```ts filename="bamboo.config.ts"
export default defineConfig({
  emitTokensOnly: true,
  theme: {
    tokens: {
      colors: {
        gray50: { value: '#F9FAFB' },
        gray100: { value: '#F3F4F6' },
      },
    },
    semanticTokens: {
      colors: {
        primary: { value: 'token(colors.gray50)' },
        success: {
          value: { _light: 'token(colors.green500)', _dark: 'token(colors.green200)' },
        },
      },
    },
  },
})
```

Running the `bamboo codegen` will generate

```css filename="styled-system/tokens/index.css"
:where(:root, :host) {
  --colors-gray50: #f9fafb;
  --colors-gray100: #f3f4f6;
  --colors-primary: var(--colors-gray50);
}

.light {
  --colors-success: var(--colors-green500);
}

.dark {
  --colors-success: var(--colors-green200);
}
```

Then you have a set of css variables that you can use in your project.

```css
@import '../styled-system/tokens/index.css';

.card {
  background-color: var(--colors-gray50);
}
```

## When not to use Bamboo?

Bamboo isn't the right fit for your project if:

- You're building with HTML and CSS.
- You're using a template-based framework like PHP.
- You're looking for an absolute zero JS solution.

In these scenarios, we recommend that you use vanilla CSS (which is getting awesome by the day), or other utility based
CSS libraries.
