Base UI
无样式、可访问的 React 组件库,以细粒度 Parts、状态属性和灵活组合能力构建设计系统。
项目概述
Base UI 由 MUI 团队维护,但不附带 Material Design 或默认 CSS。它提供 Dialog、Menu、Popover、Combobox、Select、Toast、Field 等可访问组件原语,并支持任意样式方案、复杂弹层定位、表单验证和自定义渲染。
Base UI 是 MUI 团队维护的一套无样式 React 组件库。它不等同于 Material UI,也不是已经停止发展的旧 MUI Base 包;当前正式包名是 @base-ui/react。组件以 Root、Trigger、Portal、Positioner、Popup、Item 等细粒度 Parts 组合,负责 WAI-ARIA 语义、键盘导航、焦点管理、弹层定位、表单状态和 Pointer 交互,而视觉完全交给应用。每个 Part 可通过 className、Style Function、data-* Attribute、CSS Variable 和 render Prop 定制。所有组件包含在一个可 Tree Shaking 的包中,当前稳定版为 1.7.0,支持 React 17、18 和 19。shadcn/ui 新项目也已把 Base UI 作为默认底层原语之一。
主要特点
Base UI 将复杂控件拆成可组合的 React Parts,并提供状态、定位、表单和无障碍基础,让团队保留完整视觉控制权。
完全无样式
组件不打包 CSS,也不继承 Material Design,可与 Tailwind CSS、CSS Module、CSS-in-JS 或普通 CSS 配合。
可访问性基础
遵循 WAI-ARIA Authoring Practices,处理角色、属性、键盘导航、焦点和 Pointer 交互等复杂细节。
细粒度 Parts
Root、Trigger、Portal、Backdrop、Positioner、Popup、Arrow 与 Item 等 Parts 可以按产品需要重组。
Render Prop 组合
通过 render Prop 替换底层 HTML Element,或与 Link、Button 和自有组件组合,同时合并行为 Props。
状态属性与 CSS 变量
data-open、data-highlighted、data-disabled 等属性和定位 CSS Variable 为纯 CSS 状态样式提供稳定钩子。
弹层定位
Popover、Menu、Select、Tooltip 和 Combobox 提供 Side、Align、Offset、Collision、Arrow 与 Anchor 控制。
焦点与 Portal 管理
Dialog 等组件处理 Focus Trap、Initial/Final Focus、背景 Inert、Scroll Lock 和 Portal Container。
受控与非受控状态
组件通常同时提供 value/defaultValue、open/defaultOpen 与回调,便于局部状态或业务状态接管。
Event Details
状态变更回调提供触发原因和原始事件等信息,应用可区分 Escape、外部点击、Trigger 或程序化操作。
原生表单扩展
Field、Form 与输入组件扩展 HTML Constraint Validation,并可集成 React Hook Form 和 TanStack Form。
动画生命周期
通过 Data Attribute 暴露进入、离开和状态阶段,可使用 CSS Transition、Keyframes 或 JavaScript 动画库。
广泛组件目录
覆盖 Accordion、Autocomplete、Combobox、Context Menu、Dialog、Drawer、Menu、Navigation Menu、Select、Toast 等应用控件。
单包与 Tree Shaking
所有组件从 @base-ui/react 的子路径导入,Bundler 只保留实际使用的模块。
TypeScript 泛型推导
Combobox、Select 等组件能够根据 Items 与 Value 推导类型,便于构建安全的业务 Wrapper。
适用场景
它适合只面向 React、拥有自有设计语言,并需要比高层 Headless Component 更细控制的产品与设计系统。
企业设计系统
把 Base UI Parts 封装为带 Design Token、主题、尺寸和品牌交互规范的内部组件。
SaaS 与复杂后台
使用 Combobox、Select、Menu、Dialog、Drawer、Toast 和 Number Field 构建高密度产品界面。
shadcn/ui 新项目
作为 shadcn/ui 新默认体系的底层行为原语,继续在应用仓库中拥有并修改上层组件源码。
复杂筛选与选择器
利用 Autocomplete、Combobox、多选、分组、Chip 与定位能力实现实体搜索和批量选择。
品牌化弹层体系
统一 Dialog、Popover、Tooltip、Menu、Context Menu 和 Navigation Menu 的层级、动画与定位。
表单与验证系统
结合 Field、Form、Checkbox、Radio、Select、Slider 和 Number Field 构建原生或第三方表单工作流。
渐进迁移设计系统
逐个替换自研行为组件,同时保留现有 CSS、DOM 结构和产品视觉,减少一次性重写风险。
优点与注意事项
技术选型不仅要看能力,也要理解它带来的团队成本。
主要优点
Base UI 擅长的地方
- 无默认 CSS 和 Material 视觉,团队不需要先覆盖主题再实现自己的设计语言。
- 复杂键盘、焦点、Portal、弹层定位和 Pointer 行为由库统一处理。
- 细粒度 Parts 与 render Prop 提供较高的 DOM 和组件组合自由度。
- Data Attribute、CSS Variable 和 State Function 适配多种样式技术。
- 组件目录广,覆盖常见 Headless Library 容易缺少的 Drawer、Toast、Autocomplete 和表单能力。
- 支持 React 17、18 和 19,方便不同升级阶段的应用采用。
- 单一包配合子路径导入和 Tree Shaking,安装与版本管理相对直接。
- 与 shadcn/ui 新默认组件体系的协同降低了源码组件方案的集成成本。
- MIT 许可证宽松,适合商业产品、设计系统和开源项目。
需要注意
采用前应考虑的问题
Base UI 官方组件面向 React;Vue、Svelte、Solid 或原生 Web 项目需要选择其他实现。
正式包是 @base-ui/react,旧 @mui/base 和更早的 @base-ui-components/react 不是当前安装入口。
团队必须自行实现 Theme、Spacing、Focus Ring、Disabled、Loading、Invalid、Dark Mode 和动画。
复杂组件的 Anatomy 包含 Portal、Positioner、Popup、Viewport 和多类 Item,新成员需要理解各自职责。
自定义 Element 需要保留合并后的 Ref、事件、ARIA 和 Data Attribute,否则可能破坏交互或无障碍。
应用根节点、Isolation、Z-Index、Shadow Root 和自定义 Container 要统一,否则弹层可能被遮挡或逃离主题范围。
部分非原生控件通过 Hidden Input 参与提交和校验,应正确设置 Name、Label、Relative Container 和 Ref。
业务拦截关闭或选择时,应根据 Event Details 判断原因,避免破坏 Escape、外部点击和焦点恢复。
项目仍在高频增加组件和修复复杂交互,升级前应阅读 Release Notes 并执行键盘、视觉和表单回归。
互动、测量、Portal 和 Focus 管理依赖浏览器环境;Next.js 等项目通常要在适当层级使用 Client Component。
应用仍需提供准确 Label、Description、Error 和状态文案,并使用真实辅助技术测试完整流程。
Tree Shaking 能减少未使用代码,但复杂页面引入多个 Popup 与 Form 模块后仍应分析生产 Bundle。
快速开始
下面安装单一 @base-ui/react 包,配置 Portal 层级,并使用 Dialog、Menu 与 Field 展示组合、状态样式和表单验证。
bashnpm install @base-ui/reactcss.app-root {
isolation: isolate;
}
/* Portal 默认挂载到 body,可自然显示在应用根节点之上。 */tsximport { Dialog } from "@base-ui/react/dialog";
export function NotificationDialog() {
return (
<Dialog.Root>
<Dialog.Trigger className="button">
查看通知
</Dialog.Trigger>
<Dialog.Portal>
<Dialog.Backdrop className="fixed inset-0 bg-black/40" />
<Dialog.Viewport className="fixed inset-0 grid place-items-center p-4">
<Dialog.Popup className="w-full max-w-md rounded-xl bg-white p-6 shadow-xl">
<Dialog.Title className="text-lg font-semibold">
通知
</Dialog.Title>
<Dialog.Description className="mt-2 text-sm text-zinc-600">
你已经处理完所有待办事项。
</Dialog.Description>
<Dialog.Close className="button mt-6">
关闭
</Dialog.Close>
</Dialog.Popup>
</Dialog.Viewport>
</Dialog.Portal>
</Dialog.Root>
);
}tsximport { Menu } from "@base-ui/react/menu";
export function AccountMenu() {
return (
<Menu.Root>
<Menu.Trigger className="button">账户</Menu.Trigger>
<Menu.Portal>
<Menu.Positioner sideOffset={8} align="end">
<Menu.Popup className="w-44 rounded-lg border bg-white p-1 shadow-lg">
<Menu.Item className="rounded px-3 py-2 data-[highlighted]:bg-zinc-100">
个人资料
</Menu.Item>
<Menu.Item className="rounded px-3 py-2 data-[highlighted]:bg-zinc-100">
退出登录
</Menu.Item>
</Menu.Popup>
</Menu.Positioner>
</Menu.Portal>
</Menu.Root>
);
}tsximport { Field } from "@base-ui/react/field";
export function WebsiteField() {
return (
<Field.Root name="website">
<Field.Label>网站地址</Field.Label>
<Field.Control
type="url"
required
pattern="https?://.*"
placeholder="https://example.com"
/>
<Field.Error match="valueMissing">
请输入网站地址
</Field.Error>
<Field.Error match="patternMismatch">
地址必须以 http:// 或 https:// 开头
</Field.Error>
</Field.Root>
);
}bashnpm run lint
npm run typecheck
npm test
npm run build
# 测试键盘、VoiceOver/NVDA、浏览器缩放、移动端滚动和高对比度
# 验证 Portal 层级、长 Dialog、表单提交和所有动画离场状态下一步:先按官方 Anatomy 复制最小结构,再封装成团队自己的 Design System Component;不要遗漏 Label、Description、Portal、Positioner 和 Focus 状态,并用真实键盘与屏幕阅读器验证。
类似项目
这些站内项目覆盖其他 Headless Primitive、源码组件方案、样式工具和 React 生态;外部项目则提供不同层次的可访问性交互抽象。
Radix UI
无样式、可访问且高度可组合的 React UI 原语,为设计系统处理焦点、键盘和复杂交互。
查看项目Headless UI
Tailwind Labs 提供的无样式、可访问 UI 组件库,为 React 与 Vue 处理键盘、焦点和复杂交互行为。
查看项目Ark UI
基于 Zag.js 状态机的无样式、可访问组件库,支持 React、Vue、Solid 与 Svelte。
查看项目shadcn/ui
把可访问、可组合的组件源码直接加入项目,由团队完整拥有和定制的 UI 分发平台。
查看项目Tailwind CSS
以实用类为核心的 CSS 框架,快速构建定制化界面。
查看项目React
用于构建 Web 和原生用户界面的组件化 JavaScript 库。
查看项目React Aria
Adobe 提供的可访问 React Hooks 与组件体系,强调国际化和跨设备输入。
访问官网Ariakit
面向 React 的低层可访问组件工具包,强调 WAI-ARIA 模式与灵活组合。
访问官网Base UI vs Radix UI
Base UI 与 Radix UI 都为 React 提供无样式、可访问、可组合的组件原语。Base UI 的组件目录、表单系统、Render API 和事件细节更具自身特色;Radix UI 生态成熟,并长期作为 shadcn/ui 的主要底层方案。
| 比较维度 | Base UI | Radix UI |
|---|---|---|
| 核心定位 | 无样式 React 组件与设计系统基础 | 无样式 React 行为 Primitives |
| 维护团队 | MUI 团队 | WorkOS / Radix 团队与贡献者 |
| 组件安装 | 单一 @base-ui/react 包,使用子路径导入 | 统一 radix-ui 包或按 Primitive 单独安装 |
| 组件目录 | 包含 Autocomplete、Drawer、Form、Number Field 等广泛控件 | Dialog、Popover、Select、Tooltip、Toast 等成熟 Primitive |
| 组合 API | 细粒度 Parts + render Prop | Parts + asChild / Slot 组合模式 |
| 状态样式 | Data Attribute、CSS Variable、Class/Style State Function | 丰富的 data-state、data-side 等 Attribute |
| 表单能力 | Field、Form、原生 Constraint 与自定义验证整合较深 | 各输入 Primitive 参与表单,常结合第三方 Form Library |
| 状态回调 | Event Details 暴露 Event、Reason 和拦截能力 | 通过 OnOpenChange、OnValueChange 等回调管理状态 |
| shadcn/ui | 新项目当前默认原语之一 | 长期成熟基础,仍是重要选择 |
| 生态成熟度 | 快速发展,组件与 API 持续扩展 | 采用时间更长,社区示例与封装更多 |
| 许可证 | MIT | MIT |
| 更适合 | 需要广组件、表单能力和新 shadcn 默认栈的 React 团队 | 看重成熟生态、稳定 Primitive 和既有 shadcn 方案的团队 |
如果新项目采用 shadcn/ui 的 Base UI 默认栈,或需要 Autocomplete、Drawer、Form、Number Field 和 Event Details 等能力,优先评估 Base UI;如果已有大量 Radix Wrapper、依赖成熟生态或需要其特定 Primitive,继续使用 Radix UI 通常更稳妥。两者都不提供视觉设计,最终选择应通过组件清单、无障碍测试、弹层边界和迁移成本验证。
资料核验
版本、维护信息与本页采用的官方资料来源。
npm 官方元数据核验的 @base-ui/react 稳定版为 1.7.0,支持 React 17、18 和 19,许可证为 MIT。官方文档确认所有组件位于单一可 Tree Shaking 包中,并支持任意样式方案、WAI-ARIA 键盘行为和焦点管理;官方仓库未归档,核验当天仍有公开代码提交。
官方仓库未归档,核验时最近可见的代码活动日期为 2026 年 8 月 20 日。该状态表示项目近期仍有公开维护活动,不代表固定发布频率或长期支持承诺。