---
title: Tokens
description: Design tokens are the platform-agnostic way to manage design decisions in your application or website.
---

Design tokens provide a platform-agnostic way to manage design decisions through key-value pairs that describe
fundamental visual styles.

> Design tokens in Bamboo are largely influenced by the [W3C Token Format](https://tr.designtokens.org/format/).

A design token consists of the following properties:

- `value`: The value of the token. This can be any valid CSS value.
- `description`: An optional description of what the token can be used for.

## Core Tokens

Tokens are defined in the `bamboo.config` file under the `theme` key

```js filename="bamboo.config.ts"
import { defineConfig } from '@bamboocss/dev'

export default defineConfig({
  theme: {
    // 👇🏻 Define your tokens here
    extend: {
      tokens: {
        colors: {
          primary: { value: '#0FEE0F' },
          secondary: { value: '#EE0F0F' },
        },
        fonts: {
          body: { value: 'system-ui, sans-serif' },
        },
      },
    },
  },
})
```

> ⚠️ Token values need to be nested in an object with a `value` key. This is to allow for additional properties like
> `description` and more in the future.

After defining tokens, you can use them in authoring components and styles.

```jsx
import { css } from '../styled-system/css'

function App() {
  return (
    <p
      className={css({
        color: 'primary',
        fontFamily: 'body',
      })}
    >
      Hello World
    </p>
  )
}
```

A value that looks like a token path but names no token is reported at build time. Bamboo warns with the value, the
property and the token category it searched, since the unresolved path is otherwise emitted verbatim — valid CSS that
the browser then drops, which surfaces much later as "this style never applied". Wrap the value in `[…]` if it really is
a literal.

You can also add an optional description to your tokens. This will be used in the autogenerate token documentation.

```js {8}
import { defineConfig } from '@bamboocss/dev'

export default defineConfig({
  theme: {
    tokens: {
      colors: {
        danger: {
          value: '#EE0F0F',
          description: 'Color for errors',
        },
      },
    },
  },
})
```

## Semantic Tokens

Semantic tokens are tokens that are designed to be used in a specific context. In most cases, the value of a semantic
token references to an existing token.

> To reference a value in a semantic token, use the `{}` syntax.

For example, assuming we've defined the following tokens:

- `red` and `green` are raw tokens that define the color red and green.
- `danger` and `success` are semantic tokens that reference the `red` and `green` tokens.

```js
import { defineConfig } from '@bamboocss/dev'

export default defineConfig({
  theme: {
    tokens: {
      colors: {
        red: { value: '#EE0F0F' },
        green: { value: '#0FEE0F' },
      },
    },
    semanticTokens: {
      colors: {
        danger: { value: 'token(colors.red)' },
        success: { value: 'token(colors.green)' },
      },
    },
  },
})
```

> ⚠️ Semantic Token values need to be nested in an object with a `value` key. This is to allow for additional properties
> like `description` and more in the future.

Semantic tokens can also be changed based on the [conditions](/docs/concepts/conditional-styles) like light and dark
modes.

For example, if you want a color to change automatically based on light or dark mode.

```js
import { defineConfig } from '@bamboocss/dev'

export default defineConfig({
  // ...
  theme: {
    semanticTokens: {
      colors: {
        danger: {
          value: { base: 'token(colors.red)', _dark: 'token(colors.darkred)' },
        },
        success: {
          value: { base: 'token(colors.green)', _dark: 'token(colors.darkgreen)' },
        },
      },
    },
  },
})
```

> NOTE 🚨: The conditions used in semantic tokens must be an at-rule or parent selector
> [condition](/docs/concepts/conditional-styles#reference).

A token whose only conditional value is `_osDark` is emitted differently: the `base` and `_osDark` pair folds into a
single `light-dark()` declaration instead of a `@media (prefers-color-scheme: dark)` block, and
`color-scheme: light dark` is declared on `cssVarRoot`. Because `light-dark()` reads the inherited `color-scheme`
property, an explicit toggle is `color-scheme: dark` on a subtree rather than a second copy of every token. A token that
also defines `_osLight` keeps the media-query form.

## Token Nesting

Tokens can be nested to create a hierarchy of tokens. This is useful when you want to group tokens together.

> Tip: You can use the `DEFAULT` key to define the default value of a nested token.

```js
import { defineConfig } from '@bamboocss/dev'

export default defineConfig({
  // ...
  theme: {
    semanticTokens: {
      colors: {
        bg: {
          DEFAULT: { value: 'token(colors.gray.100)' },
          muted: { value: 'token(colors.gray.100)' },
        },
      },
    },
  },
})
```

This allows the use of the `bg` token in the following ways:

```jsx
import { css } from '../styled-system/css'

function App() {
  return (
    <div
      className={css({
        // 👇🏻 This will use the `DEFAULT` value
        bg: 'bg',
        // 👇🏻 This will use the `muted` value
        color: 'bg.muted',
      })}
    >
      Hello World
    </div>
  )
}
```

## Token Types

Most token types take a single scalar value:

```jsx
const theme = {
  tokens: {
    sizes: {
      sm: { value: '12px' },
    },
  },
}
```

| Category         | Value                | Typical use                                                           |
| ---------------- | -------------------- | --------------------------------------------------------------------- |
| `sizes`          | `string`             | `width`, `height`, `min-width`/`max-width`, `min-height`/`max-height` |
| `spacing`        | `string \| number`   | `margin`, `padding`, `gap`, `top`/`right`/`bottom`/`left`             |
| `fonts`          | `string \| string[]` | `font-family`                                                         |
| `fontSizes`      | `string`             | `font-size`                                                           |
| `fontWeights`    | `string \| number`   | `font-weight`                                                         |
| `letterSpacings` | `string`             | `letter-spacing`                                                      |
| `lineHeights`    | `string \| number`   | `line-height`                                                         |
| `radii`          | `string`             | `border-radius`                                                       |
| `borderWidths`   | `string`             | `border-width`, `outline-width`                                       |
| `blurs`          | `string`             | the `blur` and `backdropBlur` utilities                               |
| `opacity`        | `string \| number`   | `opacity`                                                             |
| `zIndex`         | `string \| number`   | `z-index`                                                             |
| `durations`      | `string`             | `transition-duration`, `animation-duration`                           |
| `animations`     | `string`             | `animation`                                                           |
| `aspectRatios`   | `string`             | `aspect-ratio`                                                        |
| `cursor`         | `string`             | `cursor`                                                              |

The remaining six types accept composite values.

### Colors

Colors have meaning and support the purpose of the content, communicating things like hierarchy of information, and
states. It is mostly defined as a string value or reference to other tokens.

```jsx
const theme = {
  tokens: {
    colors: {
      red: { 100: { value: '#fff1f0' } },
    },
  },
}
```

### Gradients

Gradient tokens represent a smooth transition between two or more colors. Its value can be defined as a string or a
composite value.

```ts
type Gradient =
  | string
  | {
      type: 'linear' | 'radial'
      placement: string | number
      stops:
        | Array<{
            color: string
            position: number
          }>
        | Array<string>
    }
```

```jsx
const theme = {
  tokens: {
    gradients: {
      // string value
      simple: { value: 'linear-gradient(to right, red, blue)' },
      // composite value
      primary: {
        value: {
          type: 'linear',
          placement: 'to right',
          stops: ['red', 'blue'],
        },
      },
    },
  },
}
```

### Borders

A border is a line surrounding a UI element. You can define them as string values or as a composite value

```jsx
const theme = {
  tokens: {
    borders: {
      // string value
      subtle: { value: '1px solid red' },
      // string value with reference to color token
      danger: { value: '1px solid token(colors.red.400)' },
      // composite value
      accent: { value: { width: '1px', color: 'red', style: 'solid' } },
    },
  },
}
```

> Border tokens are typically used in `border`, `border-top`, `border-right`, `border-bottom`, `border-left`, `outline`
> properties.

### Shadows

Shadow tokens represent the shadow of an element. Its value is defined as single or multiple values containing a string
or a composite value.

```ts
type CompositeShadow = {
  offsetX: number
  offsetY: number
  blur: number
  spread: number
  color: string
  inset?: boolean
}

type Shadow = string | CompositeShadow | string[] | CompositeShadow[]
```

```jsx
const theme = {
  tokens: {
    shadows: {
      // string value
      subtle: { value: '0 1px 2px 0 rgba(0, 0, 0, 0.05)' },
      // composite value
      accent: {
        value: {
          offsetX: 0,
          offsetY: 4,
          blur: 4,
          spread: 0,
          color: 'rgba(0, 0, 0, 0.1)',
        },
      },
      // multiple string values
      realistic: {
        value: ['0 1px 2px 0 rgba(0, 0, 0, 0.05)', '0 1px 4px 0 rgba(0, 0, 0, 0.1)'],
      },
    },
  },
}
```

> Shadow tokens are typically used in `box-shadow` property.

### Easings

Easing tokens represent the easing function of an animation or transition. Its value is defined as a string or an array
of values representing the cubic bezier.

```jsx
const theme = {
  tokens: {
    easings: {
      // string value
      easeIn: { value: 'cubic-bezier(0.4, 0, 0.2, 1)' },
      // array value
      easeOut: { value: [0.4, 0, 0.2, 1] },
    },
  },
}
```

> Ease tokens are typically used in `transition-timing-function` property.

### Assets

Asset tokens represent a url or svg string. Its value is defined as a string or a composite value.

```ts
type CompositeAsset = { type: 'url' | 'svg'; value: string }
type Asset = string | CompositeAsset
```

```js
const theme = {
  tokens: {
    assets: {
      logo: {
        value: { type: 'url', value: '/static/logo.png' },
      },
      checkmark: {
        value: { type: 'svg', value: '<svg>...</svg>' },
      },
    },
  },
}
```

> Asset tokens are typically used in `background-image` property.

## Token Helpers

To help defining tokens in a type-safe way, you can use the tokens
[Config Functions](/docs/customization/config-functions#token-creators).

## CSS variables

The generated CSS variables will be scoped using the `cssVarRoot` selector defined in the config.

```js
import { defineConfig } from '@bamboocss/dev'

export default defineConfig({
  cssVarRoot: ':where(:root, :host)',
  // ...
})
```

This will generate a CSS file similar to the following:

```css
:where(:root, :host) {
  --colors-primary: #0fee0f;
  --colors-secondary: #ee0f0f;
  /* ... */
}
```

Only the tokens something asks for are declared there. [`prune.tokens`](/docs/references/config#prunetokens) is on by
default, and the gap is usually wide — the `vite-ts` example in this repository ships 480 tokens in `tokens/index.mjs`
and declares 45 of them in `styles.css`. Set it to `false` to declare every token, or name the ones to keep with
[`prune.keepTokens`](/docs/references/config#prunekeeptokens).

You can also define type-safe CSS variables using [`global.vars`](/docs/concepts/writing-styles#property-conflicts).
