# Animation
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/animation
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(handbook)/animation.mdx
> Add smooth animations and transitions to HeroUI Native components
All animations in HeroUI Native are built with [react-native-reanimated](https://docs.swmansion.com/react-native-reanimated/) and gesture control is handled by [react-native-gesture-handler](https://docs.swmansion.com/react-native-gesture-handler/). It's worth familiarizing yourself with these libraries if you want more control over animations.
## The `animation` Prop
Every animated component in HeroUI Native exposes a single `animation` prop that controls all animations for that component. This prop allows you to modify animation values, timing configurations, layout animations, or completely disable animations.
**Approach**: If you're working with animations, first look for the `animation` prop on the component you're using.
## Modifying Animations
You can customize animations by passing an object to the `animation` prop. Each component exposes different animation properties that you can modify. The approach is simple: if you want to slightly change the animation behavior of already written animations in components, we provide all necessary values for modification. If you want to write your own animations without relying on our written ones, you must create your own custom components with animations.
### Example 1: Simple Value Modification
Modify animation values like scale, opacity, or colors:
```tsx
import {Switch} from 'heroui-native';
;
```
### Example 2: Timing Configuration
Customize animation timing and easing:
```tsx
import {Accordion} from 'heroui-native';
;
```
### Example 3: Layout Animations (Entering/Exiting)
Customize entering and exiting animations using Reanimated's layout animations:
```tsx
import {Accordion} from 'heroui-native';
import {FadeInRight, FadeInLeft, ZoomIn} from 'react-native-reanimated';
import {Easing} from 'react-native-reanimated';
Content here
;
```
## Disabling Animations
You can disable animations at different levels using the `animation` prop.
### Disable Options
* `animation={false}` or `animation="disabled"`: Disable animations for the specific component only
* `animation="disable-all"`: Disable all animations including children (only available at root level)
* `animation={true}` or `animation={undefined}`: Use default animations
### Component-Level Disabling
Disable animations for a specific component:
```tsx
```
### Root-Level Disabling (`disable-all`)
The `"disable-all"` option is only available at the root level of compound components. When used, it disables all animations including children, even if those children are not part of the compound component structure:
```tsx
// Disables all animations including Button components inside Card
$450Living room Sofa
```
**Important**: `"disable-all"` cascades down to all child components, including standalone components like `Button`, `Spinner`, etc., not just compound component parts.
## Global Animation Configuration
You can disable all HeroUI Native animations globally using the `HeroUINativeProvider`:
```tsx
import {HeroUINativeProvider} from 'heroui-native';
;
```
This will disable all animations across your entire application, regardless of individual component `animation` prop settings.
## Accessibility
Reduce motion is handled automatically under the hood. When a user enables "Reduce Motion" in their device accessibility settings, all animations are automatically disabled globally. This is handled by the `GlobalAnimationSettingsProvider` which checks `useReducedMotion()` from react-native-reanimated.
You don't need to do anything - the library respects the user's accessibility preferences automatically.
## Animation State Management
We keep disabled state of animations under control internally to ensure they look nice without unpredictable lags or jumps. When animations are disabled, components immediately jump to their final state rather than animating, preventing visual glitches or intermediate states.
## Children Render Function
Many components support a render function pattern for children, which is particularly handy when working with state like `isSelected`:
```tsx
import {Switch} from 'heroui-native';
{({isSelected, isDisabled}) => (
{isSelected ? : }
)}
;
```
This pattern allows you to conditionally render content based on component state, making it easy to create dynamic UIs that respond to selection, disabled states, and other component properties.
## Next Steps
* Learn about [Styling](/docs/native/getting-started/styling) approaches
* View [Theming](/docs/native/getting-started/theming) documentation
* Explore [Colors](/docs/native/getting-started/colors) documentation
# Colors
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/colors
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(handbook)/colors.mdx
> Color palette and theming system for HeroUI Native
import {ColorSwatch, ColorPalette} from "@/components/color-swatch";
HeroUI Native uses CSS variables for colors that automatically switch between light and dark themes. All colors use the `oklch` color space for better color transitions.
## How It Works
HeroUI Native's color system is built on top of [Tailwind CSS v4](https://tailwindcss.com/docs/theme)'s theme via [Uniwind](https://uniwind.dev/). When you import `heroui-native/styles`, it uses Tailwind's built-in color palettes and maps them to semantic variables.
**Naming pattern:**
* Colors without a suffix are backgrounds (e.g., `--accent`)
* Colors with `-foreground` are for text on that background (e.g., `--accent-foreground`)
**Usage:**
```tsx
import { View, Text } from 'react-native';
// This gives you the right background and text colors
Hello
```
### Base Colors
These four colors stay the same in all themes:
### Background & Surface
### Primary Colors
**Accent** — Your main brand color (used for primary actions)
**Accent Soft** — A lighter version for secondary actions
### Status Colors
For alerts, validation, and status messages:
### Form Field Colors
For consistent form field styling across input components:
### Other Colors
## How to Use Colors
**In your components:**
```tsx
import { View, Text } from 'react-native';
import { Button } from 'heroui-native';
Content
```
**In CSS files:**
```css title="global.css"
/* Direct CSS variables */
.container {
flex: 1;
background-color: var(--accent);
width: 50px;
height: 50px;
border-radius: var(--radius);
}
```
## Default Theme
The complete theme definition can be found in ([variables.css](https://github.com/heroui-inc/heroui-native/blob/beta/src/styles/variables.css)). This theme automatically switches between light and dark modes through [Uniwind's theming system](https://docs.uniwind.dev/theming/basics), which supports system preferences and programmatic theme switching.
```css
@theme {
/* Primitive Colors (Do not change between light and dark) */
--white: oklch(100% 0 0);
--black: oklch(0% 0 0);
--snow: oklch(0.9911 0 0);
--eclipse: oklch(0.2103 0.0059 285.89);
/* Base radius */
--radius: 0.5rem;
/* Opacity */
--opacity-disabled: 0.5;
}
@layer theme {
:root {
@variant light {
/* Base Colors */
--background: oklch(0.9702 0 0);
--foreground: var(--eclipse);
/* Surface: Used for non-overlay components (cards, accordions, disclosure groups) */
--surface: var(--white);
--surface-foreground: var(--foreground);
/* Overlay: Used for floating/overlay components (dialogs, popovers, modals, menus) */
--overlay: var(--white);
--overlay-foreground: var(--foreground);
--muted: oklch(55.2% 0.016 285.938);
--default: oklch(94% 0.001 286.375);
--default-foreground: var(--eclipse);
--accent: oklch(0.6204 0.195 253.83);
--accent-foreground: var(--snow);
/* Form Field Defaults - Colors */
--field-background: var(--white);
--field-foreground: oklch(0.2103 0.0059 285.89);
--field-placeholder: var(--muted);
--field-border: transparent; /* no border by default on form fields */
/* Status Colors */
--success: oklch(0.7329 0.1935 150.81);
--success-foreground: var(--eclipse);
--warning: oklch(0.7819 0.1585 72.33);
--warning-foreground: var(--eclipse);
--danger: oklch(0.6532 0.2328 25.74);
--danger-foreground: var(--snow);
/* Component Colors */
--segment: var(--white);
--segment-foreground: var(--eclipse);
/* Misc Colors */
--border: oklch(0 0 0 / 0%);
--divider: oklch(72% 0.004 286.32);
--link: var(--foreground);
}
@variant dark {
/* Base Colors */
--background: var(--black);
--foreground: var(--snow);
/* Surface: Used for non-overlay components (cards, accordions, disclosure groups) */
--surface: oklch(0.2103 0.0059 285.89);
--surface-foreground: var(--foreground);
/* Overlay: Used for floating/overlay components (dialogs, popovers, modals, menus) - lighter for contrast */
--overlay: oklch(
0.2563 0.0058 271.19
); /* Lighter than surface for visibility in dark mode */
--overlay-foreground: var(--foreground);
--muted: oklch(70.5% 0.015 286.067);
--default: oklch(27.4% 0.006 286.033);
--default-foreground: var(--snow);
--accent: oklch(0.6204 0.195 253.83);
--accent-foreground: var(--snow);
/* Form Field Defaults - Colors (only the ones that are different from light theme) */
--field-background: var(--default);
--field-foreground: var(--foreground);
--field-placeholder: var(--muted);
--field-border: transparent; /* no border by default on form fields */
/* Status Colors */
--success: oklch(0.7329 0.1935 150.81);
--success-foreground: var(--eclipse);
--warning: oklch(0.8203 0.1388 76.34);
--warning-foreground: var(--eclipse);
--danger: oklch(0.594 0.1967 24.63);
--danger-foreground: var(--snow);
/* Component Colors */
--segment: oklch(0.3964 0.01 285.93);
--segment-foreground: var(--foreground);
/* Misc Colors */
--border: oklch(1 0 0 / 0%);
--divider: oklch(38% 0.006 286.033);
--link: var(--foreground);
}
}
}
```
## Customizing Colors
**Override existing colors:**
```css
@layer theme {
@variant light {
/* Override default colors */
--accent: oklch(0.65 0.25 270); /* Custom indigo accent */
--success: oklch(0.65 0.15 155);
}
@variant dark {
/* Override dark theme colors */
--accent: oklch(0.65 0.25 270);
--success: oklch(0.75 0.12 155);
}
}
```
**Tip:** Convert colors at [oklch.com](https://oklch.com)
**Add your own colors:**
```css
@layer theme {
@variant light {
--info: oklch(0.6 0.15 210);
--info-foreground: oklch(0.98 0 0);
}
@variant dark {
--info: oklch(0.7 0.12 210);
--info-foreground: oklch(0.15 0 0);
}
}
@theme inline {
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
}
```
Now you can use it:
```tsx
import { View, Text } from 'react-native';
Info message
```
> **Note**: To learn more about theme variables and how they work in Tailwind CSS v4, see the [Tailwind CSS Theme documentation](https://tailwindcss.com/docs/theme).
## Quick Tips
* Always use color variables, not hard-coded values
* Use foreground/background pairs for good contrast
* Test in both light and dark modes
* The system respects user's theme preference automatically
## Related
* [Theming](/docs/native/getting-started/theming) - Learn about the theming system
* [Styling](/docs/native/getting-started/styling) - Styling components with CSS
* [Design Principles](/docs/native/getting-started/design-principles) - Understanding HeroUI's design philosophy
# Composition
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/composition
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(handbook)/composition.mdx
> Build flexible UI with component composition patterns
HeroUI Native uses composition patterns to create flexible, customizable components. Change the rendered element, compose components together, and maintain full control over markup.
## Compound Components
HeroUI Native components use a compound component pattern with dot notation—components export sub-components as properties (e.g., `Button.Label`, `Dialog.Trigger`, `Accordion.Item`) that work together to form complete UI elements.
```tsx
import { Button, Dialog } from 'heroui-native';
function DialogExample() {
return (
);
}
```
## The asChild Prop
The `asChild` prop lets you change what element a component renders. When `asChild` is true, HeroUI Native clones the child element and merges props instead of rendering its default element.
```tsx
import { Button, Dialog } from 'heroui-native';
function DialogExample() {
return (
);
}
```
## Custom Components
Create your own components by composing HeroUI Native primitives:
```tsx
import { Button, Card, Popover } from 'heroui-native';
import { View } from 'react-native';
// Product card component
function ProductCard({ title, description, price, onBuy, ...props }) {
return (
{price}{title}{description}
);
}
// Popover button component
function PopoverButton({ children, popoverContent, ...props }) {
return (
{popoverContent}
);
}
// Usage
console.log('Buy')}
/>
InformationAdditional details here
}>
Show Info
```
## Custom Variants
Create custom variants using `tailwind-variants` to extend component styling:
```tsx
import { Button } from 'heroui-native';
import type { ButtonRootProps } from 'heroui-native';
import { tv, type VariantProps } from 'tailwind-variants';
const customButtonVariants = tv({
base: 'font-semibold rounded-lg',
variants: {
intent: {
primary: 'bg-blue-500 text-white',
secondary: 'bg-gray-200',
danger: 'bg-red-500 text-white',
},
},
defaultVariants: {
intent: 'primary',
},
});
type CustomButtonVariants = VariantProps;
interface CustomButtonProps
extends Omit,
CustomButtonVariants {
className?: string;
}
export function CustomButton({
intent,
className,
children,
...props
}: CustomButtonProps) {
return (
);
}
```
## Next Steps
* Learn about [Styling](/docs/native/getting-started/styling) system
* Explore [Theming](/docs/native/getting-started/theming) documentation
* Explore [Animation](/docs/native/getting-started/animation) options
# Provider
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/provider
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(handbook)/provider.mdx
> Configure HeroUI Native provider with text, animation, and toast settings
The `HeroUINativeProvider` is the root provider component that configures and initializes HeroUI Native in your React Native application. It provides global configuration and portal management for your application.
## Overview
The provider serves as the main entry point for HeroUI Native, wrapping your application with essential contexts and configurations:
* **Text Configuration**: Global text component settings for consistency across all HeroUI components
* **Animation Configuration**: Global animation control to disable all animations across the application
* **Toast Configuration**: Global toast system configuration including insets, default props, and wrapper components
* **Portal Management**: Handles overlays, modals, and other components that render on top of the app hierarchy
## Basic Setup
Wrap your application root with the provider:
```tsx
import { HeroUINativeProvider } from 'heroui-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function App() {
return (
{/* Your app content */}
);
}
```
## Configuration Options
The provider accepts a `config` prop with the following options:
### Text Component Configuration
Global settings for all Text components within HeroUI Native. These props are carefully selected to include only those that make sense to configure globally across all Text components in the application:
```tsx
import { HeroUINativeProvider } from 'heroui-native';
import type { HeroUINativeConfig } from 'heroui-native';
const config: HeroUINativeConfig = {
textProps: {
// Disable font scaling for accessibility
allowFontScaling: false,
// Auto-adjust font size to fit container
adjustsFontSizeToFit: false,
// Maximum font size multiplier when scaling
maxFontSizeMultiplier: 1.5,
// Minimum font scale (iOS only, 0.01-1.0)
minimumFontScale: 0.5,
},
};
export default function App() {
return (
{/* Your app content */}
);
}
```
### Animation Configuration
Global animation configuration for the entire application:
```tsx
const config: HeroUINativeConfig = {
// Disable all animations across the application (cascades to all children)
animation: 'disable-all',
};
```
**Note**: When set to `'disable-all'`, all animations across the application will be disabled. This is useful for accessibility or performance optimization.
### Toast Configuration
Configure the global toast system including insets, default props, and wrapper components:
```tsx
import { KeyboardAvoidingView } from 'react-native';
const config: HeroUINativeConfig = {
toast: {
// Global toast configuration (used as defaults for all toasts)
defaultProps: {
variant: 'default',
placement: 'top',
isSwipeable: true,
animation: true,
},
// Insets for spacing from screen edges (added to safe area insets)
insets: {
top: 0, // Default: iOS = 0, Android = 12
bottom: 6, // Default: iOS = 6, Android = 12
left: 12, // Default: 12
right: 12, // Default: 12
},
// Maximum number of visible toasts before opacity starts fading
maxVisibleToasts: 3,
// Custom wrapper function to wrap the toast content
contentWrapper: (children) => (
{children}
),
},
};
```
## Complete Example
Here's a comprehensive example showing all configuration options:
```tsx
import { HeroUINativeProvider } from 'heroui-native';
import type { HeroUINativeConfig } from 'heroui-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
const config: HeroUINativeConfig = {
// Global text configuration
textProps: {
minimumFontScale: 0.5,
maxFontSizeMultiplier: 1.5,
allowFontScaling: true,
adjustsFontSizeToFit: false,
},
// Global animation configuration
animation: 'disable-all', // Optional: disable all animations
// Global toast configuration
toast: {
defaultProps: {
variant: 'default',
placement: 'top',
},
insets: {
top: 0,
bottom: 6,
left: 12,
right: 12,
},
maxVisibleToasts: 3,
},
};
export default function App() {
return (
);
}
```
## Integration with Expo Router
When using Expo Router, wrap your root layout:
```tsx
// app/_layout.tsx
import { HeroUINativeProvider } from 'heroui-native';
import type { HeroUINativeConfig } from 'heroui-native';
import { Stack } from 'expo-router';
const config: HeroUINativeConfig = {
textProps: {
minimumFontScale: 0.5,
maxFontSizeMultiplier: 1.5,
},
};
export default function RootLayout() {
return (
);
}
```
## Architecture
### Provider Hierarchy
The `HeroUINativeProvider` internally composes multiple providers:
```
HeroUINativeProvider
├── GlobalAnimationSettingsProvider (animation configuration)
│ └── TextComponentProvider (text configuration)
│ └── ToastProvider (toast configuration)
│ └── Your App
│ └── PortalHost (for overlays)
```
## Best Practices
### 1. Single Provider Instance
Always use a single `HeroUINativeProvider` at the root of your app. Don't nest multiple providers:
```tsx
// ❌ Bad
{/* Don't do this */}
// ✅ Good
```
### 2. Configuration Object
Define your configuration outside the component to prevent recreating on each render:
```tsx
// ❌ Bad
function App() {
return (
{/* ... */}
);
}
// ✅ Good
const config: HeroUINativeConfig = {
textProps: {
maxFontSizeMultiplier: 1.5,
},
};
function App() {
return (
{/* ... */}
);
}
```
### 3. Text Configuration
Consider accessibility when configuring text props:
```tsx
const config: HeroUINativeConfig = {
textProps: {
// Allow font scaling for accessibility
allowFontScaling: true,
// But limit maximum scale
maxFontSizeMultiplier: 1.5,
},
};
```
## TypeScript Support
The provider is fully typed. Import types for better IDE support:
```tsx
import { HeroUINativeProvider, type HeroUINativeConfig } from 'heroui-native';
const config: HeroUINativeConfig = {
// Full type safety and autocomplete
textProps: {
allowFontScaling: true,
maxFontSizeMultiplier: 1.5,
},
animation: 'disable-all', // Optional: disable all animations
toast: {
defaultProps: {
variant: 'default',
placement: 'top',
},
insets: {
top: 0,
bottom: 6,
left: 12,
right: 12,
},
},
};
```
## Related
* [Quick Start](/docs/native/getting-started/quick-start) - Basic setup guide
* [Theming](/docs/native/getting-started/theming) - Customize colors and themes
* [Styling](/docs/native/getting-started/styling) - Style components with Tailwind
# Styling
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/styling
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(handbook)/styling.mdx
> Style HeroUI Native components with Tailwind or StyleSheet API
HeroUI Native components provide flexible styling options: Tailwind CSS utilities, StyleSheet API, and render props for dynamic styling.
## Styling Principles
HeroUI Native is built with `className` as the go-to styling solution. You can use Tailwind CSS classes via the `className` prop on all components.
**StyleSheet precedence:** The `style` prop (StyleSheet API) can be used and has precedence over `className` when both are provided. This allows you to override Tailwind classes when needed.
**Animated styles:** Some style properties are animated using `react-native-reanimated` and, like StyleSheet styles, they have precedence over `className`. To identify which styles are animated and cannot be used via `className`:
* **Hover over `className` in your IDE** - The TypeScript definitions will show which properties are available
* **Check component documentation** - Each component page includes a link to the component's style source at the top, which contains notes about animated properties
**Customizing animated styles:** If styles are occupied by animation, you can modify them via the `animation` prop on components that support it.
## Basic Styling
**Using className:** All HeroUI Native components accept `className` props:
```tsx
import { Button } from 'heroui-native';
```
**Using style:** Components also accept inline styles via the `style` prop:
```tsx
import { Button } from 'heroui-native';
```
## Render Props
Use a render function to access component state and customize content dynamically:
```tsx
import { RadioGroup, cn } from 'heroui-native';
{({ isSelected, isInvalid, isDisabled }) => (
<>
Option 1
{isSelected && }
>
)}
```
## Creating Wrapper Components
Create reusable custom components using [tailwind-variants](https://tailwind-variants.org/)—a Tailwind CSS first-class variant API:
```tsx
import { Button } from 'heroui-native';
import type { ButtonRootProps } from 'heroui-native';
import { tv, type VariantProps } from 'tailwind-variants';
const customButtonVariants = tv({
base: 'font-semibold rounded-lg',
variants: {
intent: {
primary: 'bg-blue-500 text-white',
secondary: 'bg-gray-200',
danger: 'bg-red-500 text-white',
},
},
defaultVariants: {
intent: 'primary',
},
});
type CustomButtonVariants = VariantProps;
interface CustomButtonProps
extends Omit,
CustomButtonVariants {
className?: string;
}
export function CustomButton({
intent,
className,
children,
...props
}: CustomButtonProps) {
return (
);
}
```
## Responsive Design
HeroUI Native supports Tailwind's responsive breakpoint system via [Uniwind](https://docs.uniwind.dev/breakpoints). Use breakpoint prefixes like `sm:`, `md:`, `lg:`, and `xl:` to apply styles conditionally based on screen width.
**Mobile-first approach:** Start with mobile styles (no prefix), then use breakpoints to enhance for larger screens.
### Responsive Typography and Spacing
```tsx
import { Button } from 'heroui-native';
import { View, Text } from 'react-native';
Responsive Heading
```
### Responsive Layouts
```tsx
import { View, Text } from 'react-native';
{/* Mobile: 1 column, Tablet: 2 columns, Desktop: 3 columns */}
Item 1
```
**Default breakpoints:**
* `sm`: 640px
* `md`: 768px
* `lg`: 1024px
* `xl`: 1280px
* `2xl`: 1536px
For custom breakpoints and more details, see the [Uniwind breakpoints documentation](https://docs.uniwind.dev/breakpoints).
## Utilities
HeroUI Native provides utility functions to assist with styling components.
### cn Utility
The `cn` utility function merges Tailwind CSS classes with proper conflict resolution. It's particularly useful when combining conditional classes or merging classes from props:
```tsx
import { cn } from 'heroui-native';
import { View } from 'react-native';
function MyComponent({ className, isActive }) {
return (
);
}
```
The `cn` utility is powered by `tailwind-variants` and includes:
* Automatic Tailwind class merging (`twMerge: true`)
* Custom opacity class group support
* Proper conflict resolution (later classes override earlier ones)
**Example with conflicts:**
```tsx
// 'bg-accent' overrides 'bg-background'
cn('bg-background p-4', 'bg-accent');
// Result: 'p-4 bg-accent'
```
### useThemeColor Hook
Quick access to theme colors in hex format for use with the `style` prop:
```tsx
import { useThemeColor } from 'heroui-native';
import { View, Text } from 'react-native';
function MyComponent() {
const accentColor = useThemeColor('accent');
const dangerColor = useThemeColor('danger');
return (
Error message
);
}
```
**Type signature:**
```tsx
useThemeColor(themeColor: ThemeColor): string
```
Available theme colors include: `background`, `foreground`, `surface`, `accent`, `default`, `success`, `warning`, `danger`, and all their variants (hover, soft, etc.).
## Next Steps
* Learn about [Animation](/docs/native/getting-started/animation) techniques
* Explore [Theming](/docs/native/getting-started/theming) system
* Explore [Colors](/docs/native/getting-started/colors) documentation
# Theming
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/theming
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(handbook)/theming.mdx
> Customize HeroUI Native's design system with CSS variables and global styles
HeroUI Native uses CSS variables for theming. Customize everything from colors to component styles using standard CSS.
## How It Works
HeroUI Native's theming system is built on top of [Tailwind CSS v4](https://tailwindcss.com/docs/theme)'s theme via [Uniwind](https://uniwind.dev/). When you import `heroui-native/styles`, it uses Tailwind's built-in color palettes, maps them to semantic variables, automatically switches between light and dark themes, and uses CSS layers and the `@theme` directive for organization.
**Naming pattern:**
* Colors without a suffix are backgrounds (e.g., `--accent`)
* Colors with `-foreground` are for text on that background (e.g., `--accent-foreground`)
## Quick Start
**Apply colors in your components:**
```tsx
import { View, Text } from 'react-native';
Your app content
```
**Switch themes:**
HeroUI Native automatically supports dark mode through [Uniwind](https://docs.uniwind.dev/theming/basics). The theme switches between light and dark variants based on system preferences or manual selection:
```tsx
import { Uniwind, useUniwind } from 'uniwind';
import { Button } from 'heroui-native';
function ThemeToggle() {
const { theme } = useUniwind();
return (
);
}
```
**Override colors:**
```css
/* global.css */
@layer theme {
@variant light {
/* Override any color variable */
--accent: oklch(0.65 0.25 270); /* Custom indigo accent */
--success: oklch(0.65 0.15 155);
}
@variant dark {
--accent: oklch(0.65 0.25 270);
--success: oklch(0.75 0.12 155);
}
}
```
> **Note**: See [Colors](/docs/native/getting-started/colors) for the complete color palette and visual reference.
**Create your own theme:**
Create multiple themes using Uniwind's variant system. For complete custom theme documentation, see the [Uniwind Custom Themes Guide](https://docs.uniwind.dev/theming/custom-themes).
**Important:** All themes must define the same variables. See the [Default Theme](/docs/native/getting-started/colors#default-theme) section for a complete list of all required variables.
```css
/* global.css */
@layer theme {
:root {
@variant ocean-light {
/* Base Colors */
--background: oklch(0.95 0.02 230);
--foreground: oklch(0.25 0.04 230);
/* Surface: Used for non-overlay components (cards, accordions, disclosure groups) */
--surface: oklch(0.98 0.01 230);
--surface-foreground: oklch(0.3 0.045 230);
/* Overlay: Used for floating/overlay components (dialogs, popovers, modals, menus) */
--overlay: oklch(0.998 0.003 230);
--overlay-foreground: oklch(0.3 0.045 230);
--muted: oklch(0.55 0.035 230);
--default: oklch(0.94 0.018 230);
--default-foreground: oklch(0.4 0.05 230);
/* Accent */
--accent: oklch(0.6 0.2 230);
--accent-foreground: oklch(0.98 0.005 230);
/* Form Field Defaults - Colors */
--field-background: oklch(0.98 0.01 230);
--field-foreground: oklch(0.25 0.04 230);
--field-placeholder: var(--muted);
--field-border: transparent;
/* Status Colors */
--success: oklch(0.72 0.14 165);
--success-foreground: oklch(0.25 0.08 165);
--warning: oklch(0.78 0.12 85);
--warning-foreground: oklch(0.3 0.08 85);
--danger: oklch(0.68 0.18 15);
--danger-foreground: oklch(0.98 0.005 15);
/* Component Colors */
--segment: oklch(0.98 0.01 230);
--segment-foreground: oklch(0.25 0.04 230);
/* Misc Colors */
--border: oklch(0 0 0 / 0%);
--divider: oklch(0.91 0.015 230);
--link: oklch(0.62 0.17 230);
}
@variant ocean-dark {
/* Base Colors */
--background: oklch(0.15 0.04 230);
--foreground: oklch(0.94 0.01 230);
/* Surface: Used for non-overlay components (cards, accordions, disclosure groups) */
--surface: oklch(0.2 0.048 230);
--surface-foreground: oklch(0.9 0.015 230);
/* Overlay: Used for floating/overlay components (dialogs, popovers, modals, menus) */
--overlay: oklch(0.23 0.045 230);
--overlay-foreground: oklch(0.9 0.015 230);
--muted: oklch(0.5 0.04 230);
--default: oklch(0.25 0.05 230);
--default-foreground: oklch(0.88 0.018 230);
/* Accent */
--accent: oklch(0.72 0.21 230);
--accent-foreground: oklch(0.15 0.04 230);
/* Form Field Defaults - Colors */
--field-background: var(--default);
--field-foreground: var(--foreground);
--field-placeholder: var(--muted);
--field-border: transparent;
/* Status Colors */
--success: oklch(0.68 0.16 165);
--success-foreground: oklch(0.95 0.008 165);
--warning: oklch(0.75 0.14 90);
--warning-foreground: oklch(0.2 0.04 90);
--danger: oklch(0.65 0.2 20);
--danger-foreground: oklch(0.95 0.008 20);
/* Component Colors */
--segment: oklch(0.22 0.046 230);
--segment-foreground: oklch(0.9 0.015 230);
/* Misc Colors */
--border: oklch(0 0 0 / 0%);
--divider: oklch(0.28 0.045 230);
--link: oklch(0.75 0.18 230);
}
}
}
```
**Important:** When adding custom themes, you must register them in your Metro config:
```js
// metro.config.js
const { withUniwindConfig } = require('uniwind/metro');
const { wrapWithReanimatedMetroConfig } = require('react-native-reanimated/metro-config');
const config = {
// ... your existing config
};
module.exports = withUniwindConfig(wrapWithReanimatedMetroConfig(config), {
cssEntryFile: './global.css',
dtsFile: './src/uniwind.d.ts',
extraThemes: [
'ocean-light',
'ocean-dark',
],
});
```
Apply themes in your app:
```tsx
import { Uniwind } from 'uniwind';
import { Button } from 'heroui-native';
function App() {
return (
);
}
```
## Adding Custom Colors
Add your own semantic colors to the theme:
```css
@layer theme {
@variant light {
--info: oklch(0.6 0.15 210);
--info-foreground: oklch(0.98 0 0);
}
@variant dark {
--info: oklch(0.7 0.12 210);
--info-foreground: oklch(0.15 0 0);
}
}
/* Make the color available to Tailwind */
@theme inline {
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
}
```
Now use it in your components:
```tsx
import { View, Text } from 'react-native';
Info message
```
## Custom Fonts
To use a custom font family in your app, you need to load the fonts and then override the font CSS variables.
### 1. Load Fonts in Your App
First, load your custom fonts (using Expo's `useFonts` hook for example):
```tsx
import { useFonts } from 'expo-font';
import { HeroUINativeProvider } from 'heroui-native';
import { YourFont_400Regular, YourFont_500Medium, YourFont_600SemiBold } from '@expo-google-fonts/your-font';
export default function App() {
const [fontsLoaded] = useFonts({
YourFont_400Regular,
YourFont_500Medium,
YourFont_600SemiBold,
});
if (!fontsLoaded) {
return null; // Or return a loading screen
}
return (
{/* Your app content */}
);
}
```
### 2. Configure Font CSS Variables
After loading the fonts, override the font CSS variables in your `global.css` file:
```css
@theme {
--font-normal: 'YourFont-Regular';
--font-medium: 'YourFont-Medium';
--font-semibold: 'YourFont-SemiBold';
}
```
**Note:** The font names in CSS variables should match the PostScript names of your loaded fonts. Check your font package documentation or use the font names exactly as they appear in your `useFonts` hook.
All HeroUI Native components automatically use these font variables, ensuring consistent typography throughout your app.
## Variables Reference
HeroUI defines three types of variables:
1. **Base Variables** — Non-changing values like `--white`, `--black`
2. **Theme Variables** — Colors that change between light/dark themes
3. **Calculated Variables** — Automatically generated hover (pressed) states and size variants
For a complete reference, see: [Colors Documentation](/docs/native/getting-started/colors), [Default Theme Variables](https://github.com/heroui-inc/heroui-native/blob/beta/src/styles/variables.css), [Shared Theme Utilities](https://github.com/heroui-inc/heroui-native/blob/beta/src/styles/theme.css)
**Calculated variables (Tailwind):**
We use Tailwind's `@theme` directive to automatically create calculated variables for hover (pressed) states and radius variants. These are defined in [theme.css](https://github.com/heroui-inc/heroui-native/blob/beta/src/styles/theme.css):
```css
@theme inline static {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-surface: var(--surface);
--color-surface-foreground: var(--surface-foreground);
--color-overlay: var(--overlay);
--color-overlay-foreground: var(--overlay-foreground);
--color-muted: var(--muted);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-segment: var(--segment);
--color-segment-foreground: var(--segment-foreground);
--color-border: var(--border);
--color-divider: var(--divider);
--color-focus: var(--focus);
--color-link: var(--link);
--color-default: var(--default);
--color-default-foreground: var(--default-foreground);
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
--color-danger: var(--danger);
--color-danger-foreground: var(--danger-foreground);
/* Form Field Tokens */
--color-field: var(--field-background, var(--color-default));
--color-field-hover: color-mix(
in oklab,
var(--field-background, var(--color-default)) 90%,
var(--field-foreground, var(--color-default-foreground)) 10%
);
--color-field-foreground: var(--field-foreground, var(--color-foreground));
--color-field-placeholder: var(--field-placeholder, var(--color-muted));
--color-field-border: var(--field-border, var(--color-border));
--radius-field: var(--field-radius, var(--radius-xl));
--border-width-field: var(--field-border-width, var(--border-width));
/* Calculated Variables */
/* Colors */
/* --- background shades --- */
--color-background-secondary: color-mix(
in oklab,
var(--color-background) 96%,
var(--color-foreground) 4%
);
--color-background-tertiary: color-mix(
in oklab,
var(--color-background) 92%,
var(--color-foreground) 8%
);
--color-background-quaternary: color-mix(
in oklab,
var(--color-background) 86%,
var(--color-foreground) 14%
);
--color-background-inverse: var(--color-foreground);
/* ------------------------- */
--color-default-hover: color-mix(
in oklab,
var(--color-default) 90%,
var(--color-default-foreground) 2%
);
--color-accent-hover: color-mix(
in oklab,
var(--color-accent) 90%,
var(--color-accent-foreground) 10%
);
--color-success-hover: color-mix(
in oklab,
var(--color-success) 90%,
var(--color-success-foreground) 10%
);
--color-warning-hover: color-mix(
in oklab,
var(--color-warning) 90%,
var(--color-warning-foreground) 10%
);
--color-danger-hover: color-mix(
in oklab,
var(--color-danger) 90%,
var(--color-danger-foreground) 10%
);
/* Form Field Colors */
--color-field-hover: color-mix(
in oklab,
var(--color-field) 90%,
var(--color-field-foreground) 2%
);
--color-field-focus: var(--color-field);
--color-field-border-hover: color-mix(
in oklab,
var(--color-field-border) 88%,
var(--color-field-foreground) 10%
);
--color-field-border-focus: color-mix(
in oklab,
var(--color-field-border) 74%,
var(--color-field-foreground) 22%
);
/* Soft Colors */
--color-accent-soft: color-mix(
in oklab,
var(--color-accent) 15%,
transparent
);
--color-accent-soft-foreground: var(--color-accent);
--color-accent-soft-hover: color-mix(
in oklab,
var(--color-accent) 20%,
transparent
);
--color-danger-soft: color-mix(
in oklab,
var(--color-danger) 15%,
transparent
);
--color-danger-soft-foreground: var(--color-danger);
--color-danger-soft-hover: color-mix(
in oklab,
var(--color-danger) 20%,
transparent
);
--color-warning-soft: color-mix(
in oklab,
var(--color-warning) 15%,
transparent
);
--color-warning-soft-foreground: var(--color-warning);
--color-warning-soft-hover: color-mix(
in oklab,
var(--color-warning) 20%,
transparent
);
--color-success-soft: color-mix(
in oklab,
var(--color-success) 15%,
transparent
);
--color-success-soft-foreground: var(--color-success);
--color-success-soft-hover: color-mix(
in oklab,
var(--color-success) 20%,
transparent
);
/* Surface Levels - progressively darker/lighter shades for layering */
--color-surface-secondary: color-mix(
in oklab,
var(--surface) 94%,
var(--surface-foreground) 6%
);
--color-surface-tertiary: color-mix(
in oklab,
var(--surface) 92%,
var(--surface-foreground) 8%
);
--color-surface-quaternary: color-mix(
in oklab,
var(--surface) 86%,
var(--default-foreground) 14%
);
/* On Surface Colors */
--color-on-surface: color-mix(
in oklab,
var(--color-surface) 93%,
var(--color-surface-foreground) 7%
);
--color-on-surface-foreground: var(--color-surface-foreground);
--color-on-surface-hover: color-mix(
in oklab,
var(--color-surface) 91%,
var(--color-surface-foreground) 9%
);
--color-on-surface-focus: var(--color-on-surface);
/* Radius and default sizes - defaults can change by just changing the --radius */
--radius-xs: calc(var(--radius) * 0.25); /* 0.125rem (2px) */
--radius-sm: calc(var(--radius) * 0.5); /* 0.25rem (4px) */
--radius-md: calc(var(--radius) * 0.75); /* 0.375rem (6px) */
--radius-lg: calc(var(--radius) * 1); /* 0.5rem (8px) */
--radius-xl: calc(var(--radius) * 1.5); /* 0.75rem (12px) */
--radius-2xl: calc(var(--radius) * 2); /* 1rem (16px) */
--radius-3xl: calc(var(--radius) * 3); /* 1.5rem (24px) */
--radius-4xl: calc(var(--radius) * 4); /* 2rem (32px) */
}
```
Form controls now rely on the `--field-*` variables and their calculated hover/focus variants. Update them in your theme to restyle inputs, checkboxes, radios, and OTP slots without impacting surfaces like buttons or cards.
## Resources
* [Colors Documentation](/docs/native/getting-started/colors)
* [Styling Guide](/docs/native/getting-started/styling)
* [Tailwind CSS v4 Theming](https://tailwindcss.com/docs/theme)
* [OKLCH Color Tool](https://oklch.com)
# Design Principles
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/design-principles
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(overview)/design-principles.mdx
> Core principles that guide HeroUI v3's design and development
HeroUI Native follows 9 core principles that prioritize clarity, accessibility, customization, and developer experience.
## Core Principles
### 1. Semantic Intent Over Visual Style
Use semantic naming (primary, secondary, tertiary) instead of visual descriptions (solid, flat, bordered). Inspired by [Uber's Base design system](https://base.uber.com/6d2425e9f/p/756216-button), variants follow a clear hierarchy:
```tsx
// ✅ Semantic variants communicate hierarchy
```
| Variant | Purpose | Usage |
| ------------- | --------------------------------- | ---------------- |
| **Primary** | Main action to move forward | 1 per context |
| **Secondary** | Alternative actions | Multiple allowed |
| **Tertiary** | Dismissive actions (cancel, skip) | Sparingly |
| **Danger** | Destructive actions | When needed |
### 2. Accessibility as Foundation
Accessibility follows mobile development best practices with proper touch accessibility, focus management, and screen reader support built into every component. All components include proper accessibility labels and semantic structure for VoiceOver (iOS) and TalkBack (Android).
```tsx
import { Tabs } from 'heroui-native';
ProfileSecurityContentContent
```
### 3. Composition Over Configuration
Compound components let you rearrange, customize, or omit parts as needed. Use dot notation to compose components exactly as you need them.
```tsx
// Compose parts to build exactly what you need
import { Accordion } from 'heroui-native';
Question Text
Answer content
```
### 4. Progressive Disclosure
Start simple, add complexity only when needed. Components work with minimal props and scale up as requirements grow.
```tsx
import { Button, Icon, Spinner } from 'heroui-native';
// Level 1: Minimal
// Level 2: Enhanced
// Level 3: Advanced
```
### 5. Predictable Behavior
Consistent patterns across all components: sizes (`sm`, `md`, `lg`), variants, and className support. Same API, same behavior.
```tsx
import { Button, Chip, Avatar } from 'heroui-native';
// All components follow the same patterns
SuccessJD
```
### 6. Type Safety First
Full TypeScript support with IntelliSense, auto-completion, and compile-time error detection. Extend types for custom components.
```tsx
import type { ButtonRootProps } from 'heroui-native';
// Type-safe props and event handlers
// Extend types for custom components
interface CustomButtonProps extends Omit {
intent: 'save' | 'cancel' | 'delete';
}
```
### 7. Developer Experience Excellence
Clear APIs, descriptive errors, IntelliSense and AI-friendly markdown docs.
### 8. Complete Customization
Beautiful defaults out-of-the-box. Transform the entire look with CSS variables through [Uniwind's theming system](https://docs.uniwind.dev/theming/basics). Every slot is customizable.
```css
/* Custom colors using Uniwind's theme layer */
@layer theme {
@variant light {
--accent: oklch(0.65 0.25 270); /* Custom indigo accent */
--background: oklch(0.98 0 0); /* Custom background */
}
@variant dark {
--accent: oklch(0.65 0.25 270);
--background: oklch(0.15 0 0);
}
}
/* Radius customization */
@theme {
--radius: 0.75rem; /* Increase for rounder components */
}
```
### 9. Open and Extensible
Wrap, extend, and customize components to match your needs. Create custom wrappers or apply custom styles using className.
```tsx
import { Button } from 'heroui-native';
import type { ButtonRootProps } from 'heroui-native';
// Custom wrapper component
interface CTAButtonProps extends Omit {
intent?: 'primary-cta' | 'secondary-cta' | 'minimal';
}
const CTAButton = ({
intent = 'primary-cta',
children,
...props
}: CTAButtonProps) => {
const variantMap = {
'primary-cta': 'primary',
'secondary-cta': 'secondary',
'minimal': 'ghost'
} as const;
return (
);
};
// Usage
Get StartedLearn More
```
**Extend with Tailwind Variants:**
```tsx
import { Button } from 'heroui-native';
import { tv } from 'tailwind-variants';
// Extend button styles with custom variants
const myButtonVariants = tv({
base: 'px-4 py-2 rounded-lg',
variants: {
variant: {
'primary-cta': 'bg-accent text-accent-foreground px-8 py-4 shadow-lg',
'secondary-cta': 'border-2 border-accent text-accent px-6 py-3',
}
},
defaultVariants: {
variant: 'primary-cta',
}
});
// Use the custom variants
function CustomButton({ variant, className, ...props }) {
return (
);
}
// Usage
Get StartedLearn More
```
# Quick Start
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/quick-start
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(overview)/quick-start.mdx
> Get started with HeroUI Native in minutes
## Getting Started
### 1. Install HeroUI Native
```bash
npm install heroui-native
```
```bash
pnpm add heroui-native
```
```bash
yarn add heroui-native
```
```bash
bun add heroui-native
```
### 2. Install Mandatory Peer Dependencies
```bash
npm install react-native-screens@~4.16.0 react-native-reanimated@~4.1.1 react-native-gesture-handler@^2.28.0 react-native-worklets@0.5.1 react-native-safe-area-context@~5.6.0 react-native-svg@15.12.1 tailwind-variants@^3.2.2 tailwind-merge@^3.4.0 @gorhom/bottom-sheet@^5
```
```bash
pnpm add react-native-screens@~4.16.0 react-native-reanimated@~4.1.1 react-native-gesture-handler@^2.28.0 react-native-worklets@0.5.1 react-native-safe-area-context@~5.6.0 react-native-svg@15.12.1 tailwind-variants@^3.2.2 tailwind-merge@^3.4.0 @gorhom/bottom-sheet@^5
```
```bash
yarn add react-native-screens@~4.16.0 react-native-reanimated@~4.1.1 react-native-gesture-handler@^2.28.0 react-native-worklets@0.5.1 react-native-safe-area-context@~5.6.0 react-native-svg@15.12.1 tailwind-variants@^3.2.2 tailwind-merge@^3.4.0 @gorhom/bottom-sheet@^5
```
```bash
bun add react-native-screens@~4.16.0 react-native-reanimated@~4.1.1 react-native-gesture-handler@^2.28.0 react-native-worklets@0.5.1 react-native-safe-area-context@~5.6.0 react-native-svg@15.12.1 tailwind-variants@^3.2.2 tailwind-merge@^3.4.0 @gorhom/bottom-sheet@^5
```
It's recommended to use the exact versions specified above to avoid compatibility issues. Version mismatches may cause unexpected bugs.
### 3. Set Up Uniwind
Follow the [Uniwind installation guide](https://docs.uniwind.dev/quickstart) to set up Tailwind CSS for React Native.
If you're migrating from NativeWind, see the [migration guide](https://docs.uniwind.dev/migration-from-nativewind).
### 4. Configure global.css
Inside your `global.css` file add the following imports:
```css
@import 'tailwindcss';
@import 'uniwind';
@import 'heroui-native/styles';
/* Path to the heroui-native lib inside node_modules from the root of your project */
@source './node_modules/heroui-native/lib';
```
### 5. Wrap Your App with Provider
Wrap your application with `HeroUINativeProvider`. You must wrap it with `GestureHandlerRootView`:
```tsx
import { HeroUINativeProvider } from 'heroui-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
export default function App() {
return (
{/* Your app content */}
);
}
```
> **Note**: For advanced configuration options including text props, animation settings, and toast configuration, see the [Provider documentation](/docs/native/getting-started/provider).
### 6. Use Your First Component
```tsx
import { Button } from 'heroui-native';
import { View } from 'react-native';
export default function MyComponent() {
return (
);
}
```
## What's Next?
* [HeroUI Native Provider](/docs/native/getting-started/provider)
* [Styling Guide](/docs/native/getting-started/styling)
* [Theming Documentation](/docs/native/getting-started/theming)
## Running on Web (Expo)
HeroUI Native is currently not recommended for web use. We are focusing on mobile platforms (iOS and Android) at this time.
# LLMs.txt
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/llms-txt
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(ui-for-agents)/llms-txt.mdx
> Enable AI assistants like Claude, Cursor, and Windsurf to understand HeroUI Native
We provide [LLMs.txt](https://llmstxt.org/) files to make HeroUI Native documentation accessible to AI coding assistants.
## Available Files
**Core documentation:**
* [/native/llms.txt](/native/llms.txt) — Quick reference index for Native documentation
* [/native/llms-full.txt](/native/llms-full.txt) — Complete HeroUI Native documentation
**For limited context windows:**
* [/native/llms-components.txt](/native/llms-components.txt) — Component documentation only
* [/native/llms-patterns.txt](/native/llms-patterns.txt) — Common patterns and recipes
**All platforms:**
* [/llms.txt](/llms.txt) — Quick reference index (React + Native)
* [/llms-full.txt](/llms-full.txt) — Complete documentation (React + Native)
* [/llms-components.txt](/llms-components.txt) — All component documentation
* [/llms-patterns.txt](/llms-patterns.txt) — All patterns and recipes
## Integration
**Claude Code:** Tell Claude to reference the documentation:
```
Use HeroUI Native documentation from https://v3.heroui.com/native/llms.txt
```
Or add to your project's `.claude` file for automatic loading.
**Cursor:** Use the `@Docs` feature:
```
@Docs https://v3.heroui.com/native/llms-full.txt
```
[Learn more](https://docs.cursor.com/context/@-symbols/@-docs)
**Windsurf:** Add to your `.windsurfrules` file:
```
#docs https://v3.heroui.com/native/llms-full.txt
```
[Learn more](https://docs.codeium.com/windsurf/memories#memories-and-rules)
**Other AI tools:** Most AI assistants can reference documentation by URL. Simply provide:
```
https://v3.heroui.com/native/llms.txt
```
**For component-specific documentation:**
```
https://v3.heroui.com/native/llms-components.txt
```
**For patterns and best practices:**
```
https://v3.heroui.com/native/llms-patterns.txt
```
## Contributing
Found an issue with AI-generated code? Help us improve our LLMs.txt files on [GitHub](https://github.com/heroui-inc/heroui).
# MCP Server
**Category**: native
**URL**: https://v3.heroui.com/docs/native/getting-started/mcp-server
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/native/getting-started/(ui-for-agents)/mcp-server.mdx
> Access HeroUI Native documentation directly in your AI assistant
The HeroUI MCP Server gives AI assistants direct access to HeroUI Native component documentation, making it easier to build with HeroUI in AI-powered development environments.
The MCP server currently supports **heroui-native** and [stdio transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio). Published at `@heroui/native-mcp` on npm. View the source code on [GitHub](https://github.com/heroui-inc/heroui-mcp).
As we add more components to HeroUI Native, they'll be available in the MCP server too.
## Quick Setup
**Cursor:**
Or manually add to **Cursor Settings** → **Tools** → **MCP Servers**:
```json title=".cursor/mcp.json"
{
"mcpServers": {
"heroui-native": {
"command": "npx",
"args": ["-y", "@heroui/native-mcp@latest"]
}
}
}
```
Alternatively, add the following to your `~/.cursor/mcp.json` file. To learn more, see the [Cursor documentation](https://cursor.com/docs/context/mcp).
**Claude Code:** Run this command in your terminal:
```bash
claude mcp add heroui-native -- npx -y @heroui/native-mcp@latest
```
Or manually add to your project's `.mcp.json` file:
```json title=".mcp.json"
{
"mcpServers": {
"heroui-native": {
"command": "npx",
"args": ["-y", "@heroui/native-mcp@latest"]
}
}
}
```
After adding the configuration, restart Claude Code and run `/mcp` to see the HeroUI MCP server in the list. If you see **Connected**, you're ready to use it.
See the [Claude Code MCP documentation](https://docs.claude.com/en/docs/claude-code/mcp) for more details.
**Windsurf:** Add the HeroUI server to your project's `.windsurf/mcp.json` configuration file:
```json title=".windsurf/mcp.json"
{
"mcpServers": {
"heroui-native": {
"command": "npx",
"args": ["-y", "@heroui/native-mcp@latest"]
}
}
}
```
After adding the configuration, restart Windsurf to activate the MCP server.
See the [Windsurf MCP documentation](https://docs.windsurf.com/windsurf/cascade/mcp) for more details.
**VS Code:** To configure MCP in VS Code with GitHub Copilot, add the HeroUI server to your project's `.vscode/mcp.json` configuration file:
```json title=".vscode/mcp.json"
{
"mcpServers": {
"heroui-native": {
"command": "npx",
"args": ["-y", "@heroui/native-mcp@latest"]
}
}
}
```
After adding the configuration, open `.vscode/mcp.json` and click **Start** next to the heroui-native server.
See the [VS Code MCP documentation](https://code.visualstudio.com/docs/copilot/customization/mcp-servers) for more details.
## Usage
Once configured, ask your AI assistant questions like:
* "Help me install HeroUI Native in my Expo app"
* "Show me all HeroUI Native components"
* "What props does the Button component have?"
* "Give me an example of using the Card component"
* "Get the source code for the Button component"
* "Show me the default styles for Card"
* "What are the theme variables for dark mode?"
### Automatic Updates
The MCP server can help you upgrade to the latest HeroUI Native version:
```bash
"Hey Cursor, update HeroUI Native to the latest version"
```
Your AI assistant will automatically:
* Compare your current version with the latest release
* Review the changelog for breaking changes
* Apply the necessary code updates to your project
This works for any version upgrade, whether you're updating to the latest alpha, beta, or stable release.
## Available Tools
The MCP server provides these tools to AI assistants:
| Tool | Description |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------ |
| `installation` | Get complete installation instructions for your specific framework (Expo or Bare React Native) and package manager |
| `list_components` | List all available HeroUI Native components |
| `get_component_info` | Get detailed documentation, anatomy, props, and examples for specific components |
| `get_component_props` | Get detailed props information for HeroUI Native components |
| `get_component_examples` | Get usage examples for HeroUI Native components |
| `get_theme_info` | Access theme variables for colors, typography, spacing with light/dark mode support |
| `get_docs` | Browse the full HeroUI Native documentation including guides and principles |
## Troubleshooting
**Requirements:** Node.js 18 or higher. The package will be automatically downloaded when using `npx`.
**Need help?** [GitHub Issues](https://github.com/heroui-inc/heroui-mcp/issues) | [Discord Community](https://discord.gg/heroui)
## Links
* [npm Package](https://www.npmjs.com/package/@heroui/native-mcp)
* [GitHub Repository](https://github.com/heroui-inc/heroui-mcp)
* [Contributing Guide](https://github.com/heroui-inc/heroui-mcp/blob/main/CONTRIBUTING.md)
# Animation
**Category**: react
**URL**: https://v3.heroui.com/docs/react/getting-started/animation
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(handbook)/animation.mdx
> Add smooth animations and transitions to HeroUI v3 components
HeroUI components support multiple animation approaches: built-in CSS transitions, custom CSS animations, and JavaScript libraries like Framer Motion.
## Built-in Animations
HeroUI components use data attributes to expose their state for animation:
```css
/* Popover entrance/exit */
.popover[data-entering] {
@apply animate-in zoom-in-90 fade-in-0 duration-200;
}
.popover[data-exiting] {
@apply animate-out zoom-out-95 fade-out duration-150;
}
/* Button press effect */
.button:active,
.button[data-pressed="true"] {
transform: scale(0.97);
}
/* Accordion expansion */
.accordion__panel[aria-hidden="false"] {
@apply h-[var(--panel-height)] opacity-100;
}
```
**State attributes for styling:**
* `[data-hovered="true"]` - Hover state
* `[data-pressed="true"]` - Active/pressed state
* `[data-focus-visible="true"]` - Keyboard focus
* `[data-disabled="true"]` - Disabled state
* `[data-entering]` / `[data-exiting]` - Transition states
* `[aria-expanded="true"]` - Expanded state
## CSS Animations
**Using Tailwind utilities:**
```tsx
// Pulse on hover
// Fade in entrance
Welcome message
// Staggered list
);
}
```
## Render Props
Apply dynamic animations based on component state:
```tsx
```
## Accessibility
**Respecting motion preferences:** HeroUI automatically respects user motion preferences using Tailwind's `motion-reduce:` utility. All built-in transitions and animations are disabled when users enable "reduce motion" in their system settings.
HeroUI extends Tailwind's `motion-reduce:` variant to support both the native `prefers-reduced-motion` media query and the `data-reduce-motion` attribute.
```css
/* HeroUI pattern - uses Tailwind's motion-reduce: */
.button {
@apply transition-colors motion-reduce:transition-none;
}
/* Expands to support both approaches: */
@media (prefers-reduced-motion: reduce) {
.button {
transition: none;
}
}
[data-reduce-motion="true"] .button {
transition: none;
}
```
With Framer Motion:
```tsx
import { useReducedMotion } from 'framer-motion';
function AnimatedCard() {
const shouldReduceMotion = useReducedMotion();
return (
Content
);
}
```
**Disabling animations globally:** Add `data-reduce-motion="true"` to the `` or `` tag:
```html
```
HeroUI automatically detects the user's `prefers-reduced-motion: reduce` setting and disables animations accordingly.
## Performance Tips
**Use GPU-accelerated properties:** Prefer `transform` and `opacity` for smooth animations:
```css
/* Good - GPU accelerated */
.slide-in {
transform: translateX(-100%);
transition: transform 0.3s;
}
/* Avoid - Triggers layout */
.slide-in {
left: -100%;
transition: left 0.3s;
}
```
**Will-change optimization:** Use `will-change` to optimize animations, but remove it when not animating:
```css
.button {
will-change: transform;
}
.button:not(:hover) {
will-change: auto;
}
```
## Next Steps
* Learn about [Styling](/docs/handbook/styling) approaches
* Explore [Component](/docs/react/components) examples
* View [Theming](/docs/handbook/theming) documentation
# Colors
**Category**: react
**URL**: https://v3.heroui.com/docs/react/getting-started/colors
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(handbook)/colors.mdx
> Color palette and theming system for HeroUI v3
import {ColorSwatch, ColorPalette} from "@/components/color-swatch";
HeroUI uses CSS variables for colors that automatically switch between light and dark themes. All colors use the `oklch` color space for better color transitions.
## How It Works
HeroUI's color system is built on top of Tailwind CSS v4's theme. When you import `@heroui/styles`, it uses Tailwind's built-in color palettes and maps them to semantic variables.
**Naming pattern:**
* Colors without a suffix are backgrounds (e.g., `--accent`)
* Colors with `-foreground` are for text on that background (e.g., `--accent-foreground`)
**Usage:**
```html
```
```tsx
// This gives you the right background and text colors
Hello
```
### Base Colors
These four colors stay the same in all themes:
### Background & Surface
### Primary Colors
**Accent** — Your main brand color (used for primary actions)\
**Accent Soft** — A lighter version for secondary actions
### Status Colors
For alerts, validation, and status messages:
### Form Field Colors
For consistent form field styling across input components:
### Other Colors
## How to Use Colors
**In your components:**
```jsx
```
**In CSS files:**
```css title="global.css"
/* Direct CSS variables */
.my-component {
background: var(--accent);
color: var(--accent-foreground);
border: 1px solid var(--border);
}
/* With @apply and @layer */
@layer components {
.button {
@apply bg-accent text-accent-foreground;
&:hover,
&[data-hovered="true"] {
@apply bg-accent-hover;
}
&:active,
&[data-pressed="true"] {
@apply bg-accent-hover;
transform: scale(0.97);
}
}
}
```
## Default Theme
The complete theme definition can be found in ([variables.css](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/default/variables.css)). This theme automatically switches between light and dark modes based on the `class="dark"` or `data-theme="dark"` attributes.
```css
@layer base {
/* HeroUI Default Theme */
:root {
color-scheme: light;
/* == Common Variables == */
/* Primitive Colors (Do not change between light and dark) */
--white: oklch(100% 0 0);
--black: oklch(0% 0 0);
--snow: oklch(0.9911 0 0);
--eclipse: oklch(0.2103 0.0059 285.89);
/* Spacing scale */
--spacing: 0.25rem;
/* Border */
--border-width: 0px; /* no border by default */
--field-border-width: var(--border-width);
--disabled-opacity: 0.5;
/* Ring offset - Used for focus ring */
--ring-offset-width: 2px;
/* Cursor */
--cursor-interactive: pointer;
--cursor-disabled: not-allowed;
/* Radius */
--radius: 0.5rem;
--field-radius: calc(var(--radius) * 1.5);
/* == Light Theme Variables == */
/* Base Colors */
--background: oklch(0.9702 0 0);
--foreground: var(--eclipse);
/* Surface: Used for non-overlay components (cards, accordions, disclosure groups) */
--surface: var(--white);
--surface-foreground: var(--foreground);
/* Overlay: Used for floating/overlay components (tooltips, popovers, modals, menus) */
--overlay: var(--white);
--overlay-foreground: var(--foreground);
--muted: oklch(0.5517 0.0138 285.94);
--scrollbar: oklch(87.1% 0.006 286.286);
--default: oklch(94% 0.001 286.375);
--default-foreground: var(--eclipse);
--accent: oklch(0.6204 0.195 253.83);
--accent-foreground: var(--snow);
/* Form Field Defaults - Colors */
--field-background: var(--white);
--field-foreground: oklch(0.2103 0.0059 285.89);
--field-placeholder: var(--muted);
--field-border: transparent; /* no border by default on form fields */
/* Status Colors */
--success: oklch(0.7329 0.1935 150.81);
--success-foreground: var(--eclipse);
--warning: oklch(0.7819 0.1585 72.33);
--warning-foreground: var(--eclipse);
--danger: oklch(0.6532 0.2328 25.74);
--danger-foreground: var(--snow);
/* Component Colors */
--segment: var(--white);
--segment-foreground: var(--eclipse);
/* Misc Colors */
--border: oklch(0 0 0 / 0%);
--separator: oklch(92% 0.004 286.32);
--focus: var(--accent);
--link: var(--foreground);
/* Shadows */
--surface-shadow:
0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06),
0 0 1px 0 rgba(0, 0, 0, 0.06);
/* Overlay shadow */
--overlay-shadow: 0 4px 16px 0 rgba(24, 24, 27, 0.08), 0 8px 24px 0 rgba(24, 24, 27, 0.09);
--field-shadow:
0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06),
0 0 1px 0 rgba(0, 0, 0, 0.06);
/* Skeleton Default Global Animation */
--skeleton-animation: shimmer; /* shimmer, pulse, none */
}
.dark,
[data-theme="dark"] {
color-scheme: dark;
/* == Dark Theme Variables == */
/* Base Colors */
--background: oklch(12% 0.005 285.823);
--foreground: var(--snow);
/* Surface: Used for non-overlay components (cards, accordions, disclosure groups) */
--surface: oklch(0.2103 0.0059 285.89);
--surface-foreground: var(--foreground);
/* Overlay: Used for floating/overlay components (tooltips, popovers, modals, menus) - lighter for contrast */
--overlay: oklch(0.22 0.0059 285.89); /* A bit lighter than surface for visibility in dark mode */
--overlay-foreground: var(--foreground);
--muted: oklch(70.5% 0.015 286.067);
--scrollbar: oklch(70.5% 0.015 286.067);
--default: oklch(27.4% 0.006 286.033);
--default-foreground: var(--snow);
/* Form Field Defaults - Colors (only the ones that are different from light theme) */
--field-background: var(--default);
--field-foreground: var(--foreground);
/* Status Colors */
--warning: oklch(0.8203 0.1388 76.34);
--warning-foreground: var(--eclipse);
--danger: oklch(0.594 0.1967 24.63);
--danger-foreground: var(--snow);
/* Component Colors */
--segment: oklch(0.3964 0.01 285.93);
--segment-foreground: var(--foreground);
/* Misc Colors */
--border: oklch(1 0 0 / 0%);
--separator: oklch(22% 0.006 286.033);
--focus: var(--accent);
--link: var(--foreground);
/* Shadows */
--surface-shadow: 0 0 0 0 transparent inset; /* No shadow on dark mode */
--overlay-shadow: 0 0 0 0 transparent inset; /* No shadow on dark mode */
--field-shadow: 0 0 0 0 transparent inset; /* Transparent shadow to allow ring utilities to work */
}
}
```
## Customizing Colors
**Override existing colors:**
```css
:root {
/* Override default colors */
--accent: oklch(0.7 0.15 250);
--success: oklch(0.65 0.15 155);
}
[data-theme="dark"] {
/* Override dark theme colors */
--accent: oklch(0.8 0.12 250);
--success: oklch(0.75 0.12 155);
}
```
**Tip:** Convert colors at [oklch.com](https://oklch.com)
**Add your own colors:**
```css
:root,
[data-theme="light"] {
--info: oklch(0.6 0.15 210);
--info-foreground: oklch(0.98 0 0);
}
.dark,
[data-theme="dark"] {
--info: oklch(0.7 0.12 210);
--info-foreground: oklch(0.15 0 0);
}
/* Make the color available to Tailwind */
@theme inline {
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
}
```
Now you can use it:
```tsx
Info message
```
> **Note**: To learn more about theme variables and how they work in Tailwind CSS v4, see the [Tailwind CSS Theme documentation](https://tailwindcss.com/docs/theme).
## Quick Tips
* Always use color variables, not hard-coded values
* Use foreground/background pairs for good contrast
* Test in both light and dark modes
* The system respects user's theme preference automatically
## Related
* [Theming](/docs/handbook/theming) - Learn about the theming system
* [Styling](/docs/handbook/styling) - Styling components with CSS
* [Design Principles](/docs/getting-started/design-principles) - Understanding HeroUI's design philosophy
# Composition
**Category**: react
**URL**: https://v3.heroui.com/docs/react/getting-started/composition
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(handbook)/composition.mdx
> Build flexible UI with component composition patterns
HeroUI uses composition patterns to create flexible, customizable components. Change the rendered element, compose components together, and maintain full control over markup.
## Polymorphic Styling
Apply HeroUI styles to any element using variant functions or BEM classes. Extend component styles to framework components, native HTML elements, or custom components with full type safety.
**Example: Styling a Link as a Button**
You can use `buttonVariants` to style a Link component with button styles:
```tsx
import { buttonVariants } from '@heroui/react';
import Link from 'next/link';
// Style a Next.js Link as a primary button
About
// Style a native anchor as a secondary button with custom size
External Link
```
**Using BEM classes directly:**
```tsx
import Link from 'next/link';
// Apply button styles directly using BEM classes
About
```
**Working with Compound Components**
When using a custom root element instead of HeroUI's Root component, child components cannot access context slots. You can manually pass `className` to child components using variant functions or BEM classes:
```tsx
import { Link, linkVariants } from '@heroui/react';
import NextLink from 'next/link';
// With custom root - pass className manually
const slots = linkVariants({ underline: "hover" });
About Page
About Page
```
This approach works because HeroUI's variant functions and BEM classes can be applied to any element, giving you complete flexibility to style framework components, native elements, or custom components with HeroUI's design system.
## Direct Class Application
The simplest way to style links or other elements is to apply HeroUI's [BEM](https://getbem.com/) classes directly. This approach is straightforward and works with any framework or vanilla HTML.
**With Next.js Link:**
```tsx
import Link from 'next/link';
Return Home
```
**With native anchor:**
```tsx
Go to Dashboard
```
**Available button classes:**
* `.button` — Base button styles
* `.button--primary`, `.button--secondary`, `.button--tertiary`, `.button--danger`, `.button--ghost` — Variants
* `.button--sm`, `.button--md`, `.button--lg` — Sizes
* `.button--icon-only` — Icon-only button
This approach works because HeroUI uses [BEM](https://getbem.com/) classes that can be applied to any element. It's perfect when you don't need the component's interactive features (like `onPress` handlers) and just want the visual styling.
## Using Variant Functions
For more control and type safety, use variant functions to apply HeroUI styles to framework-specific components or custom elements.
**With Next.js Link:**
```tsx
import { Link, linkVariants } from '@heroui/react';
import NextLink from 'next/link';
const slots = linkVariants({ underline: "hover" });
About Page
```
**With Button styles:**
```tsx
import { buttonVariants } from '@heroui/react';
import Link from 'next/link';
Dashboard
```
**Available variant functions:** Each component exports its variant function (`buttonVariants`, `chipVariants`, `linkVariants`, `spinnerVariants`, and more). Use them to apply HeroUI's design system to any element while maintaining type safety.
## Compound Components
HeroUI components are built as compound components—they export multiple parts that work together. Use them in three flexible ways:
**Option 1: Compound pattern (recommended)** — Use the main component directly without `.Root` suffix:
```tsx
import { Alert } from '@heroui/react';
SuccessYour changes have been saved.
```
**Option 2: Compound pattern with .Root** — Use the `.Root` suffix if you prefer explicit naming:
```tsx
import { Alert } from '@heroui/react';
SuccessYour changes have been saved.
```
**Option 3: Named exports** — Import each part separately:
```tsx
import {
AlertRoot,
AlertIcon,
AlertContent,
AlertTitle,
AlertDescription,
AlertClose
} from '@heroui/react';
SuccessYour changes have been saved.
```
**Mixed syntax:** Mix compound and named exports in the same component:
```tsx
import { Alert, AlertTitle, AlertDescription } from '@heroui/react';
SuccessYour changes have been saved.
```
**Simple components:** Simple components like `Button` work the same way—no `.Root` needed:
```tsx
import { Button } from '@heroui/react';
// Recommended - no .Root needed
// Or with .Root
Click me
// Or named export
import { ButtonRoot } from '@heroui/react';
Click me
```
**Benefits:** All three patterns provide flexibility, customization, control, and consistency. Choose the pattern that fits your codebase.
## Mixing Variant Functions
You can combine variant functions from different components to create unique styles:
```tsx
import { Link, linkVariants, buttonVariants } from '@heroui/react';
// Link styled with button variants
const linkSlots = linkVariants({ underline: "hover" });
const buttonStyles = buttonVariants({ variant: "tertiary", size: "md" });
HeroUI
```
## Custom Components
Create your own components by composing HeroUI primitives:
```tsx
import { Button, Tooltip, buttonVariants } from '@heroui/react';
// Link button component using variant functions
function LinkButton({ href, children, variant = "primary", ...props }) {
return (
{children}
);
}
// Icon button with tooltip
function IconButton({ icon, label, ...props }) {
return (
{label}
);
}
```
## Custom Variants
Create custom variants by extending the component's variant function:
```tsx
import type { ButtonRootProps } from "@heroui/react";
import type { VariantProps } from "tailwind-variants";
import { Button, buttonVariants } from "@heroui/react";
import { tv } from "tailwind-variants";
const myButtonVariants = tv({
extend: buttonVariants,
base: "text-md text-shadow-lg font-semibold shadow-md data-[pending=true]:opacity-40",
variants: {
radius: {
lg: "rounded-lg",
md: "rounded-md",
sm: "rounded-sm",
full: "rounded-full",
},
size: {
sm: "h-10 px-4",
md: "h-11 px-6",
lg: "h-12 px-8",
xl: "h-13 px-10",
},
variant: {
primary: "text-white dark:bg-white/10 dark:text-white dark:hover:bg-white/15",
},
},
defaultVariants: {
radius: "full",
variant: "primary",
},
});
type MyButtonVariants = VariantProps;
export type MyButtonProps = Omit &
MyButtonVariants & { className?: string };
function CustomButton({ className, radius, variant, ...props }: MyButtonProps) {
return ;
}
export function CustomVariants() {
return Custom Button;
}
```
**Type references:** When working with component types, use named type imports or object-style syntax.
**Recommended — Named type imports:**
```tsx
import type { ButtonRootProps, AvatarRootProps } from "@heroui/react";
type MyButtonProps = ButtonRootProps;
type MyAvatarProps = AvatarRootProps;
```
**Alternative — Object-style syntax:**
```tsx
import { Button, Avatar } from "@heroui/react";
type MyButtonProps = Button["RootProps"];
type MyAvatarProps = Avatar["RootProps"];
```
**Note:** The namespace syntax `Button.RootProps` is no longer supported. Use `Button["RootProps"]` or named imports instead.
## Framework Integration
**With Next.js:**
Use variant functions for type-safe styling:
```tsx
import { buttonVariants } from '@heroui/react';
import Link from 'next/link';
Dashboard
```
Or apply BEM classes directly (simplest):
```tsx
import Link from 'next/link';
Dashboard
```
**With React Router:**
Use variant functions:
```tsx
import { buttonVariants } from '@heroui/react';
import { Link } from 'react-router-dom';
Dashboard
```
Or apply BEM classes directly (simplest):
```tsx
import { Link } from 'react-router-dom';
Dashboard
```
## Next Steps
* Learn about [Styling](/docs/handbook/styling) components
* Explore [Animation](/docs/handbook/animation) options
* Browse [Components](/docs/react/components) for more examples
# Styling
**Category**: react
**URL**: https://v3.heroui.com/docs/react/getting-started/styling
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(handbook)/styling.mdx
> Style HeroUI components with CSS, Tailwind, or CSS-in-JS
HeroUI components provide flexible styling options: Tailwind CSS utilities, CSS with [BEM](https://getbem.com/) classes or data attributes, CSS-in-JS libraries, and render props for dynamic styling.
## Basic Styling
**Using className:** All HeroUI components accept `className` props:
```tsx
{/* content */}
```
**Using style:** Components also accept inline styles:
```tsx
```
## State-Based Styling
HeroUI components expose their state through data attributes, similar to CSS pseudo-classes:
```css
/* Target different states */
.button[data-hovered="true"], .button:hover {
background: var(--accent-hover);
}
.button[data-pressed="true"], .button:active {
transform: scale(0.97);
}
.button[data-focus-visible="true"], .button:focus-visible {
outline: 2px solid var(--focus);
}
```
## Render Props
Apply dynamic styling based on component state:
```tsx
// Dynamic classes
// Dynamic content
```
## BEM Classes
HeroUI uses [BEM methodology](https://getbem.com/) for consistent class naming:
```css
/* Block */
.button { }
.accordion { }
/* Element */
.accordion__trigger { }
.accordion__panel { }
/* Modifier */
.button--primary { }
.button--lg { }
.accordion--outline { }
```
**Customizing components globally:**
```css
/* global.css */
@layer components {
/* Override button styles */
.button {
@apply font-semibold uppercase;
}
.button--primary {
@apply bg-indigo-600 hover:bg-indigo-700;
}
/* Add custom variant */
.button--gradient {
@apply bg-gradient-to-r from-purple-500 to-pink-500;
}
}
```
## Creating Wrapper Components
Create reusable custom components using [tailwind-variants](https://tailwind-variants.org/)—a Tailwind CSS first-class variant API:
```tsx
import { Button as HeroButton, buttonVariants, type ButtonProps } from '@heroui/react';
import { tv, type VariantProps } from 'tailwind-variants';
const customButtonVariants = tv({
extend: buttonVariants,
base: 'font-medium transition-all',
variants: {
intent: {
primary: 'bg-blue-500 hover:bg-blue-600 text-white',
secondary: 'bg-gray-200 hover:bg-gray-300',
danger: 'bg-red-500 hover:bg-red-600 text-white',
},
size: {
small: 'text-sm px-2 py-1',
medium: 'text-base px-4 py-2',
large: 'text-lg px-6 py-3',
},
},
defaultVariants: {
intent: 'primary',
size: 'medium',
},
});
type CustomButtonVariants = VariantProps;
interface CustomButtonProps
extends Omit,
CustomButtonVariants {
className?: string;
}
export function CustomButton({ intent, size, className, ...props }: CustomButtonProps) {
return (
);
}
```
## CSS-in-JS Integration
**Styled Components:**
```tsx
import styled from 'styled-components';
import { Button } from '@heroui/react';
const StyledButton = styled(Button)`
background: linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%);
border-radius: 8px;
color: white;
padding: 12px 24px;
&:hover {
box-shadow: 0 3px 10px rgba(255, 105, 135, 0.3);
}
`;
```
**Emotion:**
```tsx
import { css } from '@emotion/css';
import { Button } from '@heroui/react';
const buttonStyles = css`
background: linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%);
border-radius: 8px;
color: white;
padding: 12px 24px;
&:hover {
box-shadow: 0 3px 10px rgba(255, 105, 135, 0.3);
}
`;
```
## Responsive Design
**Using Tailwind utilities:**
```tsx
```
**Or with CSS:**
```css
.button {
font-size: 0.875rem;
padding: 0.5rem 1rem;
}
@media (min-width: 768px) {
.button {
font-size: 1rem;
padding: 0.75rem 1.5rem;
}
}
```
## CSS Modules
For scoped styles, use CSS Modules:
```css
/* Button.module.css */
.button {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
padding: 12px 24px;
border-radius: 8px;
}
.button:hover {
transform: translateY(-2px);
}
.button--primary {
background: linear-gradient(135deg, #667eea, #764ba2);
color: white;
padding: 12px 24px;
border-radius: 8px;
}
```
```tsx
import styles from './Button.module.css';
import { Button } from '@heroui/react';
```
## Component Classes Reference
**Button:** `.button`, `.button--{variant}`, `.button--{size}`, `.button--icon-only`\
**Accordion:** `.accordion`, `.accordion__item`, `.accordion__trigger`, `.accordion__panel`, `.accordion--outline`
> **Note:** See component docs for complete class references: [Button](/docs/components/button#css-classes), [Accordion](/docs/components/accordion#css-classes)
View all component classes in [@heroui/styles/components](https://github.com/heroui-inc/heroui/tree/main/packages/styles/components).
## Next Steps
* Learn about [Animation](/docs/handbook/animation) techniques
* Explore [Theming](/docs/handbook/theming) system
* Browse [Component](/docs/react/components) examples
# Theming
**Category**: react
**URL**: https://v3.heroui.com/docs/react/getting-started/theming
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(handbook)/theming.mdx
> Customize HeroUI's design system with CSS variables and global styles
HeroUI uses CSS variables and [BEM](https://getbem.com/) classes for theming. Customize everything from colors to component styles using standard CSS.
## How It Works
HeroUI's theming system is built on top of [Tailwind CSS v4](https://tailwindcss.com/docs/theme)'s theme. When you import `@heroui/styles`, it uses Tailwind's built-in color palettes, maps them to semantic variables, automatically switches between light and dark themes, and uses CSS layers and the `@theme` directive for organization.
**Naming pattern:**
* Colors without a suffix are backgrounds (e.g., `--accent`)
* Colors with `-foreground` are for text on that background (e.g., `--accent-foreground`)
## Quick Start
**Apply a theme:** Add a theme class to your HTML and apply colors to the body:
```html
```
**Switch themes:**
```html
```
**Override colors:**
```css
/* app/globals.css */
@import "tailwindcss";
@import "@heroui/styles";
:root {
/* Override any color variable */
--accent: oklch(0.7 0.25 260);
--success: oklch(0.65 0.15 155);
}
```
> **Note**: See [Colors](/docs/handbook/colors) for the complete color palette and visual reference.
**Create your own theme:**
```css
/* src/themes/ocean.css */
@layer base {
/* Ocean Light */
[data-theme="ocean"] {
color-scheme: light;
/* Primitive Colors (Do not change between light and dark) */
--white: oklch(100% 0 0);
--black: oklch(0% 0 0);
--snow: oklch(0.9911 0 0);
--eclipse: oklch(0.2103 0.0059 285.89);
/* Spacing & Layout */
--spacing: 0.25rem;
--border-width: 0px;
--field-border-width: var(--border-width);
--disabled-opacity: 0.5;
--ring-offset-width: 2px;
--cursor-interactive: pointer;
--cursor-disabled: not-allowed;
/* Radius */
--radius: 0.75rem;
--field-radius: calc(var(--radius) * 1.5);
/* Base Colors */
--background: oklch(0.985 0.015 225);
--foreground: var(--eclipse);
/* Surface: Used for non-overlay components */
--surface: var(--white);
--surface-foreground: var(--foreground);
/* Overlay: Used for floating/overlay components */
--overlay: var(--white);
--overlay-foreground: var(--foreground);
--muted: oklch(0.5517 0.0138 285.94);
--scrollbar: oklch(87.1% 0.006 286.286);
--default: oklch(94% 0.001 286.375);
--default-foreground: var(--eclipse);
/* Ocean accent */
--accent: oklch(0.450 0.150 230);
--accent-foreground: var(--snow);
/* Form Field Defaults */
--field-background: var(--white);
--field-foreground: oklch(0.2103 0.0059 285.89);
--field-placeholder: var(--muted);
--field-border: transparent;
/* Status (kept compatible) */
--success: oklch(0.7329 0.1935 150.81);
--success-foreground: var(--eclipse);
--warning: oklch(0.7819 0.1585 72.33);
--warning-foreground: var(--eclipse);
--danger: oklch(0.6532 0.2328 25.74);
--danger-foreground: var(--snow);
/* Component Colors */
--segment: var(--white);
--segment-foreground: var(--foreground);
/* Misc */
--border: oklch(0.50 0.060 230 / 22%);
--separator: oklch(92% 0.004 286.32);
--focus: var(--accent);
--link: var(--accent);
/* Shadows */
--surface-shadow:
0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06),
0 0 1px 0 rgba(0, 0, 0, 0.06);
--overlay-shadow: 0 4px 16px 0 rgba(24, 24, 27, 0.08), 0 8px 24px 0 rgba(24, 24, 27, 0.09);
--field-shadow:
0 2px 4px 0 rgba(0, 0, 0, 0.04), 0 1px 2px 0 rgba(0, 0, 0, 0.06),
0 0 1px 0 rgba(0, 0, 0, 0.06);
/* Skeleton Default Global Animation */
--skeleton-animation: shimmer; /* Possible values: shimmer, pulse, none */
}
/* Ocean Dark */
[data-theme="ocean-dark"] {
color-scheme: dark;
/* Base Colors */
--background: oklch(0.140 0.020 230);
--foreground: var(--snow);
/* Surface: Used for non-overlay components */
--surface: oklch(0.2103 0.0059 285.89);
--surface-foreground: var(--foreground);
/* Overlay: Used for floating/overlay components */
--overlay: oklch(0.22 0.0059 285.89);
--overlay-foreground: var(--foreground);
--muted: oklch(70.5% 0.015 286.067);
--scrollbar: oklch(70.5% 0.015 286.067);
--default: oklch(27.4% 0.006 286.033);
--default-foreground: var(--snow);
/* Form Field Defaults */
--field-background: var(--default);
--field-foreground: var(--foreground);
/* Ocean accent */
--accent: oklch(0.860 0.080 230);
--accent-foreground: var(--eclipse);
/* Status */
--success: oklch(0.7329 0.1935 150.81);
--success-foreground: var(--eclipse);
--warning: oklch(0.8203 0.1388 76.34);
--warning-foreground: var(--eclipse);
--danger: oklch(0.594 0.1967 24.63);
--danger-foreground: var(--snow);
/* Component Colors */
--segment: oklch(0.3964 0.01 285.93);
--segment-foreground: var(--foreground);
/* Misc */
--border: oklch(1 0 0 / 0%);
--separator: oklch(22% 0.006 286.033);
--focus: var(--accent);
--link: var(--accent);
/* Shadows */
--surface-shadow: 0 0 0 0 transparent inset;
--overlay-shadow: 0 0 0 0 transparent inset;
--field-shadow: 0 0 0 0 transparent inset;
}
}
```
Use your theme:
```css
/* app/globals.css */
@layer theme, base, components, utilities;
@import "tailwindcss";
@import "@heroui/styles";
@import "./src/themes/ocean.css" layer(theme); /* [!code highlight]*/
```
Apply your theme:
```html
```
## Customize Components
**Global component styles:** Override any component using BEM classes:
```css
@layer components {
/* Customize buttons */
.button {
@apply font-semibold tracking-wide;
}
.button--primary {
@apply bg-blue-600 hover:bg-blue-700;
}
/* Customize accordions */
.accordion__trigger {
@apply text-lg font-bold;
}
}
```
> **Note**: See [Styling](/docs/handbook/styling) for the complete styling reference.
**Find component classes:** Each component docs page lists all available classes (base classes, modifiers, elements, states). Example: [Button classes](/docs/components/button#css-classes)
## Import Strategies
**Full import (recommended):** Get everything with two lines:
```css
@import "tailwindcss";
@import "@heroui/styles";
```
**Selective import:** Import only what you need:
```css
/* Define layers */
@layer theme, base, components, utilities;
/* Base requirements */
@import "tailwindcss";
@import "@heroui/styles/base" layer(base);
/* OR specific base file */
@import "@heroui/styles/base/base.css" layer(base);
/* Theme variables */
@import "@heroui/styles/themes/shared/theme.css" layer(theme);
@import "@heroui/styles/themes/default" layer(theme);
/* OR specific theme files */
@import "@heroui/styles/themes/default/index.css" layer(theme);
@import "@heroui/styles/themes/default/variables.css" layer(theme);
/* Components (all components) */
@import "@heroui/styles/components" layer(components);
/* OR specific component files */
@import "@heroui/styles/components/index.css" layer(components);
@import "@heroui/styles/components/button.css" layer(components);
@import "@heroui/styles/components/accordion.css" layer(components);
/* Utilities (optional) */
@import "@heroui/styles/utilities" layer(utilities);
/* Variants (optional) */
@import "@heroui/styles/variants" layer(utilities);
```
> **Note**: Directory imports (e.g., `@heroui/styles/components`) automatically resolve to their `index.css` file. Use explicit file paths (e.g., `@heroui/styles/components/button.css`) to import individual component styles.
**Headless mode:** Build your own styles from scratch:
```css
@import "tailwindcss";
@import "@heroui/styles/base/base.css";
/* Your custom styles */
.button {
/* Your button styles */
}
```
## Adding Custom Colors
Add your own semantic colors to the theme:
```css
/* Define in both light and dark themes */
:root,
[data-theme="light"] {
--info: oklch(0.6 0.15 210);
--info-foreground: oklch(0.98 0 0);
}
.dark,
[data-theme="dark"] {
--info: oklch(0.7 0.12 210);
--info-foreground: oklch(0.15 0 0);
}
/* Make the color available to Tailwind */
@theme inline {
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
}
```
Now use it in your components:
```tsx
Info message
```
## Variables Reference
HeroUI defines three types of variables:
1. **Base Variables** — Non-changing values like `--white`, `--black`, spacing, and typography
2. **Theme Variables** — Colors that change between light/dark themes
3. **Calculated Variables** — Automatically generated hover states and size variants
For a complete reference, see: [Colors Documentation](/docs/handbook/colors), [Default Theme Variables](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/default/variables.css), [Shared Theme Utilities](https://github.com/heroui-inc/heroui/blob/v3/packages/styles/themes/shared/theme.css)
**Calculated variables (Tailwind):**
We use Tailwind's `@theme` directive to automatically create calculated variables for hover states and radius variants. These are defined in `themes/shared/theme.css`:
```css
@theme inline {
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-surface: var(--surface);
--color-surface-foreground: var(--surface-foreground);
--color-overlay: var(--overlay);
--color-overlay-foreground: var(--overlay-foreground);
--color-muted: var(--muted);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-segment: var(--segment);
--color-segment-foreground: var(--segment-foreground);
--color-border: var(--border);
--color-separator: var(--separator);
--color-focus: var(--focus);
--color-link: var(--link);
--color-default: var(--default);
--color-default-foreground: var(--default-foreground);
--color-success: var(--success);
--color-success-foreground: var(--success-foreground);
--color-warning: var(--warning);
--color-warning-foreground: var(--warning-foreground);
--color-danger: var(--danger);
--color-danger-foreground: var(--danger-foreground);
--shadow-surface: var(--surface-shadow);
--shadow-overlay: var(--overlay-shadow);
--shadow-field: var(--field-shadow);
/* Form Field Tokens */
--color-field: var(--field-background, var(--color-default));
--color-field-hover: color-mix(
in oklab,
var(--field-background, var(--color-default)) 90%,
var(--field-foreground, var(--color-default-foreground)) 10%
);
--color-field-foreground: var(--field-foreground, var(--color-foreground));
--color-field-placeholder: var(--field-placeholder, var(--color-muted));
--color-field-border: var(--field-border, var(--color-border));
--radius-field: var(--field-radius, var(--radius-xl));
--border-width-field: var(--field-border-width, var(--border-width));
/* Calculated Variables */
/* --- background shades --- */
--color-background-secondary: color-mix(
in oklab,
var(--color-background) 96%,
var(--color-foreground) 4%
);
--color-background-tertiary: color-mix(
in oklab,
var(--color-background) 92%,
var(--color-foreground) 8%
);
--color-background-quaternary: color-mix(
in oklab,
var(--color-background) 86%,
var(--color-foreground) 14%
);
--color-background-inverse: var(--color-foreground);
/* Hover states */
--color-default-hover: color-mix(in oklab, var(--color-default) 80%, transparent);
--color-accent-hover: color-mix(
in oklab,
var(--color-accent) 90%,
var(--color-accent-foreground) 10%
);
--color-success-hover: color-mix(
in oklab,
var(--color-success) 90%,
var(--color-success-foreground) 10%
);
--color-warning-hover: color-mix(
in oklab,
var(--color-warning) 90%,
var(--color-warning-foreground) 10%
);
--color-danger-hover: color-mix(
in oklab,
var(--color-danger) 90%,
var(--color-danger-foreground) 10%
);
/* Form Field Colors */
--color-field-hover: color-mix(
in oklab,
var(--color-field) 90%,
var(--color-field-foreground) 2%
);
--color-field-focus: var(--color-field);
--color-field-border-hover: color-mix(
in oklab,
var(--color-field-border) 88%,
var(--color-field-foreground) 10%
);
--color-field-border-focus: color-mix(
in oklab,
var(--color-field-border) 74%,
var(--color-field-foreground) 22%
);
/* Soft Colors */
--color-accent-soft: color-mix(in oklab, var(--color-accent) 15%, transparent);
--color-accent-soft-foreground: var(--color-accent);
--color-accent-soft-hover: color-mix(in oklab, var(--color-accent) 20%, transparent);
--color-danger-soft: color-mix(in oklab, var(--color-danger) 15%, transparent);
--color-danger-soft-foreground: var(--color-danger);
--color-danger-soft-hover: color-mix(in oklab, var(--color-danger) 20%, transparent);
--color-warning-soft: color-mix(in oklab, var(--color-warning) 15%, transparent);
--color-warning-soft-foreground: var(--color-warning);
--color-warning-soft-hover: color-mix(in oklab, var(--color-warning) 20%, transparent);
--color-success-soft: color-mix(in oklab, var(--color-success) 15%, transparent);
--color-success-soft-foreground: var(--color-success);
--color-success-soft-hover: color-mix(in oklab, var(--color-success) 20%, transparent);
/* Surface Levels */
--color-surface-secondary: color-mix(in oklab, var(--surface) 94%, var(--surface-foreground) 6%);
--color-surface-tertiary: color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%);
--color-surface-quaternary: color-mix(
in oklab,
var(--surface) 86%,
var(--default-foreground) 14%
);
/* On Surface Colors */
--color-on-surface: color-mix(
in oklab,
var(--color-surface) 93%,
var(--color-surface-foreground) 7%
);
--color-on-surface-foreground: var(--color-surface-foreground);
--color-on-surface-hover: color-mix(
in oklab,
var(--color-surface) 91%,
var(--color-surface-foreground) 9%
);
--color-on-surface-focus: var(--color-on-surface);
/* Radius scale */
--radius-xs: calc(var(--radius) * 0.25); /* 0.125rem (2px) */
--radius-sm: calc(var(--radius) * 0.5); /* 0.25rem (4px) */
--radius-md: calc(var(--radius) * 0.75); /* 0.375rem (6px) */
--radius-lg: calc(var(--radius) * 1); /* 0.5rem (8px) */
--radius-xl: calc(var(--radius) * 1.5); /* 0.75rem (12px) */
--radius-2xl: calc(var(--radius) * 2); /* 1rem (16px) */
--radius-3xl: calc(var(--radius) * 3); /* 1.5rem (24px) */
--radius-4xl: calc(var(--radius) * 4); /* 2rem (32px) */
/* Transition Timing Functions */
--ease-smooth: ease;
--ease-in-quad: cubic-bezier(0.55, 0.085, 0.68, 0.53);
--ease-in-cubic: cubic-bezier(0.55, 0.055, 0.675, 0.19);
--ease-in-quart: cubic-bezier(0.895, 0.03, 0.685, 0.22);
--ease-in-quint: cubic-bezier(0.755, 0.05, 0.855, 0.06);
--ease-in-expo: cubic-bezier(0.95, 0.05, 0.795, 0.035);
--ease-in-circ: cubic-bezier(0.6, 0.04, 0.98, 0.335);
--ease-out-quad: cubic-bezier(0.25, 0.46, 0.45, 0.94);
--ease-out-cubic: cubic-bezier(0.215, 0.61, 0.355, 1);
--ease-out-quart: cubic-bezier(0.165, 0.84, 0.44, 1);
--ease-out-quint: cubic-bezier(0.23, 1, 0.32, 1);
--ease-out-expo: cubic-bezier(0.19, 1, 0.22, 1);
--ease-out-circ: cubic-bezier(0.075, 0.82, 0.165, 1);
--ease-out-fluid: cubic-bezier(0.32, 0.72, 0, 1);
--ease-in-out-quad: cubic-bezier(0.455, 0.03, 0.515, 0.955);
--ease-in-out-cubic: cubic-bezier(0.645, 0.045, 0.355, 1);
--ease-in-out-quart: cubic-bezier(0.77, 0, 0.175, 1);
--ease-in-out-quint: cubic-bezier(0.86, 0, 0.07, 1);
--ease-in-out-expo: cubic-bezier(1, 0, 0, 1);
--ease-in-out-circ: cubic-bezier(0.785, 0.135, 0.15, 0.86);
--ease-linear: linear;
/* Animations */
--animate-spin-fast: spin 0.75s linear infinite;
--animate-skeleton: skeleton 2s linear infinite;
--animate-caret-blink: caret-blink 1.2s ease-out infinite;
@keyframes skeleton {
100% {
transform: translateX(200%);
}
}
@keyframes caret-blink {
0%,
70%,
100% {
opacity: 1;
}
20%,
50% {
opacity: 0;
}
}
}
```
Form controls now rely on the `--field-*` variables and their calculated hover/focus variants. Update them in your theme to restyle inputs, checkboxes, radios, and OTP slots without impacting surfaces like buttons or cards.
## Resources
* [Colors Documentation](/docs/handbook/colors)
* [Styling Guide](/docs/handbook/styling)
* [Tailwind CSS v4 Theming](https://tailwindcss.com/docs/theme)
* [BEM Methodology](https://getbem.com/)
* [OKLCH Color Tool](https://oklch.com)
# Design Principles
**Category**: react
**URL**: https://v3.heroui.com/docs/react/getting-started/design-principles
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(overview)/design-principles.mdx
> Core principles that guide HeroUI v3's design and development
HeroUI v3 follows 10 core principles that prioritize clarity, accessibility, customization, and developer experience.
## Core Principles
### 1. Semantic Intent Over Visual Style
Use semantic naming (primary, secondary, tertiary) instead of visual descriptions (solid, flat, bordered). Inspired by [Uber's Base design system](https://base.uber.com/6d2425e9f/p/756216-button), variants follow a clear hierarchy:
```tsx
// ✅ Semantic variants communicate hierarchy
```
| Variant | Purpose | Usage |
| ------------- | --------------------------------- | ---------------- |
| **Primary** | Main action to move forward | 1 per context |
| **Secondary** | Alternative actions | Multiple allowed |
| **Tertiary** | Dismissive actions (cancel, skip) | Sparingly |
| **Danger** | Destructive actions | When needed |
### 2. Accessibility as Foundation
Built on [React Aria Components](https://react-spectrum.adobe.com/react-aria/) for WCAG 2.1 AA compliance. Automatic ARIA attributes, keyboard navigation, and screen reader support included.
```tsx
import { Tabs, TabList, Tab, TabPanel } from '@heroui/react';
ProfileSecurityContentContent
```
### 3. Composition Over Configuration
Compound components let you rearrange, customize, or omit parts as needed. Use dot notation, named exports, or mix both.
```tsx
// Compose parts to build exactly what you need
import {
Accordion,
AccordionItem,
AccordionHeading,
AccordionTrigger,
AccordionIndicator,
AccordionPanel,
AccordionBody
} from '@heroui/react';
Question Text
Answer content
```
### 4. Progressive Disclosure
Start simple, add complexity only when needed. Components work with minimal props and scale up as requirements grow.
```tsx
// Level 1: Minimal
// Level 2: Enhanced
// Level 3: Advanced
```
### 5. Predictable Behavior
Consistent patterns across all components: sizes (`sm`, `md`, `lg`), variants, className support, and data attributes. Same API, same behavior.
```tsx
// All components follow the same patterns
// Compound components support both named exports and dot notation
import { Alert, AlertIcon, CardHeader, AccordionTrigger } from '@heroui/react';
// Named exports
// Dot notation
```
### 6. Type Safety First
Full TypeScript support with IntelliSense, auto-completion, and compile-time error detection. Extend types for custom components.
```tsx
import type { ButtonProps } from '@heroui/react';
// Type-safe props and event handlers
# Quick Start
**Category**: react
**URL**: https://v3.heroui.com/docs/react/getting-started/quick-start
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(overview)/quick-start.mdx
> Get started with HeroUI v3 in minutes
## Requirements
* [React 19+](https://reactjs.org/)
* [Tailwind CSS v4](https://tailwindcss.com/docs/installation/framework-guides)
## Quick Install
Install HeroUI and required dependencies:
```bash
npm i @heroui/styles@beta @heroui/react@beta
```
```bash
pnpm add @heroui/styles@beta @heroui/react@beta
```
```bash
yarn add @heroui/styles@beta @heroui/react@beta
```
```bash
bun add @heroui/styles@beta @heroui/react@beta
```
## Import Styles
Add to your main CSS file `globals.css`:
```css
@import "tailwindcss";
@import "@heroui/styles"; /* [!code highlight]*/
```
Import order matters. Always import `tailwindcss` first.
## Use Components
```tsx
import { Button } from '@heroui/react';
function App() {
return (
My Button
);
}
```
## What's Next?
* [Browse Components](/docs/react/components) - See all available components
* [Learn Styling](/docs/handbook/styling) - Customize with Tailwind CSS
* [Explore Patterns](/docs/handbook/composition) - Master compound components
# LLMs.txt
**Category**: react
**URL**: https://v3.heroui.com/docs/react/getting-started/llms-txt
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(ui-for-agents)/llms-txt.mdx
> Enable AI assistants like Claude, Cursor, and Windsurf to understand HeroUI v3
We provide [LLMs.txt](https://llmstxt.org/) files to make HeroUI v3 documentation accessible to AI coding assistants.
## Available Files
**Core documentation:**
* [/react/llms.txt](/react/llms.txt) — Quick reference index for React documentation
* [/react/llms-full.txt](/react/llms-full.txt) — Complete HeroUI React documentation
**For limited context windows:**
* [/react/llms-components.txt](/react/llms-components.txt) — Component documentation only
* [/react/llms-patterns.txt](/react/llms-patterns.txt) — Common patterns and recipes
**All platforms:**
* [/llms.txt](/llms.txt) — Quick reference index (React + Native)
* [/llms-full.txt](/llms-full.txt) — Complete documentation (React + Native)
* [/llms-components.txt](/llms-components.txt) — All component documentation
* [/llms-patterns.txt](/llms-patterns.txt) — All patterns and recipes
## Integration
**Claude Code:** Tell Claude to reference the documentation:
```
Use HeroUI React documentation from https://v3.heroui.com/react/llms.txt
```
Or add to your project's `.claude` file for automatic loading.
**Cursor:** Use the `@Docs` feature:
```
@Docs https://v3.heroui.com/react/llms-full.txt
```
[Learn more](https://docs.cursor.com/context/@-symbols/@-docs)
**Windsurf:** Add to your `.windsurfrules` file:
```
#docs https://v3.heroui.com/react/llms-full.txt
```
[Learn more](https://docs.codeium.com/windsurf/memories#memories-and-rules)
**Other AI tools:** Most AI assistants can reference documentation by URL. Simply provide:
```
https://v3.heroui.com/react/llms.txt
```
**For component-specific documentation:**
```
https://v3.heroui.com/react/llms-components.txt
```
**For patterns and best practices:**
```
https://v3.heroui.com/react/llms-patterns.txt
```
## Contributing
Found an issue with AI-generated code? Help us improve our LLMs.txt files on [GitHub](https://github.com/heroui-inc/heroui).
# MCP Server
**Category**: react
**URL**: https://v3.heroui.com/docs/react/getting-started/mcp-server
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(ui-for-agents)/mcp-server.mdx
> Access HeroUI v3 documentation directly in your AI assistant
The HeroUI MCP Server gives AI assistants direct access to HeroUI v3 component documentation, making it easier to build with HeroUI in AI-powered development environments.
The MCP server currently supports **@heroui/react v3** only and [stdio transport](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports#stdio). Published at `@heroui/react-mcp` on npm. View the source code on [GitHub](https://github.com/heroui-inc/heroui-mcp).
As we add more components to HeroUI v3, they'll be available in the MCP server too.
## Quick Setup
**Cursor:**
Or manually add to **Cursor Settings** → **Tools** → **MCP Servers**:
```json title=".cursor/mcp.json"
{
"mcpServers": {
"heroui-react": {
"command": "npx",
"args": ["-y", "@heroui/react-mcp@latest"]
}
}
}
```
Alternatively, add the following to your `~/.cursor/mcp.json` file. To learn more, see the [Cursor documentation](https://cursor.com/docs/context/mcp).
**Claude Code:** Run this command in your terminal:
```bash
claude mcp add heroui-react -- npx -y @heroui/react-mcp@latest
```
Or manually add to your project's `.mcp.json` file:
```json title=".mcp.json"
{
"mcpServers": {
"heroui-react": {
"command": "npx",
"args": ["-y", "@heroui/react-mcp@latest"]
}
}
}
```
After adding the configuration, restart Claude Code and run `/mcp` to see the HeroUI MCP server in the list. If you see **Connected**, you're ready to use it.
See the [Claude Code MCP documentation](https://docs.claude.com/en/docs/claude-code/mcp) for more details.
**Windsurf:** Add the HeroUI server to your project's `.windsurf/mcp.json` configuration file:
```json title=".windsurf/mcp.json"
{
"mcpServers": {
"heroui-react": {
"command": "npx",
"args": ["-y", "@heroui/react-mcp@latest"]
}
}
}
```
After adding the configuration, restart Windsurf to activate the MCP server.
See the [Windsurf MCP documentation](https://docs.windsurf.com/windsurf/cascade/mcp) for more details.
**VS Code:** To configure MCP in VS Code with GitHub Copilot, add the HeroUI server to your project's `.vscode/mcp.json` configuration file:
```json title=".vscode/mcp.json"
{
"mcpServers": {
"heroui-react": {
"command": "npx",
"args": ["-y", "@heroui/react-mcp@latest"]
}
}
}
```
After adding the configuration, open `.vscode/mcp.json` and click **Start** next to the heroui-react server.
See the [VS Code MCP documentation](https://code.visualstudio.com/docs/copilot/customization/mcp-servers) for more details.
## Usage
Once configured, ask your AI assistant questions like:
* "Help me install HeroUI v3 in my Next.js/Vite/Astro app"
* "Show me all HeroUI components"
* "What props does the Button component have?"
* "Give me an example of using the Card component"
* "Get the source code for the Button component"
* "Show me the CSS styles for Card"
* "What are the theme variables for dark mode?"
### Automatic Updates
The MCP server can help you upgrade to the latest HeroUI version:
```bash
"Hey Cursor, update HeroUI to the latest version"
```
Your AI assistant will automatically:
* Compare your current version with the latest release
* Review the changelog for breaking changes
* Apply the necessary code updates to your project
This works for any version upgrade, whether you're updating to the latest alpha, beta, or stable release.
## Available Tools
The MCP server provides these tools to AI assistants:
| Tool | Description |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `installation` | Get complete installation instructions for your specific framework (Next.js, Vite, etc.) and package manager |
| `list_components` | List all available HeroUI v3 components |
| `get_component_info` | Get detailed documentation, anatomy, props, and examples for specific components |
| `get_component_props` | Get detailed props information for HeroUI components |
| `get_component_examples` | Get usage examples for HeroUI components |
| `get_component_source_code` | Access the React/TypeScript source code (.tsx files) for components |
| `get_component_source_styles` | View the CSS styles (.css files) for components |
| `get_theme_info` | Access theme variables for colors, typography, spacing with light/dark mode support |
| `get_docs` | Browse the full HeroUI v3 documentation including guides and principles |
## Troubleshooting
**Requirements:** Node.js 18 or higher. The package will be automatically downloaded when using `npx`.
**Need help?** [GitHub Issues](https://github.com/heroui-inc/heroui-mcp/issues) | [Discord Community](https://discord.gg/heroui)
## Links
* [npm Package](https://www.npmjs.com/package/@heroui/react-mcp)
* [GitHub Repository](https://github.com/heroui-inc/heroui-mcp)
* [Contributing Guide](https://github.com/heroui-inc/heroui-mcp/blob/main/CONTRIBUTING.md)