Redpanda UIRedpanda UI
General

Install

Set up the Redpanda UI Registry in your project, then install components.

Prerequisites

Install @base-ui/react in your app before running shadcn add. Registry components import from @base-ui/react@^1.8.0, and the peer dep must be present in your package.json:

bun add @base-ui/react@^1.8.0
# npm install @base-ui/react@^1.8.0
# pnpm add @base-ui/react@^1.8.0

Project setup

You only need to do this once per project.

1. Create a components.json file

Create a components.json file at the root of your application or project:

{
  "$schema": "https://ui.shadcn.com/schema.json",
  "style": "new-york",
  "rsc": false,
  "tsx": true,
  "tailwind": {
    "config": "",
    "css": "src/globals.css",
    "baseColor": "neutral",
    "cssVariables": true
  },
  "aliases": {
    "components": "@/components/redpanda-ui",
    "utils": "@/components/redpanda-ui/lib/utils",
    "ui": "@/components/redpanda-ui",
    "lib": "@/components/redpanda-ui/lib",
    "hooks": "@/components/redpanda-ui/lib"
  },
  "iconLibrary": "lucide",
  "registries": {
    "@redpanda": "https://redpanda-ui-registry.netlify.app/r/{name}.json"
  }
}

Adjust the aliases paths if your project uses a different base directory for UI components.

2. Install and configure Tailwind CSS

The UI Registry uses Tailwind CSS for styling. You'll need to configure the Tailwind compiler in your project.

bun add tailwindcss tw-animate-css
bun add @tailwindcss/postcss -D

Then, create a postcss.config.mjs file at the root of your application or project.

export default {
  plugins: {
    '@tailwindcss/postcss': {
      content: ['./src/**/*.{js,ts,jsx,tsx}'],
    },
  },
};

3. Install the theme and import styles

bunx shadcn@latest add @redpanda/theme

Create a globals.css file within your project's src directory and add the following:

@import "tailwindcss";
@import "tw-animate-css";
@import "./components/redpanda-ui/style/theme.css"; /* or wherever your aliases point + /style/theme.css */

The order matters. theme.css extends Tailwind — @theme, @utility, @custom-variant — and its @layer base block has to land inside the layer order that @import "tailwindcss" declares, so Tailwind comes first. If you keep a palette override file of your own, it goes after theme.css: see Theming your app.

4. Wrap your app in RedpandaProvider

Most registry components rely on a few cross-cutting providers — theme management, a motion/react MotionConfig, and a global Sonner toaster. The registry ships these pre-wired as the Redpanda Provider. Install it once and mount it near the root of your app:

bunx shadcn@latest add @redpanda/redpanda-provider
import { RedpandaProvider } from "@/components/redpanda-ui/components/redpanda-provider";
import { ThemeScript } from "@/components/redpanda-ui/components/theme-provider";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en" suppressHydrationWarning>
      <body>
        {/* Before anything paints — see below */}
        <ThemeScript />
        <RedpandaProvider>{children}</RedpandaProvider>
      </body>
    </html>
  );
}

5. Apply the theme before the first paint

ThemeProvider can only apply the stored theme from its mount effect, which is one paint too late: a server-rendered page shows the light ground and then flips to dark. ThemeScript is that same resolve as a blocking inline script — render it inside <head> or as the first thing in <body>, and put suppressHydrationWarning on <html>, since the script's whole job is to mutate the element the server rendered. Pass it the same storageKey and defaultTheme as the provider, or the two disagree for one paint.

A client-rendered app (Vite, CRA) has an entry module that runs before React instead, so call initTheme there — above createRoot:

src/main.tsx
import { initTheme, ThemeProvider } from "@/components/redpanda-ui/components/theme-provider";

initTheme({ defaultTheme: "dark", storageKey: "my-app:theme" });

ReactDOM.createRoot(document.getElementById("root")!).render(
  <ThemeProvider defaultTheme="dark" storageKey="my-app:theme">
    <App />
  </ThemeProvider>
);

Both write the same three things, which together are what "being in a theme" means: data-theme (what theme.css keys on), the .dark class (for CSS the theme does not own — a stylesheet you vendored before the move, or Tailwind's own class-based dark: in your app code), and color-scheme (what the browser keys on: scrollbars, native form controls, date pickers). Nothing else in your app needs to set any of them.

Fonts & typography

Installing @redpanda/theme (step 3 above) handles fonts automatically — no Google Fonts link or manual font setup is needed. The theme package adds the following npm dependencies to your project and theme.css imports them:

PackageFonts provided
@fontsource/inter (weights 400/500/600/700)Inter — --font-sans
inter-uiInterDisplay — --font-display
@fontsource/geist-mono (weights 400/500/600)Geist Mono — --font-mono

Fonts are self-hosted: they resolve from node_modules through your bundler, so no CDN dependency is introduced.

Install a component

Most projects only need a handful of components. Every registry item is addressable as @redpanda/<name> — pass one or more names to shadcn add and the CLI copies the source (plus any dependencies) directly into your project.

Install a single component:

bunx shadcn@latest add @redpanda/button

Install several at once — the CLI resolves shared dependencies so nothing is duplicated:

bunx shadcn@latest add @redpanda/button @redpanda/input @redpanda/form

Browse and build a command

Pick components by category. The command at the bottom updates live as you tick boxes — copy it once you've got the set you want. Toggle --overwrite to replace existing local copies.

No components selected
bunx shadcn@latest add @redpanda/<component>

Install everything

For scaffolding a new app, auditing the full set of components, or maintaining an internal fork, the registry ships a meta item — @redpanda/all — that depends on every component, hook, and style. Running the command below is equivalent to ticking every box above.

Install the full registry
bunx shadcn@latest add @redpanda/all --overwrite

Update components

Use add with --overwrite to update a component to the latest version:

bunx shadcn@latest add @redpanda/button --overwrite

To update the entire registry at once:

bunx shadcn@latest add @redpanda/all --overwrite

Use diff to see what changed in a component since you installed it:

bunx shadcn@latest diff @redpanda/button

Other CLI commands

Preview a component's code before installing:

bunx shadcn@latest view @redpanda/button

Search for components in the registry:

bunx shadcn@latest search --query "form"

Migrating from fumadocs/cli

If you previously used @fumadocs/cli with a cli.json file, run the migration script:

bash <(curl -fsSL https://redpanda-ui-registry.netlify.app/migrate.sh) --cwd .

The script reads your existing cli.json, generates components.json with the correct aliases and @redpanda registry, deletes cli.json, and prints reinstall commands for all detected components.

Or migrate manually:

  1. Create components.json as shown above (use your existing cli.json baseDir to set the aliases paths)
  2. Delete cli.json
  3. Install new components with bunx shadcn@latest add @redpanda/<name> instead of bunx @fumadocs/cli add --dir ...

Your existing installed component files will continue to work as-is. No changes needed to already-installed code.

Built by malinskibeniamin. The source code is available on GitHub.

On this page