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.
--rui-primary
--rui-primary-dark
--rui-secondary
--rui-accent
--rui-success
--rui-warning
--rui-error
--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.
| Variable | Default | Description |
|---|---|---|
| --rui-primary | #6366f1 | Primary brand color used for buttons, links, and active states |
| --rui-primary-dark | #4f46e5 | Darker shade of primary, used for hover and pressed states |
| --rui-secondary | #f1f5f9 | Secondary background color for cards, inputs, and subtle surfaces |
| --rui-accent | #f59e0b | Accent color for highlights, badges, and call-to-action elements |
| --rui-background | #ffffff | Page background color |
| --rui-foreground | #0f172a | Primary text color |
| --rui-muted | #64748b | Muted text color for descriptions, captions, and helper text |
| --rui-border | #e2e8f0 | Default border color for cards, inputs, and dividers |
| --rui-radius-sm | 4px | Small border radius for badges and chips |
| --rui-radius-md | 8px | Medium border radius for buttons and inputs |
| --rui-radius-lg | 12px | Large border radius for cards and modals |
| --rui-radius-full | 9999px | Full border radius for avatars and pill shapes |
| --rui-font-body | Inter, system-ui, sans-serif | Body and UI text font family |
| --rui-font-heading | Inter, system-ui, sans-serif | Heading font family |
| --rui-font-mono | JetBrains Mono, monospace | Monospace font for code blocks and inline code |
| --rui-shadow-sm | 0 1px 2px rgba(0,0,0,0.05) | Small shadow for subtle elevation |
| --rui-shadow-md | 0 4px 6px rgba(0,0,0,0.07) | Medium shadow for cards and dropdowns |
| --rui-shadow-lg | 0 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.
| Token | Size | Line Height | Usage |
|---|---|---|---|
| xs | 0.75rem / 12px | 1rem | Captions, badges, small labels |
| sm | 0.875rem / 14px | 1.25rem | Helper text, table cells, secondary text |
| base | 1rem / 16px | 1.5rem | Body text, paragraphs, form labels |
| lg | 1.125rem / 18px | 1.75rem | Lead text, card descriptions |
| xl | 1.25rem / 20px | 1.75rem | Section subheadings |
| 2xl | 1.5rem / 24px | 2rem | Section headings |
| 3xl | 1.875rem / 30px | 2.25rem | Page titles |
| 4xl | 2.25rem / 36px | 2.5rem | Hero 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 */
}