Theming

Take full control of your design system. ReactUI uses CSS custom properties for theming, making it trivial to customize colors, typography, spacing, border radius, and dark mode across every component.

Color Palette

ReactUI ships with a carefully curated set of colors. Each color maps to a CSS variable that you can override globally or per-component.

Primary
#6366f1

--rui-primary

Primary Dark
#4f46e5

--rui-primary-dark

Secondary
#f1f5f9

--rui-secondary

Accent
#f59e0b

--rui-accent

Success
#22c55e

--rui-success

Warning
#eab308

--rui-warning

Error
#ef4444

--rui-error

Info
#3b82f6

--rui-info

CSS Variables Reference

Below is the complete list of CSS custom properties used by ReactUI. Override any of them in your global stylesheet to customize the design system.

VariableDefaultDescription
--rui-primary#6366f1Primary brand color used for buttons, links, and active states
--rui-primary-dark#4f46e5Darker shade of primary, used for hover and pressed states
--rui-secondary#f1f5f9Secondary background color for cards, inputs, and subtle surfaces
--rui-accent#f59e0bAccent color for highlights, badges, and call-to-action elements
--rui-background#ffffffPage background color
--rui-foreground#0f172aPrimary text color
--rui-muted#64748bMuted text color for descriptions, captions, and helper text
--rui-border#e2e8f0Default border color for cards, inputs, and dividers
--rui-radius-sm4pxSmall border radius for badges and chips
--rui-radius-md8pxMedium border radius for buttons and inputs
--rui-radius-lg12pxLarge border radius for cards and modals
--rui-radius-full9999pxFull border radius for avatars and pill shapes
--rui-font-bodyInter, system-ui, sans-serifBody and UI text font family
--rui-font-headingInter, system-ui, sans-serifHeading font family
--rui-font-monoJetBrains Mono, monospaceMonospace font for code blocks and inline code
--rui-shadow-sm0 1px 2px rgba(0,0,0,0.05)Small shadow for subtle elevation
--rui-shadow-md0 4px 6px rgba(0,0,0,0.07)Medium shadow for cards and dropdowns
--rui-shadow-lg0 10px 15px rgba(0,0,0,0.1)Large shadow for modals and popovers

Overriding CSS Variables

Add your overrides in your global CSS file. The variables cascade through the entire component tree automatically.

:root {
  /* Brand colors */
  --rui-primary: #e11d48;
  --rui-primary-dark: #be123c;
  --rui-accent: #8b5cf6;

  /* Surfaces */
  --rui-background: #fafafa;
  --rui-secondary: #f4f4f5;
  --rui-border: #d4d4d8;

  /* Typography */
  --rui-foreground: #18181b;
  --rui-muted: #71717a;

  /* Radius */
  --rui-radius-sm: 6px;
  --rui-radius-md: 10px;
  --rui-radius-lg: 16px;

  /* Fonts */
  --rui-font-body: 'Geist', system-ui, sans-serif;
  --rui-font-heading: 'Geist', system-ui, sans-serif;
  --rui-font-mono: 'Geist Mono', monospace;
}

Dark Mode

ReactUI supports three color modes: light, dark, and system (follows the user's OS preference). Configure it via the provider or toggle programmatically with the useColorMode hook.

Provider Configuration

// Light mode (default)
<ReactUIProvider theme="light">
  {children}
</ReactUIProvider>

// Dark mode
<ReactUIProvider theme="dark">
  {children}
</ReactUIProvider>

// Follow system preference
<ReactUIProvider theme="system">
  {children}
</ReactUIProvider>

Toggle with Hook

Use the useColorMode hook to read and change the current mode at runtime. This is ideal for building a theme toggle button.

'use client';

import { useColorMode, Button } from '@reactui/core';

export function ThemeToggle() {
  const { colorMode, setColorMode } = useColorMode();

  return (
    <Button
      variant="outline"
      onClick={() =>
        setColorMode(colorMode === 'light' ? 'dark' : 'light')
      }
    >
      {colorMode === 'light' ? '🌙 Dark' : '☀️ Light'}
    </Button>
  );
}

Dark Mode CSS Variables

When dark mode is active, ReactUI automatically applies a .dark class to the root element. You can customize dark mode colors by targeting this class.

.dark {
  --rui-primary: #818cf8;
  --rui-primary-dark: #6366f1;
  --rui-background: #0f172a;
  --rui-foreground: #f1f5f9;
  --rui-secondary: #1e293b;
  --rui-border: #334155;
  --rui-muted: #94a3b8;
  --rui-accent: #fbbf24;

  --rui-shadow-sm: 0 1px 2px rgba(0,0,0,0.3);
  --rui-shadow-md: 0 4px 6px rgba(0,0,0,0.4);
  --rui-shadow-lg: 0 10px 15px rgba(0,0,0,0.5);
}

Creating a Custom Theme

For advanced control, use the createTheme utility to generate a complete theme object. This approach gives you type-safe access to every design token.

import { createTheme, ReactUIProvider } from '@reactui/core';

const brandTheme = createTheme({
  colors: {
    primary: '#0ea5e9',       // Sky-500
    primaryDark: '#0284c7',   // Sky-600
    secondary: '#f0f9ff',     // Sky-50
    accent: '#f97316',        // Orange-500
    success: '#10b981',       // Emerald-500
    warning: '#f59e0b',       // Amber-500
    error: '#ef4444',         // Red-500
    info: '#6366f1',          // Indigo-500
    background: '#ffffff',
    foreground: '#0c4a6e',    // Sky-900
    muted: '#64748b',
    border: '#e0f2fe',        // Sky-100
  },
  radius: {
    sm: '4px',
    md: '8px',
    lg: '16px',
    full: '9999px',
  },
  fonts: {
    body: '"Plus Jakarta Sans", system-ui, sans-serif',
    heading: '"Plus Jakarta Sans", system-ui, sans-serif',
    mono: '"Fira Code", monospace',
  },
  shadows: {
    sm: '0 1px 3px rgba(14, 165, 233, 0.08)',
    md: '0 4px 12px rgba(14, 165, 233, 0.12)',
    lg: '0 12px 24px rgba(14, 165, 233, 0.16)',
  },
});

export default function RootLayout({ children }) {
  return (
    <ReactUIProvider theme={brandTheme}>
      {children}
    </ReactUIProvider>
  );
}

Extending the Default Theme

You do not need to override every token. The createTheme function deep-merges your values with the defaults, so you can override only what you need.

const minimalOverride = createTheme({
  colors: {
    primary: '#e11d48',   // Only override primary
  },
  radius: {
    md: '12px',           // Slightly rounder corners
  },
});
// All other tokens keep their default values.

Typography Scale

ReactUI uses a harmonious type scale based on a 1.125 ratio. Use the Text component or apply sizes directly via CSS variables. The scale is designed to be legible at every size with proper line heights.

TokenSizeLine HeightUsage
xs0.75rem / 12px1remCaptions, badges, small labels
sm0.875rem / 14px1.25remHelper text, table cells, secondary text
base1rem / 16px1.5remBody text, paragraphs, form labels
lg1.125rem / 18px1.75remLead text, card descriptions
xl1.25rem / 20px1.75remSection subheadings
2xl1.5rem / 24px2remSection headings
3xl1.875rem / 30px2.25remPage titles
4xl2.25rem / 36px2.5remHero headings

Using the Text Component

import { Text } from '@reactui/core';

function TypographyExample() {
  return (
    <div>
      <Text variant="h1">Heading 1</Text>
      <Text variant="h2">Heading 2</Text>
      <Text variant="h3">Heading 3</Text>
      <Text variant="body">
        Body text for paragraphs and general content.
      </Text>
      <Text variant="caption" color="muted">
        Caption text for labels and metadata.
      </Text>
      <Text variant="code">
        const x = 42;
      </Text>
    </div>
  );
}

Spacing Tokens

ReactUI components use a consistent spacing scale based on a 4px grid. These tokens are applied to padding, margin, and gap properties throughout the library.

:root {
  --rui-space-1: 0.25rem;   /*  4px */
  --rui-space-2: 0.5rem;    /*  8px */
  --rui-space-3: 0.75rem;   /* 12px */
  --rui-space-4: 1rem;      /* 16px */
  --rui-space-5: 1.25rem;   /* 20px */
  --rui-space-6: 1.5rem;    /* 24px */
  --rui-space-8: 2rem;      /* 32px */
  --rui-space-10: 2.5rem;   /* 40px */
  --rui-space-12: 3rem;     /* 48px */
  --rui-space-16: 4rem;     /* 64px */
}