跳到主要内容

HeroUI

HeroUI 就是原来的 NextUI。进入 v3 之后,这套库的定位已经更清楚了:它不是单纯给 React 项目补几个漂亮按钮,而是一套建立在 Tailwind CSS v4、React Aria Components 和 CSS variables 之上的完整组件体系。

如果 Tailwind 更像“设计语言底座”,那 HeroUI 更像“现成可落地的设计系统成品层”。

HeroUI 现在更适合怎么理解

HeroUI v3 有几层比较关键的变化:

  • React Web 和 React Native 都有独立路线
  • Web 端样式和实现解耦
  • @heroui/styles 负责样式
  • @heroui/react 负责组件和行为
  • 主题、变量、组件样式都围绕 Tailwind v4 组织

这意味着现在看 HeroUI,重点已经不是“它原来叫 NextUI”,而是:

  • 它能不能快速接进 React 项目
  • 默认视觉是否足够成熟
  • Tailwind 项目里能不能自然定制
  • 组件、主题、交互是否足够统一

什么时候很适合选 HeroUI

适合

  • React 项目已经准备使用 Tailwind v4
  • 需要一套默认完成度比较高的组件库
  • 不想从 Base UI / Radix 这种 headless 方案自己拼完整视觉层
  • 需要按钮、弹层、表单、导航、数据展示这整套能力
  • 希望主题变量和 Tailwind token 统一

不太适合

  • 项目不是 React 主线
  • 团队完全不想使用 Tailwind
  • 想做极度轻量、极度原生的最小组件层
  • 设计语言已经非常固定,更适合自建一套业务组件

先看版本主线

截至目前,HeroUI 主线已经进入 v3。

官方 release 页面提到的重点包括:

  • 全量重写组件
  • 样式和组件实现拆分
  • 基于 Tailwind CSS v4
  • 基于 React Aria Components
  • 组件写法更偏 compound components
  • Web 与 Native 拆成更清楚的两条线

如果项目里还在使用早期 NextUI 的 mental model,迁移时最好把这层变化单独看一遍。

最小安装方式

HeroUI Web 端最基础的依赖是两部分:

pnpm add @heroui/styles @heroui/react

官方 Quick Start 里给出的要求是:

  • React 19+
  • Tailwind CSS v4

在 Vite + React 项目里怎么接

这是最容易落地的一种方式。

1. 先装 Tailwind

pnpm add tailwindcss @tailwindcss/vite

2. 配 vite.config.ts

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'

export default defineConfig({
plugins: [react(), tailwindcss()],
})

3. 安装 HeroUI

pnpm add @heroui/styles @heroui/react

4. 在主样式文件引入

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

顺序要注意:Tailwind 在前,HeroUI 在后。

5. 直接使用组件

import { Button, Card } from '@heroui/react'

export function App() {
return (
<main className="mx-auto flex min-h-screen max-w-5xl items-center justify-center px-6 py-12">
<Card className="w-full max-w-md p-6">
<h1 className="text-xl font-semibold">HeroUI in Vite</h1>
<p className="mt-2 text-sm text-zinc-600">组件样式已经 ready,Tailwind 依然可以继续往上叠。</p>
<Button className="mt-4">提交</Button>
</Card>
</main>
)
}

在 Next.js App Router 里怎么接

HeroUI 和 Next.js 的组合也很常见。

1. 安装 Tailwind PostCSS 链路

pnpm add tailwindcss @tailwindcss/postcss postcss

2. 配置 postcss.config.mjs

export default {
plugins: {
'@tailwindcss/postcss': {},
},
}

3. 安装 HeroUI

pnpm add @heroui/styles @heroui/react

4. 在 app/globals.css 引入样式

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

5. 在组件里直接使用

import { Button } from '@heroui/react'

export default function Page() {
return (
<section className="p-8">
<Button>保存</Button>
</section>
)
}

主题切换和 next-themes

如果项目要做浅色 / 深色切换,HeroUI 官方文档里给出的常见做法是配合 next-themes

安装

pnpm add next-themes

包一层 Provider

// app/providers.tsx
"use client"

import { ThemeProvider } from 'next-themes'

export function Providers({ children }: { children: React.ReactNode }) {
return (
<ThemeProvider attribute="class" defaultTheme="light">
{children}
</ThemeProvider>
)
}

接到 layout.tsx

import './globals.css'
import { Providers } from './providers'

export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="zh-CN" suppressHydrationWarning>
<body className="bg-background text-foreground">
<Providers>{children}</Providers>
</body>
</html>
)
}

这种组合的好处是:

  • Tailwind 的 dark: 写法还能继续用
  • HeroUI 的主题变量也能跟着切
  • 页面主体背景和文本颜色可以统一接 bg-backgroundtext-foreground

HeroUI 的样式结构怎么理解

HeroUI v3 的关键点之一,是样式已经被拆成独立包。

全量引入

这是官方最推荐、也是最省心的方式:

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

按层拆开引入

如果项目很在意样式边界,也可以按 layer 拆:

@layer theme, base, components, utilities;

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

这种方式适合:

  • 想自己控制主题层顺序
  • 只想引入部分组件样式
  • 准备搭更完整的企业级设计系统

最常见的前端集成方式

1. 直接使用组件 + Tailwind 微调

import { Button } from '@heroui/react'

export function SaveButton() {
return (
<Button className="rounded-full px-5 font-medium shadow-none">
保存修改
</Button>
)
}

HeroUI v3 已经回到标准 className 语义,不需要再用早期比较绕的 classNames 对象心智。

2. 用 @layer components 改全局组件样式

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

.button--primary {
@apply shadow-none;
}
}

这一层适合统一全项目视觉,而不是在每个页面都手动覆盖一次。

3. 用包装组件补业务变体

import { Button, buttonVariants } from '@heroui/react'
import { tv } from 'tailwind-variants'
import type { ButtonProps } from '@heroui/react'

const appButton = tv({
extend: buttonVariants,
variants: {
tone: {
brand: 'bg-sky-600 text-white hover:bg-sky-700',
quiet: 'bg-zinc-100 text-zinc-900 hover:bg-zinc-200',
},
},
})

type AppButtonProps = ButtonProps & {
tone?: 'brand' | 'quiet'
}

export function AppButton({ tone = 'brand', className, ...props }: AppButtonProps) {
return <Button className={appButton({ tone, className })} {...props} />
}

如果项目已经有一层业务设计语言,这种封装会比到处散着覆写更稳。

主题定制怎么做

HeroUI 当前的主题体系核心在:

  • CSS variables
  • data-theme
  • Tailwind @theme
  • BEM 风格类名

最小改色示例

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

:root {
--accent: oklch(0.7 0.25 260);
--success: oklch(0.65 0.15 155);
}

自定义语义色并暴露给 Tailwind

: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);
}

@theme inline {
--color-info: var(--info);
--color-info-foreground: var(--info-foreground);
}

这之后就能直接写:

<div className="bg-info text-info-foreground">状态提示</div>

常用搭配和插件

HeroUI 自己不是 Tailwind 插件式组件库了,v3 更偏 CSS-first,所以项目里常见的搭配工具也会更明确。

常用搭配

  • next-themes:主题切换
  • clsx + tailwind-merge:业务组件 className 合并
  • tailwind-variants:变体抽象
  • 图标库:@iconify/reactlucide-react

什么时候会考虑 CLI

HeroUI 也有 CLI,适合:

  • 想快速起模板
  • 想批量添加组件
  • 想让项目自动补依赖和基础配置

如果当前项目已经是成熟仓库,很多团队还是会更倾向手动接入,因为样式层和目录结构更可控。

在真实项目里最常见的组件组合

HeroUI 比较容易先落地的通常是:

  • Button
  • Input
  • Modal / Drawer
  • Tabs
  • Dropdown / Select
  • Card
  • Table

原因很简单:这些组件既能立刻提升完成度,又最容易暴露“自研很费时间”的成本。

和 Tailwind 的关系怎么理解

Tailwind 负责:

  • 设计 token
  • utility classes
  • 页面布局
  • 局部微调

HeroUI 负责:

  • 组件行为
  • 可访问性
  • 默认视觉
  • 组件 API

所以更稳的组合一般不是“Tailwind 和 HeroUI 二选一”,而是:

  • Tailwind 作为底座
  • HeroUI 作为成品组件层
  • 业务组件再往上包一层

常见误区

1. 想把 HeroUI 当成完全零样式底座

这不太对。

HeroUI 是有明确视觉倾向的。如果项目目标是极度自定义的品牌设计系统,Base UI 这类 headless 方案可能更合适。

2. 每个页面都手动 patch 组件样式

这样一开始很快,后面会很乱。更稳的是:

  • 统一变量
  • 统一 @layer components
  • 统一包装组件

3. 对旧 NextUI 心智照搬

v3 最大的变化之一,就是样式体系和 API 更标准了。尤其是 className、主题变量、样式导入方式,都应该按新文档重新理解。

一个更实际的接入顺序

  1. 先把 Tailwind v4 跑通
  2. 接入 @heroui/styles@heroui/react
  3. 先落 Button、Input、Modal、Card
  4. 再补 next-themes
  5. 最后决定哪些组件要做业务包装

参考来源