Getting Started

A step-by-step guide to get started with Cerberus.

What is Cerberus?

Cerberus is a UI-like flexible design system that is built on top of Panda CSS. It uses two foundational packages:

  1. Panda Preset
  2. React

Panda Preset

The Cerberus Panda Preset is a set of tokens, recipes, conditions, utilities, patterns, and more that are built on top of Panda CSS. It provides a consistent look and feel for your application and makes it easy to get started with Panda CSS.

Cerberus React

The Cerberus React is a set of pre-configured components that are built on top of the Panda CSS preset. It provides a set of components that can be categorized into 3 groups:

  1. Abstractions - Abstracted component APIs of the primitives
  2. Primitives - Low level component APIs for fine-grained control
  3. Parts - Object oriented components that are used to build the abstractions

Setup Guide

Step 1 - Setup Panda CSS

Before you can use the Cerberus, you need to have Panda CSS installed and setup in your project.

Head over to the Panda CSS installation guide to get started.

Step 2 - Setup the Cerberus Preset

In order to use the Cerberus React, you need to install the Cerberus preset package.

Terminal
npx jsr add @cerberus/panda-preset

Next, update your PandaCSS config to utilize the Cerberus helpers:

panda.config.ts
import {
createCerberusConfig,
createCerberusPreset,
} from '@cerberus/panda-preset'
export default createCerberusConfig({
presets: [createCerberusPreset()],
include: ['./app/**/*.{ts,tsx}'],
exclude: [],
})

The createCerberusConfig function adds the recommended Cerberus settings and any additional settings you pass into it.

The createCerberusPreset function does the same except on the preset level.

Step 3 - Update your root layout to trigger Cerberus

Because Cerberus provides multiple themes and modes out of the box, you need to initialize your root layout to trigger the default options you want to use.

To connect the Cerberus theme, add the required data attributes to your root html tag.

app/layout.tsx
function RootLayout({ children }) {
return (
<html lang="en" data-panda-theme="cerberus" data-color-mode="light">
<body>{children}</body>
</html>
)
}

This is a good point to run your panda codegen command to generate the Cerberus related additions.

Path Aliases

Cerberus React assumes you have your baseUrl setup to the root location in your tsconfig.json file. If you do not, or use a different location, you should include a path alias for the styled-system/* location.

tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["./*"]
}
}
}

Step 4 - Setup Cerberus React

Cerberus React is icon agnostic which means you should install the Icon library of choice before installing the Cerberus React package.

Terminal
npm install @cerberus/react@npm:@cerberus-design/react

Step 5 - Registering Your Icons

Because Cerberus React is icon agnostic, you need to register the library you prefer. This will map certain icons to the Cerberus components that depend on them.

If you do not have an icon preference, we recommend using the Carbon Icons library.

Terminal
npm install @carbon/icons-react

Create your Cerberus Config

In Next, you will need to create a new file to wrap your application with the CerberusProvider where you will keep your global settings.

We will name this abstraction CerberusConfig since it will own the Cerberus configuration.

context/cerberus-config.tsx
'use client'
import {
CerberusProvider,
defineIcons,
makeSystemConfig,
} from '@cerberus/react'
import {
Calendar,
Checkmark,
CheckmarkOutline,
ChevronDown,
ChevronLeft,
ChevronRight,
Close,
CloudUpload,
Information,
Restart,
TrashCan,
UserFilled,
Warning,
WarningAlt,
WarningFilled,
} from '@carbon/icons-react'
import type { PropsWithChildren } from 'react'
/**
* This module provides a Cerberus configuration component which must to be used
* in a client abstraction because of React 19 rules around data passing into
* props.
*/
const icons = defineIcons({
accordionIndicator: ChevronDown,
avatar: UserFilled,
calendar: Calendar,
calendarPrev: ChevronLeft,
calendarNext: ChevronRight,
close: Close,
confirmModal: Information,
delete: TrashCan,
promptModal: Information,
waitingFileUploader: CloudUpload,
infoNotification: Information,
successNotification: CheckmarkOutline,
warningNotification: WarningAlt,
dangerNotification: WarningFilled,
invalid: WarningFilled,
invalidAlt: Warning,
redo: Restart,
selectArrow: ChevronDown,
selectChecked: Checkmark,
toggleChecked: Checkmark,
})
const config = makeSystemConfig({
icons,
})
export default function CerberusConfig(props: PropsWithChildren<{}>) {
return <CerberusProvider config={config}>{props.children}</CerberusProvider>
}

Then wrap your application with the CerberusConfig component:

app/layout.tsx
import { Poppins, Recursive } from 'next/font/google'
import { type PropsWithChildren } from 'react'
import { css, cx } from 'styled-system/css'
import CerberusConfig from '@/context/cerberus-config'
import './globals.css'
const poppins = Poppins({
display: 'swap',
subsets: ['latin'],
weight: ['400', '600', '700'],
variable: '--font-poppins',
})
const recursive = Recursive({
display: 'swap',
subsets: ['latin'],
weight: ['400'],
variable: '--font-recursive',
})
interface RootProps {}
export default function RootLayout(props: PropsWithChildren<RootProps>) {
return (
<html
className={cx(poppins.variable, recursive.variable)}
data-panda-theme="cerberus"
data-color-mode="light"
lang="en"
>
<body>
<CerberusConfig>
{props.children}
</CerberusConfig>
</body>
</html>
)
}

Tip: Add a Cerberus script

To help make maintaining a breeze, add this new script to your package.json to use when you need to upgrade Cerberus:

package.json
"scripts": {
"up:cerberus": "pnpm up @cerberus/react@latest && pnpm dlx jsr add @cerberus/panda-preset && pnpm up @pandacss/dev@latest"
}

Now you can update Cerberus and PandaCSS with a single command:

Terminal
npm run up:cerberus

FAQ

Why does the package path for react look weird?

The Cerberus packages are published under the @cerberus-design organization in NPM (due to the name cerberus being taken). However, in JSR, we use the @cerberus organization. We eventually plan on fully migrating to JSR when there is better support for the features we need.

The version paths are simply creating an alias to the @cerberus-design organization so that you can have consistent package naming across your project.

Everything should use the @cerberus organization in your code.

Why do I need to have a specific baseUrl in our tsconfig.json?

In order for our React components to know where to find the styled-system APIs, it needs to know where to look. By setting the baseUrl to the root of your project, we can use the styled-system import path without needing to know the exact location of the file.

On this page