---
title: Migrating from Styled Components
description: Migrate your project from Styled Components to Bamboo.
---

This guide outlines the steps needed to migrate your project from Styled Components to Bamboo and highlights key design
differences between the two libraries.

> **Disclaimer:** This isn't about comparing which one is best. Bamboo and Styled Components are two different CSS-in-JS
> solutions with design decisions.

Here are some similarities between the two libraries.

- Both libraries provide a way to define design tokens (variables) and use them in your styles.
- Both libraries require the use of `&` for nested selectors.

Below are some differences between the two libraries.

## Installation and Syntax

In styled-components, you can use both tagged template literals and object syntax to style components.

Bamboo styles are always objects. Every tagged template in your project becomes an object literal — the sections below
show the mapping for each case.

To initialize a project, run the following command.

```bash
bamboo init -p
```

Then you need to add the cascade layers to the global styles of your project.

```css
@layer reset, base, tokens, recipes, utilities;
```

## Tagged Template and Object Syntax

In styled-components, you style a component with a tagged template literal:

```jsx
import styled from 'styled-components'

const Button = styled.button`
  background-color: #fff;
  border: 1px solid #000;
  color: #000;
  padding: 0.5rem 1rem;
`
```

…or with an object:

```jsx
const Button = styled.button({
  backgroundColor: '#fff',
  border: '1px solid #000',
  color: '#000',
  padding: '0.5rem 1rem',
})
```

Bamboo has neither a tagged template API nor a `styled` factory, and does not generate a `styled-system/jsx` directory.
Both forms become the same `css()` call with camelCased properties, and variants and compound variants go to
[`cva`](/docs/concepts/recipes).

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

const button = css({
  backgroundColor: '#fff',
  border: '1px solid #000',
  color: '#000',
  padding: '0.5rem 1rem',
})
```

## Prop Interpolation

In styled-components, you can interpolate the component's props to conditionally set styles.

```jsx
const Button = styled.button`
  ${(props) =>
    props.color === 'violet' &&
    `
    background-color: 'blueviolet'
  `}

  ${(props) =>
    props.color === 'gray' &&
    `
    background-color: 'gainsboro'
  `}
`
```

In Bamboo, we model interpolations using the variants API. This allows define style groups or recipes that can be
applied to components.

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

const button = cva({
  variants: {
    color: {
      violet: { backgroundColor: 'blueviolet' },
      gray: { backgroundColor: 'gainsboro' },
    },
  },
})

// Usage
<button className={button({ color: 'violet' })}>Button</button>
```

## Tokens and Themes

### Defining Tokens

In styled-components, you can define tokens in a theme object that is passed to the `ThemeProvider`. This requires the
use of React's context API to access the theme object in your styles

```tsx
import { ThemeProvider } from 'styled-components'

const theme = {
  colors: {
    primary: 'blue',
    secondary: 'red',
  },
}

const App = () => (
  <ThemeProvider theme={theme}>
    <Button>Button</Button>
  </ThemeProvider>
)
```

In Bamboo, you define tokens in the `theme` key of the `bamboo.config.ts` file. This allows you to access the tokens in
your styles without the need for React's context API.

```tsx
// bamboo.config.ts
import { defineConfig } from '@bamboocss/dev'

export default defineConfig({
  theme: {
    extend: {
      tokens: {
        colors: {
          primary: { value: 'blue' },
          secondary: { value: 'red' },
        },
      },
    },
  },
})
```

### Using Tokens

In styled-components, you can use tokens in your styles using a function approach that provides the `theme` prop, and
requires ambient type declarations to get type safety.

```tsx
import styled from 'styled-components'

// link.tsx
const StyledLink = styled.a(({ theme }) => ({
  color: theme.colors.primary,
  display: 'block',
  textDecoration: 'none',
}))

// theme.d.ts
declare module 'styled-components' {
  export interface DefaultTheme {
    colors: {
      primary: string
      secondary: string
    }
  }
}
```

In Bamboo, the tokens defined above are automatically available in your styles and connected to each css property,
removing the need for an interpolation function and for the ambient declarations.

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

const styledLink = css({
  color: 'primary',
  display: 'block',
  textDecoration: 'none',
})
```

## Responsive Styles

In styled-components, you write the media query yourself — inline in a tagged template, or through a helper like
`styled-media-query` in the object form.

```tsx
import styled from 'styled-components'
import media from 'styled-media-query'

const Button = styled.button({
  backgroundColor: '#fff',
  border: '1px solid #000',
  color: '#000',
  padding: '0.5rem 1rem',

  [media.greaterThan('medium')]: {
    padding: '1rem 2rem',
  },
})
```

In Bamboo, you name the breakpoint on the property value itself and the media query is generated for you.

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

const button = css({
  backgroundColor: '#fff',
  border: '1px solid #000',
  color: '#000',
  padding: { base: '0.5rem 1rem', md: '1rem 2rem' },
})
```

## Global Styles

In styled-components, you can use the `createGlobalStyle` function to define global styles.

```tsx
import { createGlobalStyle } from 'styled-components'

const GlobalStyle = createGlobalStyle`
  body {
    margin: 0;
    padding: 0;
  }
`
```

In Bamboo, you can use the `global.css` key of the `bamboo.config.ts` file to define global styles. This will
automatically add styles to the project via PostCSS.

```tsx
// bamboo.config.ts
import { defineConfig } from '@bamboocss/dev'

export default defineConfig({
  global: {
    css: {
      body: {
        margin: 0,
        padding: 0,
      },
    },
  },
})
```

## Targeting Components

In styled-components, you can target existing styled components within the styled function

```tsx
import styled from 'styled-components'

const Link = styled.a`
  background: papayawhip;
  color: #bf4f74;
`

const Icon = styled.svg`
  width: 48px;
  height: 48px;

  ${Link}:hover & {
    fill: rebeccapurple;
  }
`
```

In Bamboo, you need to use the native selector directly. This is largely due to the static nature of Bamboo

```tsx
import { css, cx } from '../styled-system/css'

const link = css({
  background: 'papayawhip',
  color: '#bf4f74',
})

const icon = css({
  width: '48px',
  height: '48px',
  '.Link:hover &': {
    fill: 'rebeccapurple',
  },
})

const App = () => (
  <a className={cx(link, 'Link')}>
    <svg className={icon} />
  </a>
)
```

## Animations

In styled components, you can define keyframes using the `keyframes` method.

```ts
import styled, { keyframes } from 'styled-components'

const rotate = keyframes`
  from {
    transform: rotate(0deg);
  }

  to {
    transform: rotate(360deg);
  }
`

// usage
const Button = styled.button`
  &:hover {
    animation: ${rotate} 200ms;
  }
`
```

In Bamboo, you define keyframes in the `theme.keyframes` key of the `bamboo.config` function.

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

export default defineConfig({
  theme: {
    extend: {
      keyframes: {
        rotate: {
          from: {
            transform: 'rotate(0deg)',
          },
          to: {
            transform: 'rotate(360deg)',
          },
        },
      },
    },
  },
})

// usage
import { css } from '../styled-system/css'

const button = css({
  _hover: {
    animation: 'rotate 200ms',
  },
})
```

## Server-Side Rendering

styled-components needs per-framework SSR wiring — a `ServerStyleSheet`, `collectStyles`, and the collected tags placed
into the document.

Bamboo needs none of it. Styles are extracted and emitted at build time by PostCSS, so there is nothing to collect at
request time.

## Conclusion

Before choosing your preferred CSS-in-JS library, be sure to consider your engineering and design goals. Both Styled
components and Bamboo are capable of achieving many of the same styling goals, but they have different approaches.
