Pro--% off in--d : --h : --m : --s
HeroUI

Introducing HeroUI v3

A ground-up rewrite for React and React Native. 75+ web components, 37 native components, Tailwind CSS v4, React Aria, compound architecture, and built for AI-assisted development.

March 2026

Every component rewritten. Every animation moved to CSS. Styles decoupled from implementation. A brand-new React Native library. And tooling that treats AI assistants as a primary development interface.

Overview

React (Web)

75+ components. React Aria Components for accessibility. Tailwind CSS v4 + CSS variables for theming. Styles in a standalone package you can use with any framework.

Jump to details

React Native

37 components with shared design tokens, compound pattern, unified animation API, and adaptive presentation modes. Built native on each platform with Uniwind for Tailwind CSS v4 support.

Jump to details

HeroUI Pro

HeroUI Pro

Premium components, templates, and AI tooling for React and React Native. Command palette, Kanban, DataGrid, Dashboard templates, and more. Pre-sale pricing at heroui.pro.

Jump to details

Design Principles

Composition over configuration: v2 components were black boxes. v3 adopts compound components: every internal piece is a real element you can style, move, swap, or remove.

Styles separated from implementation: @heroui/styles is standalone CSS. @heroui/react handles behavior. Use the styles with React, plain HTML + Tailwind, or any framework. BEM class names make every slot customizable globally. Swap themes to change not just variables, but how components look and feel.

Headless when you want it: Remove the @heroui/styles import and you have a headless library. We maintain functionality and accessibility. You focus on your product.

Performance by default: v2 used Framer Motion for every animation. v3 replaced it with native CSS transitions and keyframes. Lighter bundles, GPU-accelerated, no JS animation runtime.

Accessible from the start: Migrated from React Aria hooks to React Aria Components. Keyboard navigation, focus management, screen readers, and ARIA attributes are built in.

Compound Components

Here's what the compound pattern looks like in practice:

<Card>
  <Card.Header>
    <Card.Title>Product</Card.Title>
    <Card.Description>Details about this product.</Card.Description>
  </Card.Header>
  <Card.Body>
    <p>Card content goes here.</p>
  </Card.Body>
  <Card.Footer>
    <Button variant="primary">Buy now</Button>
  </Card.Footer>
</Card>

More lines of code. But every piece is a real element you can style, move, or replace. The pattern runs through the entire library, from Accordion to Toast.

import {
  ArrowsRotateLeft,
  Box,
  ChevronDown,
  CreditCard,

Each compound component shares state through React context. The root component creates a style context, and every child consumes it. You never pass classNames down manually:

<Alert status="success">
  <Alert.Indicator />
  <Alert.Content>
    <Alert.Title>Profile updated</Alert.Title>
    <Alert.Description>Your changes have been saved.</Alert.Description>
  </Alert.Content>
</Alert>

New features available

Check out our latest updates including dark mode support and improved accessibility features.

Update available

A new version of the application is available. Please refresh to get the latest features and bug fixes.

Unable to connect to server

We're experiencing connection issues. Please try the following:
  • Check your internet connection
  • Refresh the page
  • Clear your browser cache

Profile updated successfully

Processing your request

Please wait while we sync your data. This may take a few moments.

Scheduled maintenance

Our services will be unavailable on Sunday, March 15th from 2:00 AM to 6:00 AM UTC for scheduled maintenance.
import {Alert, Button, CloseButton, Spinner} from "@heroui/react";
import React from "react";

export function Basic() {
  return (

Progressive Disclosure

Components support both simple and compound usage. Start with the one-liner. Add structure when you need it:

// One line
<Button>Submit</Button>

// With icon
<Button>
  <Icon icon="gravity-ui:check" />
  Submit
</Button>

// Full control
<Button variant="primary" size="lg" isDisabled={isLoading}>
  {isLoading ? <Spinner size="sm" /> : <Icon icon="gravity-ui:check" />}
  {isLoading ? "Saving..." : "Submit"}
</Button>
import {Button} from "@heroui/react";

export function Variants() {
  return (
    <div className="flex flex-wrap gap-3">

Tailwind CSS v4 + CSS Variables

Theming runs on Tailwind CSS v4's native CSS variable layer with OKLCH colors. Every design token is a CSS variable:

:root {
  --background: oklch(0.9702 0 0);
  --foreground: oklch(0.2103 0.0059 285.89);
  --accent: oklch(0.6204 0.195 253.83);
  --surface: oklch(100% 0 0);
  --danger: oklch(0.6532 0.2328 25.74);
  --radius: 0.5rem;
}

Tailwind's @theme directive maps these tokens to utility classes. bg-accent, text-foreground, rounded-lg all resolve to CSS variables. Light and dark mode switch by swapping the values:

.dark, [data-theme="dark"] {
  --background: oklch(12% 0.005 285.823);
  --foreground: oklch(0.9911 0 0);
  --surface: oklch(0.2103 0.0059 285.89);
}

No provider component. No JavaScript theme object. One CSS import, two lines:

@import "tailwindcss";
@import "@heroui/styles";

BEM Classes

Override any component globally through standard CSS:

@layer components {
  .button {
    @apply font-semibold tracking-wide;
  }

  .button--primary {
    @apply bg-blue-600 hover:bg-blue-700;
  }
}

No className threading. No style prop gymnastics. Your design system overrides happen in CSS, where they belong.

Custom Themes

Create a theme by defining your own token set. Everything cascades from there:

@layer base {
  [data-theme="ocean"] {
    --accent: oklch(0.450 0.150 230);
    --background: oklch(0.985 0.015 225);
    --radius: 0.75rem;
    --border: oklch(0.50 0.060 230 / 22%);
  }
}

Apply it with a single data attribute:

<html data-theme="ocean">

The Theme Builder generates these variables visually. Pick colors, adjust radius and spacing, export the CSS.

Selective Imports

Import the full library or pick individual component styles:

@import "tailwindcss";
@import "@heroui/styles/base" layer(base);
@import "@heroui/styles/themes/default" layer(theme);
@import "@heroui/styles/components/button.css" layer(components);
@import "@heroui/styles/components/card.css" layer(components);

Ship only the CSS you use. No unused component styles in production.

Animation That Respects Users

All component animations use CSS transitions and keyframes tied to data attributes. Popovers fade in with [data-entering]. Buttons scale on [data-pressed]. Accordions expand with [aria-hidden="false"].

.popover[data-entering] {
  @apply animate-in zoom-in-90 fade-in-0 duration-200;
}

.button:active,
.button[data-pressed="true"] {
  transform: scale(0.97);
}

Reduce Motion

Some users need animations disabled. HeroUI extends Tailwind's motion-reduce: variant to support both the system preference and a data attribute:

.button {
  @apply transition-colors motion-reduce:transition-none;
}

This responds to the native prefers-reduced-motion: reduce media query. It also responds to data-reduce-motion="true" on the HTML element, for app-level control:

<html data-reduce-motion="true">
  <!-- All HeroUI animations are disabled -->
</html>

The data attribute overrides the system setting. Set data-reduce-motion="false" to force animations on, or remove the attribute to defer to the OS. Every animated component respects this. No opt-in required.

Bring Your Own Animation Library

Framer Motion, Motion One, or any CSS animation library works alongside HeroUI's built-in transitions:

import { motion } from "framer-motion";
import { Button } from "@heroui/react";

const MotionButton = motion(Button);

<MotionButton whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }}>
  Animated
</MotionButton>

75+ Components for React

Date & Time

Six components: Calendar, RangeCalendar, DateField, DatePicker, DateRangePicker, and TimeField. Built on React Aria's internationalized date library with Gregorian, Buddhist, Persian, and other calendar systems by default. Keyboard navigation, screen reader labels, and locale-aware formatting come free.

Date
"use client";

import {Calendar, DateField, DatePicker, Label} from "@heroui/react";

export function Basic() {

Trip dates, March 2026

23
24
25
26
27
28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
"use client";

import {RangeCalendar} from "@heroui/react";

export function Basic() {

Color

Six color components: ColorPicker, ColorArea, ColorSlider, ColorField, ColorSwatch, and ColorSwatchPicker. Pick from a 2D area, adjust hue and alpha sliders, enter hex values, or select from a swatch palette.

import {ColorArea, ColorPicker, ColorSlider, ColorSwatch, Label} from "@heroui/react";

export function Basic() {
  return (
    <ColorPicker defaultValue="#0485F7">

Data

Need a table with sorting, row selection, column resizing, async loading, and custom cells? Table does all of that. Large datasets get virtualization via React Aria's Virtualizer. ListBox shares the same virtualization support.

Name
Emma Smith
"use client";

import {Table, TableLayout, Virtualizer} from "@heroui/react";

interface User {

Forms

Thirteen form components: TextField, Select, Autocomplete, ComboBox, Checkbox, CheckboxGroup, RadioGroup, Switch, InputOTP, NumberField, SearchField, Slider, and Fieldset. All integrate with React Aria's form validation. isRequired, isInvalid, and custom error messages through FieldError work across every one.

State
import {Label, ListBox, Select} from "@heroui/react";

export function Default() {
  return (
    <Select className="w-[256px]" placeholder="Select one">

We've sent a code to a****@gmail.com

Didn't receive a code?

Resend
import {InputOTP, Label, Link} from "@heroui/react";

export function Basic() {
  return (
    <div className="flex w-[280px] flex-col gap-2">

Overlays

Seven overlay components. Drawer supports four placements with drag-to-dismiss gestures. Toast stacks notifications with auto-dismiss and promise support. Menu composes with submenus and sections. Plus Modal, AlertDialog, Popover, and Tooltip.

import {Button, Drawer} from "@heroui/react";

export function Basic() {
  return (
    <Drawer>
"use client";

import {Persons} from "@gravity-ui/icons";
import {Button, toast} from "@heroui/react";

Tabs, Accordion, Breadcrumbs, Pagination, and Link. Tabs support horizontal and vertical orientation. Accordion supports single or multiple expanded panels.

View your project overview and recent activity.

import {Tabs} from "@heroui/react";

export function Basic() {
  return (
    <Tabs className="w-full max-w-md">

Feedback

ProgressBar and ProgressCircle handle determinate + indeterminate states. Meter maps values to semantic colors: green for safe, yellow for cautious, red for critical. Skeleton and Spinner round out the set.

Default50%
Accent50%
Success50%
Warning50%
Danger50%
import {Label, Meter} from "@heroui/react";

export function Colors() {
  return (
    <div className="flex w-64 flex-col gap-6">
import {Skeleton} from "@heroui/react";

export function Basic() {
  return (
    <div className="shadow-panel w-[250px] space-y-5 rounded-lg bg-transparent p-4">

Buttons & Toggles

Button, ButtonGroup, ToggleButton, ToggleButtonGroup, CloseButton, and Toolbar. ButtonGroup connects buttons with shared borders and supports vertical orientation. Toolbar groups buttons, toggles, and separators into an accessible role="toolbar" container.

Attached (default)
Detached
import {Bold, Italic, Strikethrough, Underline} from "@gravity-ui/icons";
import {ToggleButton, ToggleButtonGroup} from "@heroui/react";

export function Attached() {
  return (

Granular Imports

Import from the root or from per-component subpaths. Both work:

// Root import
import { Button, Card, Table } from "@heroui/react";

// Subpath import
import { Button } from "@heroui/react/button";
import { Card } from "@heroui/react/card";
import { Table } from "@heroui/react/table";

UI for Agents

More developers build by prompting than by reading API docs. HeroUI v3 accounts for that.

MCP Server

The HeroUI MCP Server connects AI coding assistants (Cursor, Claude Code, VS Code Copilot, Windsurf, Zed) to component docs, props, source code, CSS styles, and theme variables. The AI reads the source of truth directly instead of guessing from training data.

{
  "mcpServers": {
    "heroui-react": {
      "command": "npx",
      "args": ["-y", "@heroui/react-mcp@latest"]
    }
  }
}

Ask your AI assistant "update HeroUI to the latest version" and it will compare versions, review the changelog for breaking changes, and apply the necessary code updates automatically.

Agent Skills

Installable knowledge packs for Cursor and Claude Code. Component patterns, variant usage, theming instructions, and upgrade guides. Preloaded context so the AI writes correct HeroUI code on the first attempt.

LLMs.txt

Structured documentation files optimized for AI context windows. Published at /llms.txt and /llms-components.txt, these give any LLM-powered tool a machine-readable summary of HeroUI's API surface.

MCP server, agent skills, LLMs.txt. Three layers that give AI assistants the same access to HeroUI that human developers get from docs.

HeroUI Native

HeroUI Native is a brand-new library shipping alongside v3 for the web. Different rendering engine, same mental model. Where the platforms diverge, the APIs adapt to feel native on each.

Try It on Your Device

Scan the QR code with your device's camera or Expo Go to explore all 37 components live:

Expo Go QR Code

Android users: If scanning the QR code redirects to a browser and shows a 404 error, open Expo Go first and use its built-in QR scanner instead.

37 Components

Forms, navigation, overlays, feedback, layout. From Button, Input, and Checkbox to Dialog, BottomSheet, Select, Toast, and InputOTP. Components follow the compound pattern:

import { Dialog, Button } from "heroui-native";

<Dialog>
  <Dialog.Trigger asChild>
    <Button variant="primary">Open</Button>
  </Dialog.Trigger>
  <Dialog.Portal>
    <Dialog.Overlay />
    <Dialog.Content>
      <Dialog.Close />
      <Dialog.Title>Confirm action</Dialog.Title>
      <Dialog.Description>This cannot be undone.</Dialog.Description>
    </Dialog.Content>
  </Dialog.Portal>
</Dialog>

Familiar Across Platforms

If you know HeroUI on the web, most of that knowledge carries over. Familiar component names, dot notation, and prop patterns wherever possible. Where the platforms diverge (layout primitives, gestures, navigation), the APIs adapt to feel native. The mental model stays the same:

// React (web)
<Alert status="success">
  <Alert.Indicator />
  <Alert.Content>
    <Alert.Title>Profile updated</Alert.Title>
    <Alert.Description>Your changes have been saved.</Alert.Description>
  </Alert.Content>
</Alert>

// React Native — similar API, native behavior
<Alert status="success">
  <Alert.Indicator />
  <Alert.Content>
    <Alert.Title>Profile updated</Alert.Title>
    <Alert.Description>Your changes have been saved.</Alert.Description>
  </Alert.Content>
</Alert>

Teams working on both web and mobile share knowledge and patterns. The learning curve between platforms is minimal, even where the components differ.

Shared Design Tokens

Both platforms read from the same token set. Colors like accent, surface, danger, and success resolve identically across web and native. Your brand stays consistent without maintaining two separate systems.

import { View, Text } from "react-native";

<View className="bg-surface p-4 rounded-lg">
  <Text className="text-foreground text-lg font-semibold">Card Title</Text>
  <Text className="text-muted text-sm">Consistent on web and mobile.</Text>
</View>

Tailwind CSS v4 on both platforms. Uniwind on native, standard Tailwind on web.

Unified Animation API

Every animated native component exposes a single animation prop. Values, timing, spring configs, enter/exit transitions controlled from one place. Reanimated powers the math, but you never touch it directly:

import { Switch } from "heroui-native";

<Switch
  animation={{
    scale: { value: [1, 0.9] },
    backgroundColor: { value: ["#172554", "#eab308"] },
  }}
>
  <Switch.Thumb />
</Switch>

Disable animations at any level. Per-component, per-tree, or globally:

// Single component
<Switch.Thumb animation={false} />

// Entire subtree
<Card animation="disable-all">...</Card>

// App-wide
<HeroUINativeProvider config={{ animation: "disable-all" }}>
  <App />
</HeroUINativeProvider>

Reduce Motion is automatic. When a user enables it in system settings, all animations stop. No extra code.

Adaptive Presentation Modes

Popover, Select, and Menu switch between popover, bottom-sheet, and dialog with a single prop. Same component, different presentation depending on context:

<Select presentation="popover">...</Select>
<Select presentation="bottom-sheet">...</Select>
<Select presentation="dialog">...</Select>

No other React Native component library does this.

Granular Imports

Each native component has its own entry point. Import only what you use:

import { HeroUINativeProvider } from "heroui-native/provider";
import { Button } from "heroui-native/button";
import { Card } from "heroui-native/card";

AI Tooling for Native

HeroUI Native ships with its own MCP Server, agent skills, and LLMs.txt. Same tooling structure as the web library:

{
  "mcpServers": {
    "heroui-native": {
      "command": "npx",
      "args": ["-y", "@heroui/native-mcp@latest"]
    }
  }
}

HeroUI Pro

HeroUI Pro

Alongside v3, the pre-sale of HeroUI Pro is live. Premium components, templates, and AI tooling for both React and React Native.

Pro Components

Components beyond the core library: Command palette, Kanban board, Stats dashboard, Filters, Agenda, DataGrid, and more. Accessibility, animations, and platform edge cases are handled. Will be available for both Web and Native.

Templates

Full-page, responsive starter templates: Dashboard, Mail, Chat, and Finances. Real layouts with real structure. Start from something that works and customize from there.

Advanced AI Tooling

Pro licenses include premium MCP servers and agent skills with Pro component docs, usage patterns, and upgrade paths baked in.

Pre-sale pricing is live. v2 Pro customers get an upgrade discount. Use the same email or contact support.

See plans and pricing at heroui.pro

Get Started

React (Web)

npm i @heroui/styles @heroui/react
pnpm add @heroui/styles @heroui/react
yarn add @heroui/styles @heroui/react
bun add @heroui/styles @heroui/react

Add two lines to your CSS:

@import "tailwindcss";
@import "@heroui/styles";

React Native

npm install heroui-native
pnpm add heroui-native
yarn add heroui-native
bun add heroui-native

See the React docs and React Native docs for full setup guides (peer dependencies, Uniwind config, and provider setup).

Coming from HeroUI v2? Follow the Migration Guide for step-by-step upgrade instructions.

Figma Kit v3

Every component in HeroUI v3 has a 1:1 match in Figma. Same variants, same naming, same structure. The kit uses auto layout throughout, Figma variables that map directly to code tokens (--accent, --surface, --radius), and Figma's new slots for flexible component composition. Designers rearrange, swap, and customize parts the same way developers do in code.

HeroUI Figma Kit v3

Get the Figma Kit

Acknowledgments

React Aria gave us the accessibility layer we couldn't build as well on our own. Tailwind CSS v4's native CSS variable approach shaped the entire theming system. The compound component pattern was refined by studying how Radix, Ark UI, and Base UI solved composition.

Thanks to every community member who filed issues, tested betas, and gave feedback throughout the alpha and RC cycle. The library is better because of you.

On this page