Installation
Get started with Versa UI by following this installation guide. It covers everything you need to integrate Versa UI into your React project.
Prerequisites
Before installing Versa UI, ensure your project meets these requirements:
- React 18.0 or higher (React 19 recommended)
- Tailwind CSS 4.0 or higher
- A bundler like Vite, Next.js, or Webpack
Versa UI is built with Tailwind CSS v4 and React 19. If you're using older versions, some components may not work as expected.
Package Installation
Install the Versa UI package:
npm install @versaui/ui/reactCore Dependencies
These packages are required by all components. Install any that your project doesn't already have:
npm install react react-dom tailwindcss clsx tailwind-merge class-variance-authority @phosphor-icons/reactInteraction & Accessibility Dependencies
Used by Button, Checkbox, Toggle, Slider, SegmentedControl, ProgressBar, and other interactive components:
npm install @react-aria/focus @react-aria/interactions @react-aria/button @react-aria/progress @react-aria/utils react-aria-componentsDropdown Dependencies
The Dropdown component uses Floating UI for positioning:
npm install @floating-ui/reactDate & Calendar Dependencies
Required only if you use DatePicker, DateRangePicker, or Calendar components:
npm install @internationalized/date @react-aria/calendar @react-aria/i18n @react-stately/calendar @react-types/calendar @react-types/sharedCSS Setup
Import the required styles in your main CSS file. Order matters:
/* Fonts — all families used across themes */
@import url('https://fonts.googleapis.com/css2?family=DM+Mono:ital,wght@0,300;0,400;0,500;1,300;1,400;1,500&family=DM+Sans:ital,opsz,wght@0,9..40,100..1000;1,9..40,100..1000&family=DM+Serif+Display&family=Manrope:wght@200..800&family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&family=Space+Grotesk:wght@300..700&display=swap');
/* Tailwind + Versa UI source scanning */
@import "tailwindcss";
@source "../node_modules/@versaui/ui/react/dist/**/*.{js,ts,jsx,tsx}";
/* Design tokens */
@import "@versaui/ui/react/styles/primitives.css";
/* Import only the themes you need */
@import "@versaui/ui/react/styles/themes/core.css";
@import "@versaui/ui/react/styles/themes/glassmorphism.css";
/* @import "@versaui/ui/react/styles/themes/brutalism.css"; */
/* @import "@versaui/ui/react/styles/themes/humanist.css"; */The @source directive tells Tailwind 4 to include Versa UI component files in its class detection. Adjust the path based on your project structure.
Base Styles
Add base styles for proper typography and colors:
@layer base {
:root {
font-family: var(--typography-font-family-body);
line-height: var(--typescale-b3-line-height);
font-weight: var(--typography-font-weight-body);
color-scheme: light dark;
color: var(--color-neutral-text-strong);
background-color: var(--color-neutral-background-default);
font-synthesis: none;
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, h5, h6 {
font-family: var(--typography-font-family-display);
}
body {
margin: 0;
min-width: 320px;
min-height: 100vh;
background-color: var(--color-neutral-background-default);
color: var(--color-neutral-text-strong);
font-family: var(--typography-font-family-body);
}
button {
font-family: inherit;
cursor: pointer;
}
}Theme & Mode Setup
Versa UI supports multiple themes and color modes (light/dark). Configure these using data attributes on your root element:
<html data-theme="core" data-mode="light">
<!-- or -->
<html data-theme="brutalism" data-mode="dark">Available Themes
| Theme | Description |
|---|---|
core | Clean, modern design with soft shadows and rounded corners |
glassmorphism | Frosted glass effects with layered depth |
brutalism | Bold, high-contrast design with sharp edges |
humanist | Refined, luxurious, and sophisticated |
Dynamic Theme Switching
Toggle themes and modes programmatically:
function ThemeSwitcher() {
const setTheme = (theme: 'core' | 'glassmorphism' | 'brutalism' | 'humanist') => {
document.documentElement.dataset.theme = theme;
};
const setMode = (mode: 'light' | 'dark') => {
document.documentElement.dataset.mode = mode;
};
return (
<div>
<button onClick={() => setTheme('core')}>Core Theme</button>
<button onClick={() => setTheme('glassmorphism')}>Glassmorphism Theme</button>
<button onClick={() => setTheme('brutalism')}>Brutalism Theme</button>
<button onClick={() => setTheme('humanist')}>Humanist Theme</button>
<button onClick={() => setMode('light')}>Light Mode</button>
<button onClick={() => setMode('dark')}>Dark Mode</button>
</div>
);
}System Preference Detection
Respect user's system color scheme preference:
import { useEffect } from 'react';
function useSystemColorScheme() {
useEffect(() => {
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
const updateMode = (e: MediaQueryListEvent | MediaQueryList) => {
document.documentElement.dataset.mode = e.matches ? 'dark' : 'light';
};
updateMode(mediaQuery);
mediaQuery.addEventListener('change', updateMode);
return () => mediaQuery.removeEventListener('change', updateMode);
}, []);
}Provider Setup
Most Versa UI components are self-contained and don't require additional providers. Components like Modal, Dropdown, and Tooltip handle their own context internally.
Toast Provider
The Toast system requires a provider for stacking support:
import { ToastProvider, ToastViewport } from '@versaui/ui/react/ToastViewport';
function App() {
return (
<ToastProvider maxToasts={3}>
<YourApp />
<ToastViewport bottomOffset={24} />
</ToastProvider>
);
}Icons & Fonts
Icons
Versa UI uses Phosphor Icons throughout its components:
import { MagnifyingGlass, User, Bell } from '@phosphor-icons/react';
function MyComponent() {
return (
<div>
<MagnifyingGlass size={20} weight="regular" />
<User size={24} weight="duotone" />
<Bell size={16} weight="fill" />
</div>
);
}Available Weights: thin, light, regular (default), bold, fill, duotone
Fonts
Each theme uses a different combination of font families. All fonts are loaded via the Google Fonts import in your CSS.
| Theme | Display (H1–H5) | Title (H6–H9) | Body | Code |
|---|---|---|---|---|
Core | Manrope | Manrope | Manrope | DM Mono |
Brutalism | Space Grotesk | Space Grotesk | DM Sans | DM Mono |
Glassmorphism | DM Sans | DM Sans | DM Sans | DM Mono |
Humanist | DM Serif Display | Plus Jakarta Sans | Plus Jakarta Sans | DM Mono |
Accessibility
Versa UI components are built with accessibility as a core principle using React Aria for robust keyboard and screen reader support.
Keyboard Navigation
All interactive components support keyboard navigation:
- Tab / Shift+Tab — Navigate between focusable elements
- Enter / Space — Activate buttons and toggles
- Arrow keys — Navigate within menus, accordions, and selects
- Escape — Close modals, dropdowns, and tooltips
Focus Indicators
All focusable elements have visible focus rings using design tokens:
/* Focus ring tokens used internally */
--focus-ring-primary: 0 0 0 2px var(--color-brand-primary-subtler);
--focus-ring-neutral: 0 0 0 2px var(--color-neutral-surface-strong);Screen Reader Support
- Semantic HTML elements used throughout
- ARIA labels and descriptions where needed
- Live regions for dynamic content updates (e.g., Toast notifications)
- Focus management for modals and dialogs
Customization
Versa UI is designed to be fully customizable. All styling is controlled via CSS custom properties (tokens), making it easy to adapt the design system to your brand.
Changing Fonts
Override the typography tokens in your CSS to use your own brand fonts:
@layer base {
:root {
/* Replace with your brand fonts */
--typography-font-family-body: 'Inter', system-ui, sans-serif;
--typography-font-family-display: 'Poppins', system-ui, sans-serif;
--typography-font-family-title: 'Inter', system-ui, sans-serif;
/* Adjust font weights if needed */
--typography-font-weight-body: 400;
--typography-font-weight-display: 700;
--typography-font-weight-title: 600;
}
}Don't forget to import your custom fonts:
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300..700&family=Poppins:wght@400;600;700&display=swap');Changing Brand Colors
Override the brand color tokens to match your brand palette:
@layer base {
:root {
/* Primary brand color (used for buttons, links, focus states) */
--color-brand-primary-medium: #6366F1; /* Main brand color */
--color-brand-primary-strong: #4F46E5; /* Darker shade */
--color-brand-primary-stronger: #4338CA; /* Even darker */
--color-brand-primary-subtle: #818CF8; /* Lighter shade */
--color-brand-primary-subtler: #C7D2FE; /* Even lighter */
--color-brand-primary-subtlest: #EEF2FF; /* Lightest/background */
/* Secondary, tertiary, quaternary colors follow same pattern */
--color-brand-secondary-medium: #8B5CF6;
--color-brand-secondary-strong: #7C3AED;
/* ... */
}
/* Dark mode overrides */
[data-mode="dark"] {
--color-brand-primary-medium: #818CF8;
--color-brand-primary-strong: #A5B4FC;
--color-brand-primary-subtle: #4F46E5;
--color-brand-primary-subtler: #312E81;
--color-brand-primary-subtlest: #1E1B4B;
}
}Use a tool like Realtime Colors or Coolors to generate a harmonious color palette, then map the shades to the Versa UI token structure.
Changing Corner Radius, Spacing & Shadows
@layer base {
:root {
/* Corner radius — default and thematic */
--corner-radius-default-medium: 8px;
--corner-radius-thematic-medium: 6px;
/* Spacing scale (1–13) */
--spacing-4: 8px;
--spacing-6: 16px;
--spacing-8: 24px;
/* Elevation shadows */
--elevation-small-1-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05);
--elevation-medium-1-shadow: 0 2px 8px 0 rgba(0, 0, 0, 0.06);
--elevation-large-1-shadow: 0 3px 12px 0 rgba(0, 0, 0, 0.08);
}
}Creating a Custom Theme
To create an entirely new theme, define all tokens under a new data-theme selector:
@layer base {
[data-theme="my-brand"][data-mode="light"] {
/* All your custom token values */
--typography-font-family-body: 'Your Font', sans-serif;
--color-brand-primary-medium: #YOUR_COLOR;
--corner-radius-default-medium: 0px; /* Sharp corners */
/* ... rest of tokens */
}
[data-theme="my-brand"][data-mode="dark"] {
/* Dark mode variants */
}
}Then activate it:
<html data-theme="my-brand" data-mode="light">When creating custom themes, ensure you define both light and dark mode variants for all color tokens. Missing tokens will fall back to the default theme values.
Verify Your Setup
Let's verify your setup with a simple example:
import { Button } from '@versaui/ui/react/Button';
import { Tooltip } from '@versaui/ui/react/Tooltip';
function HelloVersaUI() {
return (
<div style={{ padding: '2rem' }}>
<Tooltip content="Welcome to Versa UI!" placement="top">
<Button variant="primary" size="default">
Hover Me
</Button>
</Tooltip>
</div>
);
}
export default HelloVersaUI;If you see a styled button with a tooltip on hover, your setup is complete!
Common Pitfalls
Missing CSS Imports
Symptom: Components render but have no styling or incorrect colors.
Fix: Ensure you've imported primitives.css and at least one theme file:
@import "@versaui/ui/react/styles/primitives.css";
@import "@versaui/ui/react/styles/themes/core.css";Missing Theme Data Attributes
Symptom: Colors appear as undefined or fallback values.
Fix: Add theme and mode attributes to your root element:
<html data-theme="core" data-mode="light">Tailwind Not Detecting Classes
Symptom: Some component styles are missing.
Fix: Add Versa UI to your Tailwind content configuration:
@source "../node_modules/@versaui/ui/react/dist/**/*.{js,ts,jsx,tsx}";Font Loading Issues
Symptom: Fonts flash or fall back to system fonts.
Fix: Preload fonts in your HTML head:
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Manrope:wght@200..800&display=swap" rel="stylesheet">React 18 Compatibility
Symptom: Hydration errors or ref warnings.
Fix: Some components use React 19 features. Ensure you're on React 18.3+ or upgrade to React 19:
npm install react@19 react-dom@19Z-Index Conflicts
Symptom: Modals or dropdowns appear behind other elements.
Fix: Versa UI uses z-index values like 9999 for overlays. If you have conflicting z-index values, adjust your global styles or use the style prop on modal containers.
Next Steps
Now that you have Versa UI installed, explore: