React Native UI 方案横评:Expo UI、HeroUI Native、Paper、Tamagui 与 gluestack-ui

This article is extracted from the chat log with AI. Please identify it with caution.

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.xcompiler、Metro / Babel、主题与多包配置的学习和升级面更大
希望组件源码进入自己的仓库,接受维护上游差异,偏好 Tailwind / Uniwindgluestack-ui v5,先做 PoCv5 很新,部分复杂组件和 NativeWind 路线仍有预发布依赖
已经有 NativeBase / UI Kitten 项目先评估升级与迁移,不要因新项目选型而仓促重写NativeBase 是历史维护路线;UI Kitten 的新架构线仍为 beta

这不是一张“谁最好”的排行榜。对于一个典型业务 App,Material 能否接受、日期选择器和图表是否真的需要、是否要把组件源码掌握在自己手里,往往比“组件数量”更重要。

比较前先分清四件事#

1. “React Native 组件”不等于系统控件#

这些库多数以 React Native 的 ViewTextPressable 等 Host Components 为基础,再组合样式、手势、动画和可访问性语义。它们不会把 JSX 自动换成 SwiftUI、UIKit 或 Jetpack Compose 控件。

因此,“Native”通常表示它运行在原生 App 中、使用 React Native 的平台渲染与原生能力;它不表示每个按钮都是操作系统自带按钮。React Native 从 React 元素到 Host View 的过程,可参见站内的架构说明官方渲染管线

2. UI kit、样式系统与源码生成器不是同一种产品#

类型代表你得到什么主要责任
Expo 管理的原生 UI primitives / bridgeExpo UIReact 中承载 SwiftUI / Jetpack Compose 子树的 Host 与原生控件管理 Host 边界、平台差异与原生 UI 的测试
成套组件库React Native Paper、HeroUI Native已实现的组件、主题、Provider 与交互约定跟随库的升级、主题和 API 约束
跨端样式 / 设计系统平台Tamaguityped styling、tokens、themes、可选 compiler,以及 UI primitives配置、编译链和跨端抽象的长期维护
复制源码的组件方案gluestack-ui v5CLI 把组件实现拷进项目,团队可直接修改合并上游更新、修复无障碍与安全问题、保持内部一致性

除 Expo UI 外,以上传统 UI kit 多数以 React Native 的 ViewTextPressable 等 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.9MIT;npx expo install @expo/uiExpo 项目中接入摩擦最低的系统原生 UI 方案;每个原生子树仍需 Host
heroui-native1.0.8,稳定 1.0 线Apache-2.0移动端优先、组件风格完整,但仍是年轻项目,应精确锁版本
heroui-native-pro1.0.0-beta.8,商业 beta商业条款;不是开源包为高价值组件补齐日期时间、图表等;可用但不应当作 GA 稳定库
react-native-paper5.15.3 稳定线;v6 仍为 alphaMIT最成熟、最保守的 Material 设计路线
Tamagui2.7.4,v2 主版本MIT真实跨 Web / Native 设计系统与 UI 源码复用的优先候选
gluestack-uiv5;@gluestack-ui/core 5.0.15MIT源码所有权很高,但当前版本新、生态组合要自己验证

Expo UI 的稳定状态来自 Expo SDK 56 发布说明当前组件参考;HeroUI 的稳定 / beta 状态来自其Native 发布记录Pro 发布记录;Paper 的 v5 / v6 状态应以官方 Releases为准;Tamagui 与 gluestack-ui 的版本和支持边界见其安装文档gluestack-ui v5 文档

版本号只是一次快照。尤其不应把 betaalpha 或“预览版样式依赖”写成稳定 API 承诺。

不要只看组件数:五条路线各自不可替代的能力#

选型不是“谁的 Button 更多”,而是“这个项目究竟缺少哪一种能力”。下表先把五条路线的真正特色拆开;随后每个小节再展开其技术代价。

路线有别于其他候选的能力它实际能解决什么不应误读为
Expo UIReact 子树直接承载 SwiftUI / Jetpack Compose;RNHostView 可渐进混入 RN 内容;还提供若干社区 UI 库的迁移入口系统设置、原生 Picker / Sheet、已有 BottomSheet / DateTimePicker 等依赖的渐进替换一套完整品牌设计系统,或任何平台控件都能由一份 universal JSX 无差别覆盖
HeroUI Native + ProUniwind / 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 和统一深浅主题高度中性的品牌基础层,或可虚拟化的专业数据网格
Tamaguityped tokens、嵌套 theme、styled / unstyled 层,Adapt 可按平台或 media query 改变交互形态;可选 compiler 做静态优化同一套 Web / Native UI 既要共享,又要让桌面 Popover、移动 Sheet 等保持适配安装后所有动态样式都会自动零运行时,或基础使用必须先配置 compiler
gluestack-ui v5CLI 把所选组件源码放入自己的仓库;Tailwind CSS v4 的 CSS-first token,NativeWind / Uniwind 两条路线团队要审计、深改和长期持有组件内部结构,而非等待库开放 prop“复制源码”会消除升级、无障碍和安全维护责任

这些能力分别来自 Expo UI Universal / drop-in APIHeroUI 的 styling / compositionPaper 的导航主题适配Tamagui introductiongluestack-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、WebiOS → SwiftUI;Android → Jetpack Compose;Web → react-domreact-native-webUniversal 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 Pickerappearance="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该交互选择唯一 ownerExpo 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.tsxsrc/ui/expo/NativePicker.tsxsrc/ui/custom/PriceConfigurator.tsx,由应用层决定何时调用谁。这样 HeroUI Pro 的 beta 更新、Expo SDK 升级或自定义原生实现变化不会蔓延到所有业务页面。

ColorPickeriOS 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 项)
ButtonsButton、CloseButton、LinkButtonFAB、ProgressButton、SlideButton、SocialAuthButton、ToggleButton、ToggleButtonGroup
Collections / ControlsMenu、TagGroup、Slider、Switch
FormsCheckbox、ControlField、Description、FieldError、Input、InputGroup、InputOTP、Label、RadioGroup、SearchField、Select、TextArea、TextFieldNumberStepper、NumberField、NumberPad、RadioButtonGroup、WheelPicker、WheelPickerGroup
NavigationAccordion、ListGroup、TabsSegment、Stepper、SplitView
OverlaysBottomSheet、Dialog、Popover、Toast
FeedbackAlert、Skeleton、SkeletonGroup、SpinnerNumberValue、ProgressBar、ProgressCircle、Rating、TrendChip
Layout / Media / DisplayCard、Separator、Surface、Avatar、Chip、Typography、PressableFeedback、ScrollShadowBadge、EmptyState、FlipCard、Timeline、Widget
ChartsAreaChart、BarChart、ChartCrosshair、ChartIndicator、ChartTooltip、ComposedChart、LineChart、PieChart、RadarChart、RadialChart
Date & TimeCalendar、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 能力可分别从 ThemingStylingCompositionDateRangePickerCalendarChartTooltipProviderPortal 核对。其实际优势是把这些“业务 UI”收敛到一个品牌体系,而不只是组件目录更长。

相应地,HeroUI 没有通用虚拟化 List / DataGrid 可以替代大量数据的专用列表;大列表仍应使用 FlashList 或自有方案。以 Menu 为例,它在 iOS 原生 modal 叠加时有坐标边界,官方给出了 Safe Area 的规避建议;PopoverSelect 等 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.36.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 业务壳层。 除了基础表单和反馈组件,它还覆盖 AppbarDrawerBottomNavigationFAB、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 UIExpo 管理的原生 UI primitives / bridgeSwiftUI / Compose 子树、RNHostView、社区控件迁移入口(逐项核对差异)expo install + Host;iOS SwiftUI、Android Compose系统设置页、跨端 Picker / Sheet,以及已验证平台分支的原生控件不是完整品牌 kit;Web 与平台特化能力另测;大列表不选其 List
HeroUI Native OSS + Pro完整品牌组件库,Pro 为高阶增量语义 token / slots、品牌化日期范围与图表、Wheel / SplitViewUniwind、Reanimated、手势及 Provider已有 Pro 权益、移动产品优先、需要品牌表单 / 日期 / 图表Pro beta、原生 peer 和 CI 授权下载需严格管理
React Native Paper 5.xMaterial 3 完整组件库App 壳层、Portal、adaptNavigationTheme、轻量 DataTableTheme Provider + 常规 RN / Expo 路径保守稳定、接受 Material 的业务 App默认视觉语言强,复杂图表 / 品牌设计仍需补充
Tamagui 2.x跨 Web / Native 样式系统 + UI kit + 可选 compilernested themes、Adapt、styled / unstyled primitives、静态优化核心可用标准 Expo Metro;复杂场景再接 compiler / 原生集成长期共用 Web / Native 组件源码只做移动时往往过重;升级和构建配置面较大
gluestack-ui v5CLI 将组件源码复制进项目源码所有权、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 上比对:

  1. 登录 / 注册表单:密码、错误提示、焦点恢复、软键盘避让、提交 loading。
  2. 长列表详情:图片、筛选、空状态、滚动性能、深色模式。
  3. 编辑页面:日期 / 时间、复杂选择器、校验、底部操作栏。
  4. Overlay:Dialog、Popover、BottomSheet、Toast,以及 Android 返回键和原生 modal 叠加。
  5. 无障碍: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 一起装进项目,而是先固定这条边界:

  1. HeroUI Native OSS 是默认业务 UI 基础层;仅在日期 / 时间、图表、Wheel、Stepper 等真实缺口使用 Pro
  2. Expo UI 先做四个很小的技术尖峰:系统设置页、单选 Picker、一个 native BottomSheet、一个受控输入。每个尖峰都在 iPhone 和 Android 真机验证键盘、深色模式、字体放大、关闭行为与表单状态。
  3. 把 Expo UI 通过 src/ui/expo/、HeroUI 通过 src/ui/hero/ 暴露给 feature;同一控件类型只能有一个默认 owner。
  4. 上述两层均不能满足、且需求是产品差异化时,再用 src/ui/custom/ 自建。若自定义到 SwiftUI / Compose,接受 development build、原生二进制重建和双端测试成为正常成本。

这个方案能够把已有 HeroUI Pro 资产兑现为品牌业务页面,又让 Expo UI 提供真正的 SwiftUI / Compose 逃生口;它比“引入第三套完整 kit”更统一。唯一不应预先承诺的是覆盖率:先以真实的编辑页、设置页和 overlay 页面做 PoC,再确认剩余定制量。

只有当“Web 与 Native 共用同一套组件实现”是长期、明确且可验收的目标时,才应把 Tamagui 提到第一候选。若重视完全掌握组件源码,再看 gluestack-ui v5;它是把维护权交给团队,不是把维护工作消失。

延伸阅读#

参考资料#

本文共 15937 字,创建于 Aug 10, 2026

相关标签: Frontend, React, UI, ByAI