Installation & Theming
How to install StyleLab UI and switch between its 8 themes in your React app.
Prerequisites
- React 18+ — The library uses hooks and modern React patterns.
- Tailwind CSS v4 — StyleLab themes are built on Tailwind v4’s
@themeand utilities. v3 is not supported. - A build setup that supports CSS
@import(Vite, Next.js, Parcel, etc.).
1. Installation
Install the package and its peer dependencies.
npm install @raxrai/stylelab-ui react react-domWith Yarn or pnpm:
yarn add @raxrai/stylelab-ui react react-dom
# or
pnpm add @raxrai/stylelab-ui react react-domPeer dependencies: react and react-dom (≥18). The library bundles class-variance-authority, clsx, tailwind-merge, lucide-react, and framer-motion; you do not need to install them separately.
2. Add the styles
Your app must use Tailwind CSS v4. Import StyleLab’s design tokens in your global CSS after Tailwind so custom shadows and theme utilities are available.
@import "tailwindcss";
@import "@raxrai/stylelab-ui/styles";The StyleLab stylesheet provides:
- Custom shadows — e.g.
--shadow-neubrutal,--shadow-clay-outer,--shadow-glass-edge,--shadow-neon-glowfor Cyberpunk. - Keyframes — e.g. skeleton shimmer, glitch (Cyberpunk).
- Theme-specific utilities used by the components.
If your setup uses a different Tailwind entry (e.g. a preset or @tailwind base/components/utilities), ensure the StyleLab import runs after Tailwind so @theme inline tokens are applied. In Next.js, this usually means adding both imports at the top of your app/globals.css (or styles/globals.css).
3. Wrap your app with ThemeProvider
All StyleLab components read the active theme from React context. Wrap your app (or the subtree that uses the library) with ThemeProvider and set a defaultTheme. The provider must be a client component ("use client") because it uses state and useEffect.
import { ThemeProvider } from "@raxrai/stylelab-ui";
export default function RootLayout({ children }) {
return (
<html>
<body>
<ThemeProvider defaultTheme="minimal">
{children}
</ThemeProvider>
</body>
</html>
);
}To restore the user’s last chosen theme from localStorage, read it in a client component and pass it as defaultTheme. The provider does not read from storage on mount; it only writes when setTheme is called.
"use client";
import { useEffect, useState } from "react";
import { ThemeProvider, THEMES } from "@raxrai/stylelab-ui";
const STORAGE_KEY = "stylelab-theme";
const FALLBACK = "minimal";
function getStoredTheme(): string {
if (typeof window === "undefined") return FALLBACK;
try {
const stored = localStorage.getItem(STORAGE_KEY);
return stored && THEMES.includes(stored) ? stored : FALLBACK;
} catch {
return FALLBACK;
}
}
export function Providers({ children }: { children: React.ReactNode }) {
const [initialTheme, setInitialTheme] = useState(FALLBACK);
useEffect(() => {
setInitialTheme(getStoredTheme());
}, []);
return (
<ThemeProvider defaultTheme={initialTheme}>
{children}
</ThemeProvider>
);
}4. Use components and switch the theme
Import components and the useTheme hook. The hook returns theme (current theme) and setTheme (update and persist). Use the hook only inside a subtree wrapped by ThemeProvider; otherwise you get a safe fallback (minimal, no-op setTheme).
import { Button, Card, useTheme } from "@raxrai/stylelab-ui";
export function MyPage() {
const { theme, setTheme } = useTheme();
return (
<div>
<Button variant="primary">Click me</Button>
<Card>Content</Card>
<select
value={theme}
onChange={(e) => setTheme(e.target.value)}
>
<option value="minimal">Minimal</option>
<option value="night">Night</option>
<option value="glass">Glass</option>
{/* ... other themes */}
</select>
</div>
);
}For TypeScript, use the StyleLabTheme type when typing theme state or props.
4b. Per-component theme override
Many components accept an optional theme prop. When set, that instance uses the given theme instead of the context theme. Useful for one-off cards, modals, or sections that should look different from the rest of the app.
import { Card, Badge, Modal } from "@raxrai/stylelab-ui";
// One card in Cyberpunk while the app is in Minimal
<Card theme="cyberpunk">Neon card</Card>
<Badge theme="night">Dark badge</Badge>
<Modal open={open} onClose={() => setOpen(false)} theme="glass">
Glass-style modal
</Modal>Components that support the theme prop include Button, Badge, Card, Input, Alert, Modal, Tabs, Tooltip, Accordion, Avatar, Breadcrumbs, Calendar, CommandPalette, and others. Check each component’s props in the Gallery.
5. Available themes
Pass any of these values to defaultTheme or setTheme(theme). TypeScript type: StyleLabTheme.
- Minimal
minimal— Clean surfaces, neutral palette, focused typography. - Night
night— Dark-first with subtle borders and inset shadows. - Glass
glass— Glassmorphism: blur, depth, soft shadows. - Neubrutal
neubrutal— Bold borders, flat shadows, high contrast. - Clay
clay— Soft 3D feel with rounded shapes and clay shadows. - Cyberpunk
cyberpunk— Neon accents, glitch, terminal-ready. - Retro
retro— 8-bit inspired: blocky, lime accent, monospace. - Motion
motion— Heavily animated: transitions and hover feedback.
import type { StyleLabTheme } from "@raxrai/stylelab-ui";
import { THEMES } from "@raxrai/stylelab-ui";
// THEMES is: ["minimal", "night", "glass", "neubrutal", "clay", "cyberpunk", "retro", "motion"]6. Persistence and DOM attribute
When you call setTheme(theme), the provider:
- Updates React state so all components re-render with the new theme.
- Writes the theme to
localStorageunder the keystylelab-theme(so it can be restored on reload). - Sets
document.documentElement.dataset.stylelabThemeto the theme name.
The initial theme is controlled by defaultTheme. The provider does not read from localStorage on mount; if you want to restore a saved theme, read it yourself and pass it as defaultTheme (see the example in section 3).
Using the data attribute in your CSS
The root element gets data-stylelab-theme="minimal" (or the current theme). You can use this to style your own layout or non–StyleLab elements to match the active theme.
/* e.g. in your global CSS or a CSS module */
[data-stylelab-theme="night"] .my-sidebar {
background: rgb(24 24 27);
border-color: rgba(255 255 255 / 0.1);
}
[data-stylelab-theme="cyberpunk"] .my-heading {
color: #22d3ee;
}7. Nesting and per-section themes
You can nest ThemeProvider. Inner providers override the theme for their subtree. Use this when part of your UI should use a different theme (e.g. a dark sidebar, a marketing block in Glass, or a modal in Cyberpunk).
<ThemeProvider defaultTheme="minimal">
<main>App in Minimal</main>
<ThemeProvider defaultTheme="cyberpunk">
<aside>This sidebar uses Cyberpunk theme.</aside>
</ThemeProvider>
</ThemeProvider>8. Troubleshooting
- Components look unstyled or wrong. Ensure
@import "@raxrai/stylelab-ui/styles"runs after Tailwind in your global CSS. If StyleLab is imported first, Tailwind’s layers can override the theme tokens. - I’m on Tailwind v3. StyleLab is built for Tailwind v4 (with
@theme inline). It is not compatible with v3. Upgrade to Tailwind v4 or use the library’s prebuilt CSS if a v4-compat build is provided. - Theme doesn’t persist after refresh. The provider only writes to localStorage when
setThemeis called. To restore on load, use the “Restore theme from localStorage” pattern in section 3. - useTheme() returns minimal and setTheme does nothing. The component is not inside a
ThemeProvider. Wrap the tree (e.g. in your root layout) withThemeProvider.
Quick reference
- • Prerequisites: React 18+, Tailwind CSS v4.
- • Install:
npm install @raxrai/stylelab-ui react react-dom - • Styles:
@import "@raxrai/stylelab-ui/styles"after Tailwind. - • Provider:
<ThemeProvider defaultTheme="minimal">around your app (client component). - • Theme hook:
const { theme, setTheme } = useTheme(). - • Override: Many components accept a
themeprop for that instance only. - • Theme values: minimal, night, glass, neubrutal, clay, cyberpunk, retro, motion.
- • Persistence:
setThemewrites tolocalStorageanddata-stylelab-themeondocument.documentElement.