installation
react router

Using React Router

Easily use Bamboo with React Router with our dedicated integration.

Start a new project

Create project

To get started, we will need to create a new React Router project using the official Create React Router (opens in a new tab) CLI. In this guide, we will use TypeScript.

If you don't enter any parameter, the CLI will guide you through the process of creating a new React Router app.

pnpm dlx create-react-router@latest

You will be asked a few questions, answer these as follows:

? Where should we create your new project? test-app
? Install dependencies? No
💡

Note: You should decline the dependency installation step as we will install dependencies together with Bamboo CSS.

Install Bamboo

Install bamboo and create your bamboo.config.ts file. React Router builds with Vite, so this is the Vite integration — @bamboocss/vite is the compiler, and it is what keeps the style engine out of your client bundle.

pnpm install -D @bamboocss/dev @bamboocss/vite
pnpm bamboo init

Update package.json scripts

Add "prepare": "bamboo codegen" to scripts. It runs codegen after every dependency install, so the output directory can stay in .gitignore.

The build itself no longer needs it. The Vite plugin generates styled-system/ in buildStart, before anything resolves an import of it, so a fresh clone builds without a separate codegen step. Keep the script regardless: tsc and your editor read the generated types without ever running the plugin.

Configure the content

Make sure that all of the paths of your React Router components are included in the include section of the bamboo.config.ts file.

This matters more under the compiler than it used to: a module it compiles that the extractor never read would have class names with no rules behind them, so the build fails instead. ./app/**/* covers app/root.tsx as well as everything under it.

bamboo.config.ts

import { defineConfig } from '@bamboocss/dev'
 
export default defineConfig({
  // Whether to use css reset
  preflight: true,
 
  // Where to look for your css declarations
  include: ['./app/**/*.{js,jsx,ts,tsx}'],
 
  // Files to exclude
  exclude: [],
 
  // The output directory for your css system
  outdir: 'styled-system',
})

Replace Tailwind CSS with Bamboo CSS

Remove the Tailwind CSS plugin from vite.config.ts and add Bamboo's. The template's app/app.css, its import in app/root.tsx, and any links entry pointing at it can go too — the next step imports Bamboo's stylesheet instead.

vite.config.ts

import { reactRouter } from '@react-router/dev/vite'
import bamboocss from '@bamboocss/vite'
import { defineConfig } from 'vite'
import tsconfigPaths from 'vite-tsconfig-paths'
 
export default defineConfig({
  plugins: [bamboocss(), reactRouter(), tsconfigPaths()],
})

There is no postcss.config.cjs entry for Bamboo and no file carrying the @layer statement: the plugin serves the stylesheet as a virtual module that emits its own layer order. You still need PostCSS for anything else you run through it, autoprefixer included.

Import the virtual stylesheet

Import it once, from app/root.tsx:

app/root.tsx

import { isRouteErrorResponse, Links, Meta, Outlet, Scripts, ScrollRestoration } from 'react-router'
 
import type { Route } from './+types/root'
import 'virtual:bamboo.css'
 
export function Layout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        {children}
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  )
}

It has to be a JavaScript import. @import from a stylesheet does not reach it, because Vite resolves CSS @import before plugin resolution and the id names a virtual module this plugin resolves.

Create app/vite-env.d.ts, or add the second line to it if your template already has one, so TypeScript accepts that import:

app/vite-env.d.ts

/// <reference types="vite/client" />
/// <reference types="@bamboocss/vite/client" />

Start your build process

Start the dev server with pnpm dev.

Start using Bamboo

app/routes/home.tsx

import type { Route } from './+types/home'
import { css } from '../../styled-system/css'
 
export function meta({}: Route.MetaArgs) {
  return [{ title: 'New React Router App' }, { name: 'description', content: 'Welcome to React Router!' }]
}
 
export default function Home() {
  return (
    <div>
      <h1 className={css({ fontSize: '2xl', fontWeight: 'bold' })}>Welcome to the home page</h1>
    </div>
  )
}

Troubleshooting

If your IDE does not autocomplete styled-system imports, add that directory to include in tsconfig.json, alongside app. See the CLI guide.