);
}
```
## 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://www.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 {ColorSectionSideBySide, ColorSectionStacked, ColorSectionFormField, ColorSectionPrimitive} from "@/components/color-section";
HeroUI's color system is built around semantic intent, not visual abundance. Instead of exposing large raw palettes, the system defines a small, meaningful set of color roles that cover the majority of interface needs.
Most colors in the system are derived automatically from a limited number of base values. This allows HeroUI to maintain consistent contrast, hierarchy, and theming behavior while keeping the system easy to reason about and modify.
Colors should communicate purpose and state first. Visual variation comes from scale, emphasis, and context.
**Want to create your own theme?** Try the [Theme Builder](/themes) to visually customize colors, radius, fonts, and more — then export the CSS to use in your project.
## Accent
The accent color represents the primary brand or product identity. It is used to draw attention to key actions, highlights, and moments of emphasis.
Accent should be used intentionally and sparingly. Overuse reduces its impact and can harm visual hierarchy. In most cases, components derive multiple accent-related values (hover, subtle backgrounds, focus states) automatically from the base accent color.
## Default (neutrals)
Default colors form the neutral backbone of the system. They are used for most non-emphasized UI elements.
## Success
Success colors communicate positive outcomes, confirmations, and completed states. They are typically used in feedback components, status indicators, and validation states.
## Warning
Warning colors indicate caution, risk, or actions that require attention but are not destructive. They are commonly used for alerts, messages, and transitional states where the user should pause or review information.
## Danger
Danger colors represent destructive, irreversible, or critical actions and states. They should be immediately recognizable and used consistently for errors, destructive buttons, and critical alerts.
## Foreground
Foreground colors are used for primary content such as text and icons. These colors are optimized for readability and accessibility and adapt automatically to background and surface contexts. Foreground colors should never be hard-coded at the component level.
## Background
Background colors define the base canvas of the interface. They establish overall contrast and mood while staying visually quiet.
## Surface
Surface colors sit on top of backgrounds and are used for containers such as cards, panels, modals, and dropdown. Surfaces help create visual separation and hierarchy through elevation, contrast, and layering rather than strong color shifts.
## Form field
Form field colors are specialized tokens used for inputs, controls, and interactive fields. They account for multiple states such as default, focus, and hover. Isolating them ensures form elements have a distinct visual language from buttons and the rest of the UI.
## Separator
Separator colors are used for dividers, outlines, and subtle boundaries. They exist to structure content and guide the eye without adding noise. Separator colors should remain low contrast and unobtrusive.
## Other
Other colors serve specific utility roles across the interface. They exist to structure content and guide the eye without adding noise.
## Primitive
Primitive colors are mode agnostic values used as foundations for semantic color tokens. They do not change between light and dark themes.
## 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: 1px;
--field-border-width: 0px;
--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(92% 0.004 286.32);
--separator: oklch(92% 0.004 286.32);
--focus: var(--accent);
--link: var(--foreground);
/* Backdrop */
--backdrop: rgba(0, 0, 0, 0.5);
/* 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(22% 0.006 286.033);
--separator: oklch(22% 0.006 286.033);
--focus: var(--accent);
--link: var(--foreground);
/* Backdrop */
--backdrop: rgba(0, 0, 0, 0.6);
/* 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).
# Composition
**Category**: react
**URL**: https://www.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.
## Framework-Agnostic Styles
HeroUI's variant functions are available in the `@heroui/styles` package, which can be used independently of React. This enables Vue, Svelte, and other frameworks to use HeroUI's design system:
```tsx
// Import directly from @heroui/styles (framework-agnostic)
import { buttonVariants } from '@heroui/styles';
// Or import from @heroui/react (re-exports the same functions)
import { buttonVariants } from '@heroui/react';
```
Both imports work identically. Use `@heroui/styles` when building for non-React frameworks or when you want to avoid pulling in React dependencies.
## 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/styles';
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 } from '@heroui/react';
import { linkVariants } from '@heroui/styles';
import NextLink from 'next/link';
// With custom root - pass className manually
const slots = linkVariants();
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. Variant functions are available from both `@heroui/styles` (framework-agnostic) and `@heroui/react` (re-exports).
**With Next.js Link:**
```tsx
import { Link } from '@heroui/react';
import { linkVariants } from '@heroui/styles';
import NextLink from 'next/link';
const slots = linkVariants();
About Page
```
**With Button styles:**
```tsx
import { buttonVariants } from '@heroui/styles';
import Link from 'next/link';
Dashboard
```
**Available variant functions:** Each component exports its variant function (`buttonVariants`, `chipVariants`, `linkVariants`, `spinnerVariants`, and more) from `@heroui/styles`. 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 } from '@heroui/react';
import { linkVariants, buttonVariants } from '@heroui/styles';
// Link styled with button variants
const buttonStyles = buttonVariants({ variant: "tertiary", size: "md" });
HeroUI
```
## Custom Components
Create your own components by composing HeroUI primitives:
```tsx
import { Button, Tooltip } from '@heroui/react';
import { buttonVariants } from '@heroui/styles';
// 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 } from "@heroui/react";
import { buttonVariants, tv } from "@heroui/styles";
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.
## Custom DOM Element
Use the `render` prop on the following components to render a custom component in place of the default DOM element.
For example, you can render a [Motion](https://motion.dev/) button and use the state to drive an animation.
```tsx
import {Button} from '@heroui/react';
import {motion} from 'motion/react';
```
The `render` prop is also useful for rendering link components from client-side routers, or reusing existing presentational components.
```tsx
import {Link} from '@heroui/react';
import NextLink from 'next/link';
(
} href="/privacy-policy" />
)}
>
Privacy Policy
```
Follow these rules to avoid breaking the behavior and accessibility of the component:
* Always render the expected element type (e.g. if `
# Styling
**Category**: react
**URL**: https://www.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
Custom Button
{/* content */}
```
**Using style:** Components also accept inline styles:
```tsx
Styled Button
```
## 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
isPressed ? 'bg-blue-600' : 'bg-blue-500'
}
>
Press me
// Dynamic content
{({ isHovered, isPressed }) => (
<>
Like
>
)}
```
## 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, type ButtonProps } from '@heroui/react';
import { buttonVariants, tv, type VariantProps } from '@heroui/styles';
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);
}
`;
Emotion Button
```
## Responsive Design
**Using Tailwind utilities:**
```tsx
Responsive Button
```
**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';
Scoped Button
```
## 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://www.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.
**Want to create your own theme?** Try the [Theme Builder](/themes) to visually customize colors, radius, fonts, and more — then export the CSS to use in your project.
## 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
```
**Switch themes programmatically with [next-themes](https://github.com/pacocoursey/next-themes) (For Next.js):**
First, wrap your app with `ThemeProvider`:
```tsx
// app/providers.tsx
"use client";
import { ThemeProvider } from "next-themes";
export function Providers({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
```
```tsx
// app/layout.tsx
import { Providers } from "./providers";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
```
Then use `useTheme` to toggle between themes:
```tsx
"use client";
import { useTheme } from "next-themes";
export function ThemeSwitch() {
const { theme, setTheme } = useTheme();
return (
setTheme(theme === "dark" ? "light" : "dark")}>
Toggle {theme === "dark" ? "Light" : "Dark"} Mode
);
}
```
**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: 1px;
--field-border-width: 0px;
--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(22% 0.006 286.033);
--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-surface-hover: color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%);
--color-surface-secondary: var(--surface-secondary);
--color-surface-secondary-foreground: var(--surface-secondary-foreground);
--color-surface-tertiary: var(--surface-tertiary);
--color-surface-tertiary-foreground: var(--surface-tertiary-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);
--color-backdrop: var(--backdrop);
--shadow-surface: var(--surface-shadow);
--shadow-overlay: var(--overlay-shadow);
--shadow-field: var(--field-shadow);
/* Form Field Tokens */
--color-field: var(--field-background, var(--default));
--color-field-foreground: var(--field-foreground, var(--foreground));
--color-field-placeholder: var(--field-placeholder, var(--muted));
--color-field-border: var(--field-border, var(--border));
--radius-field: var(--field-radius, calc(var(--radius) * 1.5));
--border-width-field: var(--field-border-width, var(--border-width));
/* Calculated Variables */
/* --- background shades --- */
--color-background-secondary: color-mix(in oklab, var(--background) 96%, var(--foreground) 4%);
--color-background-tertiary: color-mix(in oklab, var(--background) 92%, var(--foreground) 8%);
--color-background-inverse: var(--foreground);
/* ------------------------- */
--color-default-hover: color-mix(in oklab, var(--default) 96%, var(--default-foreground) 4%);
--color-accent-hover: color-mix(in oklab, var(--accent) 90%, var(--accent-foreground) 10%);
--color-success-hover: color-mix(in oklab, var(--success) 90%, var(--success-foreground) 10%);
--color-warning-hover: color-mix(in oklab, var(--warning) 90%, var(--warning-foreground) 10%);
--color-danger-hover: color-mix(in oklab, var(--danger) 90%, var(--danger-foreground) 10%);
/* Form Field Colors */
--color-field-hover: color-mix(
in oklab,
var(--field-background, var(--default)) 90%,
var(--field-foreground, var(--foreground)) 2%
);
--color-field-focus: var(--field-background, var(--default));
--color-field-border-hover: color-mix(
in oklab,
var(--field-border, var(--border)) 88%,
var(--field-foreground, var(--foreground)) 10%
);
--color-field-border-focus: color-mix(
in oklab,
var(--field-border, var(--border)) 74%,
var(--field-foreground, var(--foreground)) 22%
);
/* Soft Colors */
--color-accent-soft: color-mix(in oklab, var(--accent) 15%, transparent);
--color-accent-soft-foreground: var(--accent);
--color-accent-soft-hover: color-mix(in oklab, var(--accent) 20%, transparent);
--color-danger-soft: color-mix(in oklab, var(--danger) 15%, transparent);
--color-danger-soft-foreground: var(--danger);
--color-danger-soft-hover: color-mix(in oklab, var(--danger) 20%, transparent);
--color-warning-soft: color-mix(in oklab, var(--warning) 15%, transparent);
--color-warning-soft-foreground: var(--warning);
--color-warning-soft-hover: color-mix(in oklab, var(--warning) 20%, transparent);
--color-success-soft: color-mix(in oklab, var(--success) 15%, transparent);
--color-success-soft-foreground: var(--success);
--color-success-soft-hover: color-mix(in oklab, var(--success) 20%, transparent);
/* Separator Colors - Levels */
--color-separator-secondary: color-mix(
in oklab,
var(--surface) 85%,
var(--surface-foreground) 15%
);
--color-separator-tertiary: color-mix(
in oklab,
var(--surface) 81%,
var(--surface-foreground) 19%
);
/* Border Colors - Levels (progressive contrast: default → secondary → tertiary) */
/* Light mode: lighter → darker | Dark mode: darker → lighter */
--color-border-secondary: color-mix(in oklab, var(--surface) 78%, var(--surface-foreground) 22%);
--color-border-tertiary: color-mix(in oklab, var(--surface) 66%, var(--surface-foreground) 34%);
/* 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) */
/* Transition Timing Functions */
--ease-smooth: ease; /* same as transition: ease; */
/* These custom curves are made by https://twitter.com/bdc */
/* From smoother to faster */
--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);
/* From slower to faster */
--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);
/* Custom smooth-out curve: fast start, smooth stop - Apple style */
--ease-out-fluid: cubic-bezier(0.32, 0.72, 0, 1);
/* From slower to faster */
--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);
/* Linear */
--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)
# CLI
**Category**: react
**URL**: https://www.heroui.com/docs/react/getting-started/cli
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(overview)/cli.mdx
> Use the CLI to manage HeroUI dependencies and initialize projects.
The CLI offers a comprehensive suite of commands to initialize, manage, and improve your HeroUI projects. It enables you to `install`, `uninstall`, or `upgrade` individual components, assess the health of your project, and more.
## Installation
Requirements:
* [Node.js version 22.22.0 or later](https://nodejs.org/en/)
### Global Installation
To install `heroui-cli` globally, execute one of the following commands in your terminal:
npm
pnpm
yarn
bun
```bash
npm install heroui-cli@latest -g
```
```bash
pnpm add heroui-cli@latest -g
```
```bash
yarn global add heroui-cli@latest
```
```bash
bun add heroui-cli@latest --global
```
### Without Installation
Alternatively, you can use `heroui-cli` without a global installation by running one of the following:
```bash
pnpm dlx heroui-cli@latest
```
```bash
npx heroui-cli@latest
```
```bash
yarn dlx heroui-cli@latest
```
```bash
bunx heroui-cli@latest
```
## Quick Start
Once `heroui-cli` is installed, run the following command to display available commands:
```bash
heroui
```
This will produce the following help output:
```bash
Usage: heroui [command]
Options:
-v, --version Output the current version
--no-cache Disable cache, by default data will be cached for 30m after the first request
-d, --debug Debug mode will not install dependencies
-h --help Display help information for commands
Commands:
init [options] [projectName] Initializes a new project
install [options] Installs @heroui/react and @heroui/styles to your project
upgrade [options] Upgrades @heroui/react and @heroui/styles to the latest versions
uninstall [options] Uninstall @heroui/react and @heroui/styles from the project
list [options] Lists installed HeroUI packages (@heroui/react, @heroui/styles)
env [options] Displays debugging information for the local environment
doctor [options] Checks for issues in the project
help [command] Display help for command
```
### init
Initialize a new HeroUI project using the `init` command. This sets up your project with the necessary configurations.
```bash
heroui init
```
output:
```bash
HeroUI CLI
┌ Create a new project
│
◇ Select a template (Enter to select)
│ ● App (A Next.js 16 with app directory template pre-configured with HeroUI (v3) and Tailwind CSS.)
│ ○ Pages (A Next.js 16 with pages directory template pre-configured with HeroUI (v3) and Tailwind CSS.)
│ ○ Vite (A Vite template pre-configured with HeroUI (v3) and Tailwind CSS.)
│
◇ New project name (Enter to skip with default name)
│ my-heroui-app
│
◇ Select a package manager (Enter to select)
│ ● npm
│ ○ yarn
│ ○ pnpm
│ ○ bun
│
◇ Template created successfully!
│
◇ Next steps ───────╮
│ │
│ cd my-heroui-app │
│ npm install │
│ │
├────────────────────╯
│
└ 🚀 Get started with npm run dev
```
Install the dependencies to start the local server:
```bash
cd my-heroui-app && npm install
```
```bash
cd my-heroui-app && pnpm install
```
```bash
cd my-heroui-app && yarn install
```
```bash
cd my-heroui-app && bun install
```
Start the local server:
npm
pnpm
yarn
bun
```bash
npm run dev
```
```bash
pnpm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
### Install
Install `@heroui/react` and `@heroui/styles` to your project, along with their peer dependencies. If they are already installed, the command does nothing.
```bash
heroui install [options]
```
**Options:**
* `-p --packagePath` \[string] The path to the package.json file
**Output:**
```bash
HeroUI CLI
📦 Packages to be installed:
╭─────────────────────────────────────────────────────────────────────────────╮
│ Package │ Version │ Status │ Docs │
│─────────────────────────────────────────────────────────────────────────────│
│ @heroui/react │ 3.0.0 │ stable │ https://heroui.com │
│ @heroui/styles │ 3.0.0 │ stable │ https://heroui.com │
╰─────────────────────────────────────────────────────────────────────────────╯
╭─────────────── PeerDependencies ────────────────╮
│ react@18.3.1 latest │
│ react-dom@18.3.1 latest │
│ tailwindcss@4.2.2 latest │
╰─────────────────────────────────────────────────╯
? Proceed with installation? › - Use arrow-keys. Return to submit.
❯ Yes
No
✅ @heroui/react and @heroui/styles installed successfully
```
### upgrade
Upgrade `@heroui/react` and `@heroui/styles` with their peer dependencies to the latest versions.
```bash
heroui upgrade [options]
```
**Options:**
* `-p --packagePath` \[string] The path to the package.json file
**Output:**
```bash
HeroUI CLI
╭──────────────────────────── Upgrade ────────────────────────────╮
│ @heroui/react ^3.0.0 -> ^3.1.0 │
│ @heroui/styles ^3.0.0 -> ^3.1.0 │
╰─────────────────────────────────────────────────────────────────╯
? Would you like to proceed with the upgrade? › - Use arrow-keys. Return to submit.
❯ Yes
No
✅ Upgrade complete. All packages are up to date.
```
### uninstall
Uninstall `@heroui/react` and `@heroui/styles` from your project. Peer dependencies will not be uninstalled.
```bash
heroui uninstall [options]
```
**Options:**
* `-p --packagePath` \[string] The path to the package.json file
**Output:**
```bash
HeroUI CLI
❗️ Packages slated for uninstallation:
╭──────────────────────────────────────────────────────────────────────────────────────╮
│ Package │ Version │ Status │ Docs │
│──────────────────────────────────────────────────────────────────────────────────────│
│ @heroui/react │ 3.0.0 │ stable │ https://heroui.com │
│ @heroui/styles │ 3.0.0 │ stable │ https://heroui.com │
╰──────────────────────────────────────────────────────────────────────────────────────╯
? Confirm uninstallation of these packages: › - Use arrow-keys. Return to submit.
❯ Yes
No
✅ Successfully uninstalled: @heroui/react, @heroui/styles
```
### list
List the installed HeroUI packages (`@heroui/react`, `@heroui/styles`).
```bash
heroui list [options]
```
**Options:**
* `-p --packagePath` \[string] The path to the package.json file
**Output:**
```bash
HeroUI CLI
Current installed packages:
╭──────────────────────────────────────────────────────────────────────────────────────╮
│ Package │ Version │ Status │ Docs │
│──────────────────────────────────────────────────────────────────────────────────────│
│ @heroui/react │ 3.0.0 🚀latest │ stable │ https://heroui.com │
│ @heroui/styles │ 3.0.0 🚀latest │ stable │ https://heroui.com │
╰──────────────────────────────────────────────────────────────────────────────────────╯
```
### doctor
Check for issues in your project.
* Check whether `@heroui/react` and `@heroui/styles` are installed
* Check whether `required peer dependencies` are installed and matched minimal requirements in the project
```bash
heroui doctor [options]
```
**Options:**
* `-p --packagePath` \[string] The path to the package.json file
**Output:**
If there is a problem in your project, the `doctor` command will display the problem information.
```bash
HeroUI CLI
HeroUI CLI: ❌ Your project has 1 issue that require attention
❗️Issue 1: missingHeroUIPackages
The following HeroUI packages are not installed:
- @heroui/styles
Run `heroui install` to install them.
```
Otherwise, the `doctor` command will display the following message.
```bash
HeroUI CLI
✅ Your project has no detected issues.
```
### env
Display debug information about the local environment.
```bash
heroui env [options]
```
**Options:**
* `-p --packagePath` \[string] The path to the package.json file
**Output:**
```bash
HeroUI CLI
Current installed packages:
╭──────────────────────────────────────────────────────────────────────────────────────╮
│ Package │ Version │ Status │ Docs │
│──────────────────────────────────────────────────────────────────────────────────────│
│ @heroui/react │ 3.0.0 🚀latest │ stable │ https://heroui.com │
│ @heroui/styles │ 3.0.0 🚀latest │ stable │ https://heroui.com │
╰──────────────────────────────────────────────────────────────────────────────────────╯
Environment Info:
System:
OS: darwin
CPU: arm64
Binaries:
Node: v25.8.1
```
## Reporting issues
If you found a bug, please report it in [heroui-cli Issues](https://github.com/heroui-inc/heroui-cli/issues).
# Design Principles
**Category**: react
**URL**: https://www.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
SaveEditCancel
```
| 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
Click me
// Level 2: Enhanced
Submit
// Level 3: Advanced
{isLoading ? <> Loading...> : 'Submit'}
```
### 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
{ // e is properly typed as PressEvent
console.log(e.target);
}}
/>
// Extend types for custom components
interface CustomButtonProps extends Omit {
intent: 'save' | 'cancel' | 'delete';
}
```
### 7. Separation of Styles and Logic
Styles (`@heroui/styles`) are separate from logic (`@heroui/react`), enabling use with any framework or vanilla HTML. See [Tailwind Play example](https://play.tailwindcss.com/vMYXzKPyUx).
```html
Click me
```
or with React:
```tsx
// Apply styles to any component
import { buttonVariants } from '@heroui/styles';
Home
```
### 8. Developer Experience Excellence
Clear APIs, descriptive errors, IntelliSense, AI-friendly markdown docs, and Storybook for visual testing.
### 9. Complete Customization
Beautiful defaults out-of-the-box. Transform the entire look with CSS variables or [BEM](https://getbem.com/) classes. Every slot is customizable.
```css
/* Theme-wide changes with variables */
:root {
--accent: oklch(0.7 0.25 260);
--radius: 0.375rem;
--spacing: 0.5rem;
}
/* Component-specific customization */
@layer components {
.button {
@apply uppercase tracking-wider;
}
.button--primary {
@apply bg-gradient-to-r from-purple-500 to-pink-500;
}
}
```
### 10. Open and Extensible
Wrap, extend, and customize components to match your needs. Use variant functions, direct BEM class application, or create custom wrappers.
**Apply styles with variant functions:**
```tsx
import { Link } from '@heroui/react';
import { linkVariants } from '@heroui/styles';
import NextLink from 'next/link';
// Use variant functions to style framework-specific components
const slots = linkVariants({ underline: "hover" });
About Page
```
**Apply BEM classes directly:**
```tsx
import Link from 'next/link';
// Apply HeroUI's BEM classes directly to any element
Dashboard
```
**Create custom wrapper components:**
```tsx
// Custom wrapper component
const CTAButton = ({
intent = 'primary-cta',
children,
ref,
...props
}: CTAButtonProps) => {
const variantMap = {
'primary-cta': 'primary',
'secondary-cta': 'secondary',
'minimal': 'ghost'
};
return (
{children}
);
};
```
**Extend with Tailwind Variants:**
```tsx
import { Button } from '@heroui/react';
import { buttonVariants, tv } from '@heroui/styles';
// Extend button styles with custom variants
const myButtonVariants = tv({
extend: buttonVariants,
variants: {
variant: {
'primary-cta': 'bg-gradient-to-r from-blue-500 to-purple-600 text-white shadow-lg',
'secondary-cta': 'border-2 border-blue-500 text-blue-500 hover:bg-blue-50',
}
}
});
// Use the custom variants
function CustomButton({ variant, className, ...props }) {
return ;
}
// Usage
Get StartedLearn More
```
## Comparison with HeroUI v2
| Aspect | HeroUI v2 | HeroUI v3 |
| ---------------------------- | ------------------------------------ | ----------------------------------------- |
| **Animations** | Framer Motion | CSS + GPU accelerated |
| **Component Pattern** | Single components with many props | Compound components |
| **Variants** | Visual-based (solid, bordered, flat) | Semantic (primary, secondary, tertiary) |
| **Styling** | Tailwind v4 partially supported | Tailwind v4 fully supported |
| **Accessibility** | Excellent (React Aria powered) | Excellent (React Aria powered) |
| **Bundle Size** | Larger (Bundle) | Smaller (tree-shakeable) |
| **Customization Difficulty** | Medium (Props-based) | Simple (Compound components + Native CSS) |
# Frameworks
**Category**: react
**URL**: https://www.heroui.com/docs/react/getting-started/frameworks
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(overview)/frameworks.mdx
> Integrate HeroUI with your framework
## Next.js
### 1. Create a Next.js project
```bash
npx heroui-cli@latest init
```
When prompted, select the **App** or **Pages** template. Then open your new folder and install dependencies (for example `pnpm install`).
### 2. Use your first HeroUI component
Example: `app/page.tsx`
```tsx
import {Button} from "@heroui/react";
export default function HomePage() {
return (
Hello HeroUI
);
}
```
Example: `pages/index.tsx`
```tsx
import {Button} from "@heroui/react";
export default function HomePage() {
return (
Hello HeroUI
);
}
```
HeroUI v3 does not require a provider. Components work directly after installation and style import.
### 3 Locale Setup (Optional)
To integrate with Next.js, ensure the locale on the server matches the client.
In your root layout, determine the user's preferred language and set the `lang` and `dir` attributes on the `` element.
```tsx
// app/layout.tsx
import {headers} from 'next/headers';
import {isRTL} from '@heroui/react';
import {ClientProviders} from './provider';
export default async function RootLayout({children}) {
// Get the user's preferred language from the Accept-Language header.
// You could also get this from a database, URL param, etc.
const acceptLanguage = (await headers()).get('accept-language');
const lang = acceptLanguage?.split(/[,;]/)[0] || 'en-US';
return (
{children}
);
}
```
Create `app/provider.tsx`. This should render an `I18nProvider` to set the locale used by React Aria.
```tsx
// app/provider.tsx
"use client";
import {I18nProvider} from '@heroui/react';
export function ClientProviders({lang, children}) {
return (
{children}
);
}
```
If you are using a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) (CSP) with a nonce, add a `` tag to your document head, setting the content attribute to the generated nonce value. React Aria automatically reads the nonce from this tag.
## Vite
### 1. Create a Vite project
```bash
npx heroui-cli@latest init
```
When prompted, select the **Vite** template. Then open your new folder and install dependencies (for example `pnpm install`).
### 2. Use your first HeroUI component
Example: `src/App.tsx`
```tsx
import {Button} from "@heroui/react";
function App() {
return (
Hello HeroUI
);
}
export default App;
```
HeroUI v3 does not require a provider. Components work directly after installation and style import.
## Next steps
* [Quick Start](/docs/react/getting-started/quick-start) for the fastest setup path
* [Themes](/docs/react/getting-started/theming) to customize colors and tokens
* [Components](/docs/react/components) to explore all available components
# Quick Start
**Category**: react
**URL**: https://www.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 @heroui/react
```
```bash
pnpm add @heroui/styles @heroui/react
```
```bash
yarn add @heroui/styles @heroui/react
```
```bash
bun add @heroui/styles @heroui/react
```
## 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?
* [Themes](/themes) - Create and share your own themes
* [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
# Agent Skills
**Category**: react
**URL**: https://www.heroui.com/docs/react/getting-started/agent-skills
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(ui-for-agents)/agent-skills.mdx
> Enable AI assistants to build UIs with HeroUI v3 components
HeroUI Skills give your AI assistant comprehensive knowledge of HeroUI v3 components, patterns, and best practices.
### Installation
```bash
curl -fsSL https://heroui.com/install | bash -s heroui-react
```
Or using the skills package:
```bash
npx skills add heroui-inc/heroui
```
Support Claude Code, Cursor, OpenCode and more.
### Usage
Skills are **automatically discovered** by your AI assistant, or call it directly using `/heroui-react` command.
Simply ask your AI assistant to:
* Build components using HeroUI v3
* Create pages with HeroUI components
* Customize themes and styles
* Access component documentation
For more complex use cases, use the [MCP Server](/docs/react/getting-started/mcp-server) which provides real-time access to component documentation and source code.
### What's Included
* HeroUI v3 installation guide
* All HeroUI v3 components with props, examples, and usage patterns
* Theming and styling guidelines
* Design principles and composition patterns
### Structure
```
skills/heroui-react/
├── SKILL.md # Main skill documentation
├── LICENSE.txt # Apache License 2.0
└── scripts/ # Utility scripts
├── list_components.mjs
├── get_component_docs.mjs
├── get_source.mjs
├── get_styles.mjs
├── get_theme.mjs
└── get_docs.mjs
```
### Related Documentation
* [Agent Skills Specification](https://agentskills.io/home) - Learn about the Agent Skills format
* [Claude Agent Skills](https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview) - Claude's Skills documentation
* [Cursor Skills](https://cursor.com/docs/context/skills) - Using Skills in Cursor
* [OpenCode Skills](https://opencode.ai/docs/skills) - Using Skills in OpenCode
# AGENTS.md
**Category**: react
**URL**: https://www.heroui.com/docs/react/getting-started/agents-md
**Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/getting-started/(ui-for-agents)/agents-md.mdx
> Download HeroUI v3 React documentation for AI coding agents
Download HeroUI v3 React documentation directly into your project for AI assistants to reference.
**Note:** The `agents-md` command is specifically for HeroUI React v3. Other CLI commands (like `add`, `init`, `upgrade`, etc.) are for HeroUI v2 (for now).
### Usage
```bash
npx heroui-cli@latest agents-md --react
```
Or specify output file:
```bash
npx heroui-cli@latest agents-md --react --output AGENTS.md
```
### What It Does
* Downloads latest HeroUI v3 React docs to `.heroui-docs/react/`
* Generates an index in `AGENTS.md` or `CLAUDE.md`
* Includes demo files for code examples
* Adds `.heroui-docs/` to `.gitignore` automatically
### Options
* `--react` - Download React docs only
* `--output ` - Target file(s) (e.g., `AGENTS.md` or `AGENTS.md CLAUDE.md`)
* `--ssh` - Use SSH for git clone
### Requirements
* Tailwind CSS >= v4
* React >= 19.0.0
* `@heroui/react >= 3.0.0` or `@latest`
### Related Documentation
* [AGENTS.md](https://agents.md/) - Learn about the AGENTS.md format for coding agents
* [CLAUDE.md](https://code.claude.com/docs/en/best-practices#write-an-effective-claude-md) - Claude equivalent of AGENTS.md
* [AGENTS.md vs Skills](https://vercel.com/blog/agents-md-outperforms-skills-in-our-agent-evals) - AGENTS.md performance
# LLMs.txt
**Category**: react
**URL**: https://www.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://heroui.com/react/llms.txt
```
Or add to your project's `.claude` file for automatic loading.
**Cursor:** Use the `@Docs` feature:
```
@Docs https://heroui.com/react/llms-full.txt
```
[Learn more](https://docs.cursor.com/context/@-symbols/@-docs)
**Windsurf:** Add to your `.windsurfrules` file:
```
#docs https://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://heroui.com/react/llms.txt
```
**For component-specific documentation:**
```
https://heroui.com/react/llms-components.txt
```
**For patterns and best practices:**
```
https://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://www.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.
### Zed
Add the HeroUI server to your `settings.json` configuration file. Open settings via Command Palette (`zed: open settings`) or use `Cmd-,` (Mac) / `Ctrl-,` (Linux):
```json title="settings.json"
{
"context_servers": {
"heroui-react": {
"command": "npx",
"args": ["-y", "@heroui/react-mcp@latest"],
"env": {}
}
}
}
```
After adding the configuration, restart Zed and open the Agent Panel settings view. Check that the indicator dot next to the heroui server is green with "Server is active" tooltip.
See the [Zed MCP documentation](https://zed.dev/docs/ai/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"
{
"servers": {
"heroui-react": {
"type": "stdio",
"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.
### Codex
Add the HeroUI server to your `~/.codex/config.toml` (or a project-scoped `.codex/config.toml`):
```toml title="config.toml"
[mcp_servers.heroui-react]
command = "npx"
args = ["-y", "@heroui/react-mcp@latest"]
```
After adding the configuration, restart Codex and run `/mcp` in the TUI to verify the server is active.
See the [Codex MCP documentation](https://developers.openai.com/codex/mcp) for more details.
### OpenCode
Add the HeroUI server to your project's `opencode.json` configuration file:
```json title="opencode.json"
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"heroui-react": {
"type": "local",
"command": ["npx", "-y", "@heroui/react-mcp@latest"]
}
}
}
```
After adding the configuration, restart OpenCode to activate the MCP server.
See the [OpenCode MCP documentation](https://open-code.ai/docs/en/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 stable or pre-release version.
## Available Tools
The MCP server provides these tools to AI assistants:
| Tool | Description |
| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `list_components` | List all available HeroUI v3 components |
| `get_component_docs` | Get complete component documentation including anatomy, props, examples, and usage patterns for one or more 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_variables` | Access theme variables for colors, typography, spacing with light/dark mode support |
| `get_docs` | Browse the full HeroUI v3 documentation including guides and principles (use path `/docs/react/getting-started/quick-start` for installation instructions) |
## Troubleshooting
**Requirements:** Node.js 22 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)