---
title: Utilities
description:
  The utility API is a way to create your own CSS properties, map existing properties to a set of values or tokens.
---

The utility API enables you to create custom CSS properties and map existing properties to specific values or tokens.
It's like building your own type-safe version of Chakra UI, Tailwind (in JS), or Styled System.

Bamboo comes with a set of utilities out of the box. You can customize them, or add your own.

Here are the properties you need to define or customize a utility:

- `className` : The className the property maps to
- `shorthand`: The shorthand or alias version of the property
- `values`: The possible values the property can have. Could be a token category, or an enum of values, string, number,
  or boolean.
- `transform`: A function that converts the value to a valid css object
- `property`: The css property this utility maps to. Its accepted values are added to the utility's own type, unless
  [`strictValues`](/docs/references/config#strictvalues) is on.
- `group`: The semantic group the utility belongs to, used to organise generated documentation.
- `deprecated`: Whether the utility is deprecated. See [Deprecations](/docs/customization/deprecations).
- `customProperties`: Custom properties this utility composes its value from, registered with `@property`. Several
  utilities build one declaration out of many variables — `filter` out of nine, `translate` out of its axes — while a
  sibling utility sets each variable on its own. Declaring them here is what registers them, so the utility that reads a
  variable is the thing that guarantees it exists, and registration is merged across every configured utility. Omitting
  `initialValue` gives the property the guaranteed-invalid value, which is what a `var(--x, )` reference expects; a
  variable read without a fallback needs one declared instead, or the whole declaration is invalid.

## Creating a custom utility

Let's say we want to create new property `br` that applies a border radius to an element.

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

export default defineConfig({
  utilities: {
    extend: {
      br: {
        className: 'rounded', // css({ br: "sm" }) => rounded-sm
        values: 'radii', // connect values to the radii tokens
        transform(value) {
          return { borderRadius: value }
        },
      },
    },
  },
})
```

Then you can run the following command to generate the pattern JS code:

```bash
pnpm bamboo codegen
```

Now, we can use the `br` property in our components.

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

function App() {
  return <div className={css({ br: 'sm' })} />
}
```

### Using enum values

Let's say we want to create a new property `borderX` that applies a limited set of inline border to an element and
automatically applies the border color.

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

export default defineConfig({
  utilities: {
    extend: {
      borderX: {
        values: ['1px', '2px', '4px'],
        shorthand: 'bx', // `bx` or `borderX` can be used
        transform(value, { token }) {
          return {
            borderInlineWidth: value,
            borderColor: token('colors.red.200'), // read the css variable for red.200
          }
        },
      },
    },
  },
})
```

Now, we can use the `borderX` or `bx` property in our components.

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

function App() {
  return <div className={css({ borderX: '2px' })} />
}
```

### Using mapped values

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

export default defineConfig({
  utilities: {
    extend: {
      borderX: {
        values: { small: '2px', medium: '5px' },
        shorthand: 'bx',
        transform(value, { token }) {
          return {
            borderTopWidth: value,
            borderTopColor: token('colors.gray.400'),
          }
        },
      },
    },
  },
})
```

### Using boolean values

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

export default defineConfig({
  utilities: {
    extend: {
      truncate: {
        className: 'truncate',
        values: { type: 'boolean' },
        transform(value) {
          if (!value) return {}
          return {
            overflow: 'hidden',
            textOverflow: 'ellipsis',
            whiteSpace: 'nowrap',
          }
        },
      },
    },
  },
})
```
