AI 参与说明(Agent:Codex):本文根据各项目的官方文档、发布记录、许可证与公开包元数据辅助整理。版本与组件目录核验于 2026-08-10;组件、兼容矩阵和许可会变化,请在选型或升级当天重新核对文中的一手链接。本文不把项目方的“production-ready”宣传、GitHub star 或 npm 下载量当作独立的质量或市场份额结论。
React Native 组件库的选择,决定的不只是“按钮长什么样”。它还会影响主题 token 的组织方式、手势与动画依赖、Portal / 弹层行为、无障碍实现、构建链的复杂度,以及未来替换组件库的成本。
本文横向比较五条当前值得评估的路线:Expo UI、HeroUI Native(含 Pro)、React Native Paper、Tamagui 与 gluestack-ui。NativeBase 和 UI Kitten 放在“既有项目与观察对象”部分,而不是和新项目的默认候选混为一谈。
先说结论#
| 你的首要条件 | 优先候选 | 关键代价 |
|---|---|---|
| 使用 Expo SDK 56+,想以最短接入路径获得 iOS / Android 的系统原生控件 | Expo UI(@expo/ui) | 不是完整品牌设计系统;Web 与平台特化 API 要独立验证 |
| 已有 HeroUI Native Pro,想用一套品牌业务 UI,再补少量系统原生体验 | HeroUI Native OSS + 按需 Pro;Expo UI 仅作为受控的原生 UI 岛屿 | 必须明确每个控件、Overlay 和页面由谁负责,不能无边界混用 |
| 只做 iOS / Android,接受 Material Design,想把维护风险压低 | React Native Paper 5.x | 视觉语言偏 Material;不应把仍为 alpha 的 v6 当成生产基线 |
| 真正需要 Web 与 React Native 共用大量 UI 源码、token 与主题体系 | Tamagui 2.x | compiler、Metro / Babel、主题与多包配置的学习和升级面更大 |
| 希望组件源码进入自己的仓库,接受维护上游差异,偏好 Tailwind / Uniwind | gluestack-ui v5,先做 PoC | v5 很新,部分复杂组件和 NativeWind 路线仍有预发布依赖 |
| 已经有 NativeBase / UI Kitten 项目 | 先评估升级与迁移,不要因新项目选型而仓促重写 | NativeBase 是历史维护路线;UI Kitten 的新架构线仍为 beta |
这不是一张“谁最好”的排行榜。对于一个典型业务 App,Material 能否接受、日期选择器和图表是否真的需要、是否要把组件源码掌握在自己手里,往往比“组件数量”更重要。
比较前先分清四件事#
1. “React Native 组件”不等于系统控件#
这些库多数以 React Native 的 View、Text、Pressable 等 Host Components 为基础,再组合样式、手势、动画和可访问性语义。它们不会把 JSX 自动换成 SwiftUI、UIKit 或 Jetpack Compose 控件。
因此,“Native”通常表示它运行在原生 App 中、使用 React Native 的平台渲染与原生能力;它不表示每个按钮都是操作系统自带按钮。React Native 从 React 元素到 Host View 的过程,可参见站内的架构说明与官方渲染管线。
2. UI kit、样式系统与源码生成器不是同一种产品#
| 类型 | 代表 | 你得到什么 | 主要责任 |
|---|---|---|---|
| Expo 管理的原生 UI primitives / bridge | Expo UI | React 中承载 SwiftUI / Jetpack Compose 子树的 Host 与原生控件 | 管理 Host 边界、平台差异与原生 UI 的测试 |
| 成套组件库 | React Native Paper、HeroUI Native | 已实现的组件、主题、Provider 与交互约定 | 跟随库的升级、主题和 API 约束 |
| 跨端样式 / 设计系统平台 | Tamagui | typed styling、tokens、themes、可选 compiler,以及 UI primitives | 配置、编译链和跨端抽象的长期维护 |
| 复制源码的组件方案 | gluestack-ui v5 | CLI 把组件实现拷进项目,团队可直接修改 | 合并上游更新、修复无障碍与安全问题、保持内部一致性 |
除 Expo UI 外,以上传统 UI kit 多数以 React Native 的 View、Text、Pressable 等 Host Components 为基础。Expo UI 是明确例外:React 仍是编写界面的入口,但其 Host 在 iOS 承载 SwiftUI、在 Android 承载 Jetpack Compose;这不是把任意 JSX 编译成 Swift / Kotlin 源文件,而是把一段 React 子树交给平台原生 UI toolkit 渲染。
它们也不替代路由、表单校验、服务端状态、鉴权或应用的领域架构。一个组件库最多是 UI 基础层,不应成为业务 feature 直接到处依赖的“总框架”。
3. Expo 新项目还有一个硬门槛:New Architecture#
Expo SDK 55 起只能运行 React Native New Architecture;选择 UI 库时必须同时检查其全部原生 peer dependency,而不是只看主包能否安装。Expo New Architecture 指南
例如,HeroUI Native 依赖 Reanimated 4;Reanimated 4 只支持 New Architecture,且它与 React Native、Worklets 的版本组合有明确边界。Reanimated 兼容矩阵 Tamagui v2 则在安装文档中直接要求 React Native 0.81+、New Architecture、React 19+ 和 TypeScript 5+。Tamagui 安装要求
无论最终选谁,先在目标 Expo SDK 中运行:
npx expo-doctor@latest
npx expo install --check然后用 development build 和双端 release build 验证;不要只因 Expo Go 打开了一个 Demo,就认为生产组合可用。
2026-08-10 的候选快照#
| 候选 | 本文采用的版本定位 | 许可证 / 获取方式 | 一句话判断 |
|---|---|---|---|
@expo/ui | 跟随 Expo SDK;SDK 56 起 SwiftUI / Jetpack Compose API 稳定,本次文档推荐 ~57.0.9 | MIT;npx expo install @expo/ui | Expo 项目中接入摩擦最低的系统原生 UI 方案;每个原生子树仍需 Host |
heroui-native | 1.0.8,稳定 1.0 线 | Apache-2.0 | 移动端优先、组件风格完整,但仍是年轻项目,应精确锁版本 |
heroui-native-pro | 1.0.0-beta.8,商业 beta | 商业条款;不是开源包 | 为高价值组件补齐日期时间、图表等;可用但不应当作 GA 稳定库 |
react-native-paper | 5.15.3 稳定线;v6 仍为 alpha | MIT | 最成熟、最保守的 Material 设计路线 |
| Tamagui | 2.7.4,v2 主版本 | MIT | 真实跨 Web / Native 设计系统与 UI 源码复用的优先候选 |
| gluestack-ui | v5;@gluestack-ui/core 5.0.15 | MIT | 源码所有权很高,但当前版本新、生态组合要自己验证 |
Expo UI 的稳定状态来自 Expo SDK 56 发布说明与当前组件参考;HeroUI 的稳定 / beta 状态来自其Native 发布记录与Pro 发布记录;Paper 的 v5 / v6 状态应以官方 Releases为准;Tamagui 与 gluestack-ui 的版本和支持边界见其安装文档与 gluestack-ui v5 文档。
版本号只是一次快照。尤其不应把 beta、alpha 或“预览版样式依赖”写成稳定 API 承诺。
不要只看组件数:五条路线各自不可替代的能力#
选型不是“谁的 Button 更多”,而是“这个项目究竟缺少哪一种能力”。下表先把五条路线的真正特色拆开;随后每个小节再展开其技术代价。
| 路线 | 有别于其他候选的能力 | 它实际能解决什么 | 不应误读为 |
|---|---|---|---|
| Expo UI | React 子树直接承载 SwiftUI / Jetpack Compose;RNHostView 可渐进混入 RN 内容;还提供若干社区 UI 库的迁移入口 | 系统设置、原生 Picker / Sheet、已有 BottomSheet / DateTimePicker 等依赖的渐进替换 | 一套完整品牌设计系统,或任何平台控件都能由一份 universal JSX 无差别覆盖 |
| HeroUI Native + Pro | Uniwind / Tailwind v4 的语义 token 与可定制 component slots;compound parts、asChild 与组件提供时的 render props;Pro 的品牌化日期时间、图表和手势控件 | 有一致视觉的业务表单、日期范围规则、移动仪表盘、Wheel / Stepper 等复杂业务交互 | SwiftUI / Compose 系统控件,或内建大数据虚拟列表 / DataGrid |
| React Native Paper | 成套 Material 3 UI、PaperProvider 内的 Portal,以及 adaptNavigationTheme 对接 React Navigation | 企业 / 工具类 App 的 Appbar、Drawer、BottomNavigation、Dialog、Menu、Snackbar、FAB 和统一深浅主题 | 高度中性的品牌基础层,或可虚拟化的专业数据网格 |
| Tamagui | typed tokens、嵌套 theme、styled / unstyled 层,Adapt 可按平台或 media query 改变交互形态;可选 compiler 做静态优化 | 同一套 Web / Native UI 既要共享,又要让桌面 Popover、移动 Sheet 等保持适配 | 安装后所有动态样式都会自动零运行时,或基础使用必须先配置 compiler |
| gluestack-ui v5 | CLI 把所选组件源码放入自己的仓库;Tailwind CSS v4 的 CSS-first token,NativeWind / Uniwind 两条路线 | 团队要审计、深改和长期持有组件内部结构,而非等待库开放 prop | “复制源码”会消除升级、无障碍和安全维护责任 |
这些能力分别来自 Expo UI Universal / drop-in API、HeroUI 的 styling / composition、Paper 的导航主题适配、Tamagui introduction 和 gluestack-ui v5 安装模型。它们是不同层次的优势,不能用一个“组件数量”分数排出绝对高低。
Expo UI:Expo 项目的系统原生 UI 路线#
@expo/ui 不是又一套用 JavaScript 复刻系统控件的主题库。它让 React 组件在 iOS 进入 SwiftUI、在 Android 进入 Jetpack Compose;SDK 56 起,这两条原生 API 已稳定。对于 Expo SDK 56+ 项目,npx expo install 会安装与当前 SDK 匹配的版本,标准组件当前也已包含在匹配版本的 Expo Go 中。Expo SDK 56 Expo UI 概览
它确实是本文所有候选中最容易接入 Expo 项目的一条路线:没有 Tailwind / Uniwind 扫描、Babel compiler、商业鉴权 artifact 或另一套全局 Portal Provider。不过,“最容易安装”不等于“最适合接管所有业务 UI”。Expo UI 的目标是原生 primitives;品牌 tokens、复杂业务变体、图表、数据表格与领域表单封装仍需由应用或另一套主 UI 基础层负责。
三层入口,先选哪一层#
| 入口 | 适用情况 | 运行时实际渲染 | 取舍 |
|---|---|---|---|
@expo/ui | 优先使用;希望同一 React 子树跑在 iOS、Android、Web | iOS → SwiftUI;Android → Jetpack Compose;Web → react-dom 或 react-native-web | Universal API 覆盖的是常见 layout、输入、选择、sheet 与列表 primitives;Web 要单独 QA |
@expo/ui/swift-ui | 需要 iOS 专属控件、modifier 或行为 | SwiftUI | 组件和行为更贴近 Apple 平台,但需要 .ios.tsx 等平台分支 |
@expo/ui/jetpack-compose | 需要 Android 专属控件、modifier 或行为 | Jetpack Compose | 能直接利用 Material 3 / Compose 能力,但同样会产生 Android 特化 |
| 社区兼容入口 | 迁移已有社区控件 API | 对应的原生 Expo UI 实现 | 覆盖 BottomSheet、DateTimePicker、Menu、Pager、Picker、SegmentedControl、Slider 等;迁移前须逐项核对不支持的 prop 与平台差异 |
Universal API 是默认起点;只有通用层没有暴露所需的系统行为时,才直接下沉到 SwiftUI / Compose 入口。Expo 在 SDK 56 的稳定公告中把 universal Web 描述为试验性,因此如果 Web 是正式交付目标,不能因为 iOS / Android 已通过就假定 Web 也达到同一成熟度;要以安装版本的类型、实际浏览器和真实页面单独验收。Expo SDK 56 Universal API Drop-in replacements
社区替代是迁移路径,不是视觉与行为完全同构。以 @expo/ui/community/picker 为例:iOS 使用始终可见的 SwiftUI wheel Picker,Android 使用 Material 3 ExposedDropdownMenuBox,Web 为原生 <select>;它还不支持部分 @react-native-picker/picker props,focus() / blur() 也只在 Android 有效。若产品需求是“点按后弹出选择器”,先在真机验证,或自行用 Sheet / Dialog 组织交互。社区 Picker 迁移边界
最小接入与 Host 的含义#
npx expo install @expo/ui每一个 Expo UI 原生子树都要有 Host。它不是像 Paper 或 HeroUI 那样全局注册主题的 Provider,而是 React Native / Web 布局与 SwiftUI / Compose 布局之间的承载边界:
import { Button, Column, Host, Text } from '@expo/ui';
export function NativeSettingsAction() {
return (
<Host matchContents={{ vertical: true }} seedColor="#6750A4">
<Column spacing={12} style={{ padding: 16 }}>
<Text>系统原生外观的设置操作</Text>
<Button label="保存设置" onPress={() => {}} />
</Column>
</Host>
);
}seedColor 在 Android 会导出 Material 3 调色板、在 iOS 作为 SwiftUI tint;它不是自动读取 HeroUI CSS token 的魔法桥梁。应由应用自己的 token 契约显式把品牌主色、深浅模式等映射到 HeroUI theme 和 Expo UI Host,然后接受两端控件细节会遵循各自系统语言。Host API
Expo UI 也支持用 RNHostView 在原生 UI 子树中容纳一段 React Native 内容。它通过 Host / matchContents 处理这段内容的尺寸边界,适合渐进迁移或让原有业务内容进入一个原生 sheet;但这是一条真实的布局边界,工程上应把它收敛为完整页面或清晰的组件岛,而不是在同一棵树里反复来回嵌套。RNHostView
Expo UI 的能力边界#
- 表单不是无差别替换。
TextInput外形接近 React Native API,但受控value/selection使用useNativeState的 observable state;要用 worklet 消除输入光标闪动,还要接入react-native-worklets。与 React Hook Form、复杂掩码或 HeroUI 字段封装结合前应做小范围适配 PoC。TextInput - 大数据列表另选。 Expo UI 的
List有系统列表外观,但当前 React 仍会预先创建每一行;官方明确建议大列表用 FlashList 或 Legend List。因此它适合设置页、短列表,不是商品流或聊天列表的默认答案。List - BottomSheet 不是像素级同构。 Universal BottomSheet 可以跨端使用,但
fraction/height类型的 snap point 在 iOS / Web 支持更精确;Android 会就近归一到half/full。它适合明确要原生 sheet 的产品需求,不能未经真机验证就替换另一套 Overlay 体系。BottomSheet - Picker 的“wheel”也不是跨端外观承诺。 Universal
Picker的appearance="wheel"只在 iOS 渲染为内联滚轮;Android 与 Web 会退回各自的默认下拉样式。若产品把滚轮交互写进需求,必须做平台分支或接受这个差异。Picker - 导航仍由 Expo Router 负责。 Expo UI 的 TabView / NavigationBar 是局部 UI primitive,不应取代 App 的文件路由、深链与整屏导航。
- 自定义原生 UI 是下一层工作。 内建组件可在匹配版本的 Expo Go 预览;若通过本地 Expo Module 自己写 SwiftUI / Compose view 或 modifier,则要使用 development build,并在变动原生实现后重新构建 iOS / Android binary。EAS Update 只能更新与既有 native runtime 兼容的 JS、样式和资源。Extending with SwiftUI EAS Update
与 HeroUI Native + Pro 的正确组合方式#
对于已经拥有 HeroUI Native Pro 的 Expo 项目,推荐的是“一套主 UI + 少量原生 UI 岛屿”,而不是引入第二套完整设计系统:
| UI 问题 | 默认 owner | 何时改用 Expo UI | 不要做什么 |
|---|---|---|---|
| 品牌化页面、账户、商品、营销、常规表单 | HeroUI Native OSS;复杂日期 / 图表等按需用 Pro | 系统原生体验比品牌一致更重要时 | 同一个 Button / Field 在不同 feature 随意换 owner |
| 跨端 Picker、设置页、局部原生 sheet;或已分别实现 iOS / Android adapter 的平台专属控件 | Expo UI | 需要 SwiftUI / Compose 的真实系统交互或 Expo UI 的替代接口;ColorPicker / ContextMenu 目前要走 iOS SwiftUI 分支,Android 需 DropdownMenu 或自定义等价实现 | 把 Expo UI 当作 HeroUI 的全量主题替身,或假定专属控件跨端同构 |
| Dialog、BottomSheet、Toast 等 Overlay | 该交互选择唯一 owner | Expo UI sheet 的系统行为是明确产品需求时 | 在同一个流程中让 HeroUI Portal 与 Expo UI sheet 争夺呈现和关闭状态 |
| 长列表、图表、业务配置器 | FlashList / 自定义;HeroUI Pro 图表可先验证 | Expo UI 只负责短设置列表或局部系统控件 | 因“原生”把未虚拟化的 Expo UI List 用到大量数据 |
| 产品差异化交互或缺失控件 | 应用自有 adapter / custom component | 需要把自研 SwiftUI / Compose 原生能力接回 React 时 | 让 feature 直接依赖未封装的原生实现 |
这是一项工程建议:每种交互只设一个 owner,并让 feature 只导入应用自有的 src/ui/ adapter。例如 src/ui/hero/DateField.tsx、src/ui/expo/NativePicker.tsx、src/ui/custom/PriceConfigurator.tsx,由应用层决定何时调用谁。这样 HeroUI Pro 的 beta 更新、Expo SDK 升级或自定义原生实现变化不会蔓延到所有业务页面。
ColorPicker 是 iOS SwiftUI 控件;ContextMenu 也只适用于 iOS / tvOS,触发语义是长按。Android 的 Compose DropdownMenu 是按压触发的菜单;如要长按菜单,还需用 combinedClickable 与它组合。因此上表说的“平台专属控件”必须落实为 .ios.tsx / .android.tsx adapter,而不是一个名称相同就默认行为相同的组件。
因此,用户当前倾向的顺序是合理的:HeroUI Native OSS 负责常规品牌业务 UI,Pro 只解决确有价值的复杂控件,Expo UI 负责少数系统原生组件,自定义路线承接剩余产品差异。 是否真的覆盖“大部分”,应由下文的同页 PoC 决定,而不是预先按组件目录或营销文案估算。
HeroUI Native:OSS 做基础,Pro 做有边界的增量#
HeroUI Native 是 React Native 组件库;其公开包为 heroui-native,付费扩展包为 heroui-native-pro。Pro 建立在 OSS 之上,使用同一个 HeroUINativeProvider,不是另一套平行 UI 运行时。
OSS 与 Pro 的组件覆盖#
下表按官网当前的组件目录入口计数,而非 npm export 数:复合组件、Provider、主题工具和内部辅助入口不会完全等于这里的数字。OSS 组件目录 Pro 组件目录
| 类别 | OSS heroui-native(39 项) | Pro heroui-native-pro(44 项) |
|---|---|---|
| Buttons | Button、CloseButton、LinkButton | FAB、ProgressButton、SlideButton、SocialAuthButton、ToggleButton、ToggleButtonGroup |
| Collections / Controls | Menu、TagGroup、Slider、Switch | — |
| Forms | Checkbox、ControlField、Description、FieldError、Input、InputGroup、InputOTP、Label、RadioGroup、SearchField、Select、TextArea、TextField | NumberStepper、NumberField、NumberPad、RadioButtonGroup、WheelPicker、WheelPickerGroup |
| Navigation | Accordion、ListGroup、Tabs | Segment、Stepper、SplitView |
| Overlays | BottomSheet、Dialog、Popover、Toast | — |
| Feedback | Alert、Skeleton、SkeletonGroup、Spinner | NumberValue、ProgressBar、ProgressCircle、Rating、TrendChip |
| Layout / Media / Display | Card、Separator、Surface、Avatar、Chip、Typography、PressableFeedback、ScrollShadow | Badge、EmptyState、FlipCard、Timeline、Widget |
| Charts | — | AreaChart、BarChart、ChartCrosshair、ChartIndicator、ChartTooltip、ComposedChart、LineChart、PieChart、RadarChart、RadialChart |
| Date & Time | — | Calendar、DateField、DatePicker、DateRangePicker、DateTimePicker、RangeCalendar、TimePicker、WheelDateTimePicker、WheelTimePicker |
这套划分很适合“用 OSS 覆盖常规页面,按需用 Pro 购买复杂交互的工程时间”的策略。不要因为已安装 Pro,就默认把每一个业务控件都写成 Pro 依赖;日期、时区、图表、滚轮选择器和 Overlay 的测试面更大,应按真实需求引入。
不只是组件清单:HeroUI 的特殊能力#
| 能力簇 | 可落地的能力 | 什么时候它比 Expo UI / 其他 kit 更合适 | 不能替代什么 |
|---|---|---|---|
| 品牌化基础层 | Uniwind + Tailwind CSS v4、语义 CSS variables、light / dark 主题;所有组件可使用 className / style,需要结构或动态内容扩展时再使用具体组件明确提供的 compound part、asChild / slot 或 render prop | 希望表单、卡片、反馈和品牌状态色可在同一语义 token 下深改,而不是接受系统默认外观 | Host 所承载的 SwiftUI / Compose 系统控件;两边的 theme 必须由应用层显式映射 |
| 复杂日期时间 | Calendar、DatePicker、DateRangePicker、DateTimePicker、WheelDateTimePicker;可表达范围、时间、滚轮和品牌化展示 | 产品需要日期范围、禁用日期、时区 / locale 规则和统一的业务外观 | 系统 DatePicker 的具体平台行为;若这才是需求,应选 Expo UI 平台入口 |
| 移动仪表盘 | 线、柱、面积、饼、雷达、径向和组合图,以及 Crosshair、Indicator、Tooltip | 有品牌化报表、趋势页或管理驾驶舱,且需要从一个组件体系获得图表交互 | 高吞吐实时图形或任意规模数据性能承诺;真实数据量仍要真机 PoC |
| 品牌化手势交互 | WheelPicker、SplitView、Stepper、Progress / Slide Button、NumberPad、Rating 等 | 需要比系统 Picker / Button 更可控、更有产品感的移动交互 | 游戏、CAD 或复杂编辑器的自绘交互;那应进入自有组件或专用渲染方案 |
| 应用级一致性 | Provider 统一 Safe Area、文本 / 输入默认值、Toast / Portal、动画;granular import / provider-raw 可做包体取舍 | HeroUI 是主 UI 基础层,愿意让其负责本应用的 Overlay 与交互约定 | 与第二套 Dialog / BottomSheet / Portal 无边界共存;同一流程必须选一个 owner |
HeroUI 的主题、组合方式、日期、图表与 Portal 能力可分别从 Theming、Styling、Composition、DateRangePicker、Calendar、ChartTooltip、Provider 与 Portal 核对。其实际优势是把这些“业务 UI”收敛到一个品牌体系,而不只是组件目录更长。
相应地,HeroUI 没有通用虚拟化 List / DataGrid 可以替代大量数据的专用列表;大列表仍应使用 FlashList 或自有方案。以 Menu 为例,它在 iOS 原生 modal 叠加时有坐标边界,官方给出了 Safe Area 的规避建议;Popover、Select 等 Overlay 也应在相同场景真机验证。这正是 Overlay 必须唯一 owner 的原因。HeroUI Menu Popover Select
技术底座与最小接入形态#
HeroUI Native 使用 React Native primitives、Uniwind / Tailwind CSS v4、Reanimated、Gesture Handler、Safe Area、SVG 等依赖。包声明 React 19+、React Native 0.81+;当前官方脚手架使用 Expo 57、React Native 0.86.2,这是一份推荐组合快照,不是 HeroUI 对所有 Expo SDK 的最低承诺。HeroUI Native Quick Start
对 Expo 项目,版本应优先由 Expo SDK 对齐,而不是手工把 Reanimated 或 Worklets 升到某个看似更高的版本。因为 Reanimated 4 与 New Architecture、Worklets 有严格兼容范围,错误组合通常会在原生构建或运行时暴露,而不是 TypeScript 编译期。
以下是已经按官方文档配置完 peer dependency 后的示意性根部结构;它不是完整安装教程:
// app/_layout.tsx
import '../global.css';
import { Stack } from 'expo-router';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { HeroUINativeProvider } from 'heroui-native/provider';
export default function RootLayout() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<HeroUINativeProvider>
<Stack />
</HeroUINativeProvider>
</GestureHandlerRootView>
);
}/* global.css */
@import 'tailwindcss';
@import 'uniwind';
@import 'heroui-native/styles';
/* 仅在安装 Native Pro 后添加。 */
@import 'heroui-native-pro/styles';
@source './node_modules/heroui-native-pro/lib';heroui-native 1.0.8 起其 stylesheet 会自行注册 source,因此不必再为 OSS 手写旧的 @source;Pro 目前仍要求 source 配置。路径相对于 global.css,monorepo 或 pnpm hoisting 下务必在无缓存构建中检查样式是否实际被扫描到。HeroUI Native 1.0.8 说明 HeroUI Native Pro 安装
HeroUI Native 还提供 granular import。例如只使用按钮时从 heroui-native/button 导入,并全项目保持这种方式;只要混入一次根入口组件导入,就可能失去该体积优化。Provider 还可通过 provider-raw 减少 Toast / Portal 相关默认能力,但这是需要自己承担对应行为的优化,不是常规起点。Provider 文档
Pro 的授权与 CI 是技术约束,不只是采购问题#
Native Pro 的安装不是单纯从公共 registry 下载:本机先通过 CLI 登录,自动化构建使用仅存在于 CI / EAS secret 中的 token。典型流程如下:
npx heroui-pro@latest login
npx heroui-pro@latest install在 EAS 中应把 CI token 保存为 HEROUI_AUTH_TOKEN secret,例如:
eas env:create --name HEROUI_AUTH_TOKEN --value <CI_TOKEN> --scope project --visibility secret不要把它放进 EXPO_PUBLIC_*、源代码、日志或仓库。HEROUI_PERSONAL_TOKEN 用于本机身份,不能拿来替代 CI token。Yarn Berry PnP 目前不受该安装流程支持;pnpm / Bun 则需要允许 postinstall。正式上线前一定要做一次“无本地缓存、无人工登录”的 CI 构建演练。Native Pro 安装与 CI
许可也需要拆开理解:OSS 是 Apache-2.0;Pro 是商业授权。Native Pro 需要 Mobile Hero 或 Super Hero 权益,不能只凭“Pro”字样推断可用。Individual 许可仅对应一位具名开发者;Team 按能访问 Pro 资产的具名员工或承包商计 seat。最终 App 可以分发,但 Pro 源码、模板和设计资产不能被公开再分发。HeroUI Native LICENSE HeroUI Pro 条款 Native Pro licensing
HeroUI Native 的风险如何看#
它并非“不能用于生产”,但也不应被当作十年历史的严格 semver 库:官方 1.0.5、1.0.8 这类 patch release 都列出 Breaking Changes,Pro beta.8 也有破坏性调整。HeroUI Native 1.0.5 HeroUI Native 1.0.8 Pro beta.8
实际做法是:精确锁定版本(不要让 ^ 自动漂移)、每次升级阅读 release notes、在 iOS 与 Android 做截图和交互回归,并把 feature 对 Pro 的直接依赖收敛到应用自有的 src/ui/ 适配层。
适用:移动端产品、视觉与交互要求高、想快速获得日期时间与图表等复杂控件、团队愿意维护 Expo / Reanimated / Uniwind 组合。
不适用或需谨慎:必须最低维护风险、不能接受商业 beta、无法安全提供 CI token、或者要用同一渲染组件无差别覆盖 Expo Web。HeroUI Native 官方当前不建议用于 Expo Web;如果未来要做 Web,应把它作为单独的渲染实现来规划,而不是把 Native 组件直接移植过去。Quick Start
React Native Paper:最保守的 Material 组件基线#
React Native Paper 的核心价值是成熟的 Material Design 组件、主题系统与相对浅的接入面。当前稳定线是 5.15.3;6.0.0-alpha.0 仍是预发布,且包含 TextInput 重写、FAB API 调整和弃用 API 删除,不应成为新生产项目的默认版本。React Native Paper Releases
它适合表单、列表、设置、内容、工具与企业业务应用:常见的 Button、TextInput、Menu、Dialog、Snackbar、FAB、BottomNavigation 等组件成熟,Material 3 的 light / dark theme 与 React Navigation 也有官方整合路径。Getting started 与 React Navigation 的主题整合
| 维度 | Paper 的取舍 |
|---|---|
| 样式模型 | Theme Provider 与 React Native styles;理解成本较低 |
| 视觉语言 | Material Design 3,能自定义,但默认气质明确 |
| Expo | 官方给出 Expo 使用路径;目标 SDK / 原生依赖组合仍应实际构建验证 |
| 高阶组件 | 常规业务 UI 覆盖强;图表、复杂日期域等不要假定由核心库一次解决 |
| 升级策略 | 固定在 v5 稳定线;把 v6 迁移当作未来专项,而非现在预装 alpha |
适用:团队希望先做稳定业务页面,接受 Material 语言,且不想把样式编译器、商业授权下载或大量原生 peer 变成基础风险。
不适用:产品必须有高度定制的品牌语言,却又不愿投入覆盖层与设计系统;或首要需求就是一组已经封装好的复杂图表、日期 / 时间和定制化选取器。
Paper 的独到能力#
- 完整的 Material 3 业务壳层。 除了基础表单和反馈组件,它还覆盖 Appbar、Drawer、BottomNavigation、FAB、Menu、Dialog、Snackbar 等常见业务 App 骨架;因此企业工具、设置页和内容型产品往往不用先拼很多基础轮子。
- 导航主题能收敛。
adaptNavigationTheme能把 React Navigation 的 light / dark theme 适配到 Paper 的 Material 3 颜色结构,避免导航与页面各有一套深浅模式状态。主题与 React Navigation - Portal 已在基础设施内。
PaperProvider提供 Portal Host,Dialog、Menu、Modal 等 Paper overlay 的接入直接;反过来也意味着,不应把它和 HeroUI 的 Portal 当作同一流程的双默认实现。Portal DataTable是轻量呈现 / 分页能力。DataTable.Pagination很适合管理型短表;官方示例仍由应用切分数据,它不是虚拟化大表格、冻结列或 BI 数据网格的替身。DataTable
Tamagui:当“共享 UI 源码”真的是硬需求#
Tamagui 不只是组件库。它把 typed styling、tokens、themes、可选的 static compiler、styled / unstyled primitives 与 UI kit 放在同一体系中,目标是让 React Native 与 React Web 可共享大量代码。Tamagui introduction
关键是“可选 compiler”:不用 compiler 也能运行,安装它是为了进一步做静态提取与优化;不要把它误解成所有 Tamagui 项目的运行前置条件。Tamagui compiler
| 维度 | Tamagui 的取舍 |
|---|---|
| 样式模型 | typed style props、tokens、nested themes;能把设计系统写得很系统 |
| UI 复用 | 五个候选中最强调 Web / Native 同源组件;也意味着抽象需同时经受两端约束 |
| 原生 / Web 集成 | 可接入原生菜单、Toast、手势等能力;不代表每个 UI 都自动变系统控件 Native integrations |
| 技术门槛 | v2 需要 RN 0.81+、New Architecture、React 19+、TS 5+;核心可走标准 Expo Metro,compiler、monorepo、Web 与原生可选整合才会扩大 Babel / 启动顺序 / 构建配置面 |
| 升级成本 | token、styled primitive 和构建配置通常会深入业务代码;大版本升级要作为工程项目处理 |
适用:一个团队确实要长期维护 React Web 与 Expo / React Native 的同源设计系统,且有能力维护相关构建配置。Expo Router 有官方接入指南,但仍应以本项目的 workspace、Metro 和部署目标做验证。Tamagui Expo guide
不适用:当前只做移动端,又只是想快速做几张页面;此时它解决的问题可能并不存在,却会引入 token、compiler 与跨端 abstraction 的维护负担。
Tamagui 的不可替代能力#
- 同一组件会“适配形态”,不只是响应式缩放。
Adapt可按照平台或 media query 调整交互表现,例如让桌面端的 Popover 在触摸小屏改用 Sheet。这个能力很适合同时有 Web 管理端和移动端的产品。Tamagui introduction - 主题可以嵌套到组件级。 typed tokens 与 nested themes 支持在同一棵树中表达品牌、子品牌或状态主题;主题值既能通过
$token 使用,也能在运行时由useTheme获取。Themes - 既可全套 UI,也可从 primitives 起步。 Tamagui 同时提供 styled / unstyled primitives 和 UI kit;因此它适合想建立内部设计系统,而不是只消费一组固定皮肤的团队。
- compiler 是有边界的优化工具。
@tamagui/static会做部分静态分析、hoisting 和 view flattening;它值得在真实 Web / Native bundle 中量测,但只优化配置范围内可分析的代码,不能承诺所有动态样式都没有运行时成本。Compiler
gluestack-ui v5:源码所有权高,维护责任也高#
gluestack-ui v5 的核心模型接近 shadcn:CLI 把组件代码加入项目,团队可以直接改,而不是只等待库维护者提供 API。它采用 Tailwind CSS v4,支持 NativeWind v5 或 Expo-only 的 Uniwind 路线。gluestack-ui v5 stable 公告
这个模型对“品牌要求极高且必须深改组件”的团队有吸引力,但它不是零成本的自由:一旦组件进入仓库,上游的 bug fix、无障碍修复、破坏性变更和安全升级都要由团队选择性合并与验证。
| 维度 | gluestack-ui v5 的取舍 |
|---|---|
| 所有权 | 组件实现进入自己的仓库,定制边界最大 |
| 样式模型 | Tailwind CSS 4;NativeWind 或 Uniwind,需关注扫描、Metro 与构建链 |
| 成熟度 | v5 于 2026-06 宣布稳定,但仍很新;Calendar、DateTimePicker、Table、Tabs、BottomSheet 等目录项目前标为 alpha |
| 依赖风险 | NativeWind 路线目前仍包含 nativewind@^5.0.0-preview.4 与固定 lightningcss@1.30.1 等要求 |
| 跨 Web 预期 | v5 已不支持 Next.js / universal adapter;不要沿用旧文档中的 universal 承诺 |
这些边界都可在 v5 安装说明、组件成熟度目录和 v5 升级指南中核对。
适用:要长期持有组件源码、设计系统团队能承诺维护、并且先完成目标 Expo / Android / iOS 的 PoC。
不适用:希望“装完就少维护”、依赖当前 Next.js 通用渲染、或核心需求正好落在仍标 alpha 的复杂组件。
gluestack-ui v5 的特殊能力与成熟度边界#
- “拿进仓库再改”是它最核心的能力。 CLI 的
add流程把选中的组件实现放到项目的components/ui,团队能直接改变内部结构、可访问性文案或产品交互,而不是等待库暴露新的 prop。它尤其适合已有设计系统团队、需要做源码审计或想控制长期 fork 的项目。v5 安装 - CSS-first token 与两条样式引擎路线。 v5 的 Tailwind CSS v4 token 集中在
global.css;NativeWind v5 与 Expo-only Uniwind 是不同的工程路径。Uniwind 不需要 PostCSS,但只适用于 Expo;两条路径都应在目标 monorepo / Metro 中实测。v5 stable 公告 - 可作为可拆取的组件材料库。 组件目录含响应式组件、Image Viewer、Chat AI、Calendar、DateTimePicker、BottomSheet 等高阶材料;
Chat AI是可通过 CLI 加入的聊天界面组件集,文档以 Vercel AI SDK 与外部 / 自建 API 的接线为例。它本身不是模型、鉴权、后端或流式传输服务。Chat AI 组件目录 - 成熟度要按组件看。 gluestack-ui v5 已宣布 stable,不代表所有附加组件都同等成熟:其目录仍将 Grid、Table、Tabs、Calendar、DateTimePicker、BottomSheet、Liquid Glass、Image Viewer、Skeleton 等标为 alpha。NativeWind v5 也仍为预发布,因此不能让这两类能力成为首期关键路径的唯一依赖。组件目录 NativeWind v5
既有项目与观察对象:NativeBase、UI Kitten#
NativeBase:迁移背景,而不是新基座#
NativeBase 并没有突然无法使用,但官方已经把新项目方向引向 gluestack-ui,并说明 gluestack-ui 是为改善 NativeBase v3 的性能与可维护性问题而重写的路线。对已有 NativeBase 项目,应以稳定维护、逐页迁移或继续观察为目标;新项目不应把它列为默认候选。NativeBase 文档 Road ahead with gluestack-ui
UI Kitten:正在现代化,但新架构线仍未 GA#
UI Kitten 稳定 dist-tag 仍是 5.3.1,但在 2026-08-07 已发布 6.0.0-beta.2,声明支持 React 19、React Native 0.81、Expo 54、ESM 与 New Architecture。这不是“已废弃”,但也不能把 beta 当成稳健的 Expo 新项目默认项;如果 Eva Design System 是硬需求,先用目标 SDK 做真机与无障碍 PoC,并等待 GA 状态更清晰。UI Kitten 官网 v6 beta Releases
五条主路线的横向比较#
将“方案”放在行而不是列,能更准确表达 Expo UI 与传统 UI kit 不同的架构定位:
| 路线 | 核心模型 | 代表性特色能力 | Expo 接入与渲染 | 最适合 | 关键边界 |
|---|---|---|---|---|---|
| Expo UI | Expo 管理的原生 UI primitives / bridge | SwiftUI / Compose 子树、RNHostView、社区控件迁移入口(逐项核对差异) | expo install + Host;iOS SwiftUI、Android Compose | 系统设置页、跨端 Picker / Sheet,以及已验证平台分支的原生控件 | 不是完整品牌 kit;Web 与平台特化能力另测;大列表不选其 List |
| HeroUI Native OSS + Pro | 完整品牌组件库,Pro 为高阶增量 | 语义 token / slots、品牌化日期范围与图表、Wheel / SplitView | Uniwind、Reanimated、手势及 Provider | 已有 Pro 权益、移动产品优先、需要品牌表单 / 日期 / 图表 | Pro beta、原生 peer 和 CI 授权下载需严格管理 |
| React Native Paper 5.x | Material 3 完整组件库 | App 壳层、Portal、adaptNavigationTheme、轻量 DataTable | Theme Provider + 常规 RN / Expo 路径 | 保守稳定、接受 Material 的业务 App | 默认视觉语言强,复杂图表 / 品牌设计仍需补充 |
| Tamagui 2.x | 跨 Web / Native 样式系统 + UI kit + 可选 compiler | nested themes、Adapt、styled / unstyled primitives、静态优化 | 核心可用标准 Expo Metro;复杂场景再接 compiler / 原生集成 | 长期共用 Web / Native 组件源码 | 只做移动时往往过重;升级和构建配置面较大 |
| gluestack-ui v5 | CLI 将组件源码复制进项目 | 源码所有权、CSS-first token、可拆取的高阶组件材料 | Tailwind CSS 4 + NativeWind 或 Uniwind | 愿意持有并深改组件源码的团队 | v5 新、部分组件 alpha;上游升级由团队承担 |
用决策树缩小候选,再做 PoC#
flowchart TD
A["开始选 React Native UI 基础层"] --> B{"是否必须长期复用 Web 与 Native 的组件源码?"}
B -- "是" --> C["优先 Tamagui 2.x\n验证 compiler / Metro / Web 部署"]
B -- "否" --> D{"Expo SDK 56+ 且系统原生交互优先?"}
D -- "是" --> E{"还需要成套品牌 UI、日期 / 图表等高阶业务控件?"}
E -- "否" --> F["Expo UI 为主\n用 Host 与真机 PoC 验证平台行为"]
E -- "是" --> G["HeroUI OSS 为主 + 按需 Pro\nExpo UI 仅做受控原生 UI 岛屿"]
D -- "否" --> H{"是否接受 Material Design,且维护风险最优先?"}
H -- "是" --> I["优先 React Native Paper 5.x"]
H -- "否" --> J{"是否必须把组件源码放进本仓库深改?"}
J -- "是" --> K["gluestack-ui v5 PoC\n团队承担上游合并"]
J -- "否" --> L["先以 HeroUI / Paper / Expo UI\n在同一真实页面做 PoC"]这个流程故意没有把“GitHub stars 多”或“组件目录更多”作为分支条件。UI 库最常见的失败不是少一个按钮,而是上线后才发现复杂 Select、输入法、弹层、无障碍、Android 返回键或主题升级不符合真实产品。
建议的 PoC:不要比较 Demo,要比较同一张真实页面#
对每个候选实现同一组最小页面,再在同一台代表性 iPhone 与中低端 Android 上比对:
- 登录 / 注册表单:密码、错误提示、焦点恢复、软键盘避让、提交 loading。
- 长列表详情:图片、筛选、空状态、滚动性能、深色模式。
- 编辑页面:日期 / 时间、复杂选择器、校验、底部操作栏。
- Overlay:Dialog、Popover、BottomSheet、Toast,以及 Android 返回键和原生 modal 叠加。
- 无障碍:VoiceOver、TalkBack、Dynamic Type / 字体放大、Reduce Motion、RTL、键盘焦点与颜色对比。
验收时至少回答以下问题:
- Expo development build、iOS release、Android release 是否都能干净构建?
- 依赖升级后
expo-doctor是否仍健康? - 每个 Overlay 是否能恢复焦点、关闭后是否留下不可点区域?
- 动画、图表、日期时间在低端 Android、时区、Locale 和大字号下是否仍正确?
- Expo UI 的
Host/RNHostView边界是否在键盘、Safe Area、屏幕旋转和动态内容高度下保持正确布局? - 同一类控件是否有唯一 owner,例如一个流程只用 HeroUI 或 Expo UI 的 BottomSheet,而非两个都可打开?
- Expo UI 的受控输入能否与实际表单状态、校验和错误展示正确协作?短设置列表之外是否仍使用虚拟化列表?
- Pro 包在没有本机缓存、没有交互登录的 EAS CI 中是否可重复安装?
- 包体、冷启动、滚动与内存是否在真实数据量下达标?
测试不应只靠 screenshot。截图回归适合发现 HeroUI 这类视觉 / token 变更;还需要自动化交互测试与真机人工无障碍测试。组件库提供 ARIA-style props、screen reader props 或主题 API,不等于产品已经通过 VoiceOver / TalkBack 验收。
落地架构:让 UI 库可替换#
不管选哪一个,建议 feature 不直接遍地导入第三方组件,而是建立应用自己的 UI 入口:
src/
├── features/
│ ├── orders/
│ └── profile/
├── ui/
│ ├── Button.tsx
│ ├── FormField.tsx
│ ├── DateInput.tsx
│ ├── AppDialog.tsx
│ ├── expo/
│ │ ├── NativePicker.tsx
│ │ └── NativeSettingsSheet.tsx
│ ├── hero/
│ │ ├── BrandButton.tsx
│ │ └── Chart.tsx
│ ├── custom/
│ │ └── PriceConfigurator.tsx
│ └── charts/
├── design/
│ ├── tokens.ts
│ └── theme.ts
└── platform/
├── keyboard.ts
└── accessibility.ts这不是为了把每一个第三方 API 重新发明一遍,而是为了把最可能变的部位收口:Button 变体、字段错误呈现、Dialog 行为、日期值格式、图表数据适配与品牌 tokens。将来 HeroUI Pro beta、Expo UI 的 API / Host 行为、Material theme、Tamagui styled primitive 或 gluestack copied component 发生变化时,影响面才不会扩散到所有业务页面。
同一应用通常不要同时引入两套完整 UI kit。两个 Provider、Portal、theme、字体默认值、手势与 Overlay 体系会互相增加不可预测性。Expo UI 可以例外地作为边界清晰的原生 UI 岛屿共存,因为它不是另一套全局主题 / Portal 基础设施;但仍要规定每个控件和 Overlay 的唯一 owner。正确的组合更接近“一套主 UI 基础层 + 少量专用、经过评估的原生平台能力”。
结合当前前提的建议#
如果移动端是近期目标、使用 Expo,且 HeroUI Native Pro 已经是现有资产,最务实的起点不是再把 Paper、Tamagui 或 gluestack-ui 一起装进项目,而是先固定这条边界:
- HeroUI Native OSS 是默认业务 UI 基础层;仅在日期 / 时间、图表、Wheel、Stepper 等真实缺口使用 Pro。
- Expo UI 先做四个很小的技术尖峰:系统设置页、单选 Picker、一个 native BottomSheet、一个受控输入。每个尖峰都在 iPhone 和 Android 真机验证键盘、深色模式、字体放大、关闭行为与表单状态。
- 把 Expo UI 通过
src/ui/expo/、HeroUI 通过src/ui/hero/暴露给 feature;同一控件类型只能有一个默认 owner。 - 上述两层均不能满足、且需求是产品差异化时,再用
src/ui/custom/自建。若自定义到 SwiftUI / Compose,接受 development build、原生二进制重建和双端测试成为正常成本。
这个方案能够把已有 HeroUI Pro 资产兑现为品牌业务页面,又让 Expo UI 提供真正的 SwiftUI / Compose 逃生口;它比“引入第三套完整 kit”更统一。唯一不应预先承诺的是覆盖率:先以真实的编辑页、设置页和 overlay 页面做 PoC,再确认剩余定制量。
只有当“Web 与 Native 共用同一套组件实现”是长期、明确且可验收的目标时,才应把 Tamagui 提到第一候选。若重视完全掌握组件源码,再看 gluestack-ui v5;它是把维护权交给团队,不是把维护工作消失。
延伸阅读#
参考资料#
- HeroUI Native Quick Start、组件目录、Provider、1.0.8 发布说明
- HeroUI Native Pro 组件目录、安装与 CI、Pro licensing、商业条款
- Expo UI 概览、SDK 56 稳定版说明、Universal API、Host、RNHostView
- Expo UI TextInput、List 性能边界、BottomSheet 跨端边界、社区兼容组件、自定义 SwiftUI 扩展
- Expo New Architecture、Reanimated compatibility
- React Native Paper 官方仓库、发布记录、Getting started、Portal、DataTable
- Tamagui introduction、Themes、安装要求、Expo guide、compiler、Native integrations
- gluestack-ui v5 stable、安装说明、组件目录、升级指南、NativeWind v5 状态
- NativeBase 的迁移说明、UI Kitten v6 beta Releases