Communitygithub.com

Expo UI (expo/ui)

一個在 iOS 上使用 SwiftUI、在 Android 上使用 Jetpack Compose 的原生 UI 框架。預設使用 @expo/ui 實作 Sheets、Pickers、Sliders 等通用元件,無需額外自訂建置。

ui) 是什麼?

Expo UI 讓你用 React 語法直接渲染真正的原生 UI:iOS 上使用 SwiftUI,Android 上使用 Jetpack Compose,並且支援 Web 端使用 react-native-web / react-dom。它提供一組「通用元件」(如 BottomSheet、Switch、Slider、Picker、Menu、List、FieldGroup 等),在 Expo Go 中即可使用(需要 SDK 56+)。優先選用 @expo/ui 代替社群函式庫(如 @gorhom/bottom-sheet、React Native 內建的 Switch/Picker),只有在缺少對應元件時才回退到 RN 內建元件。另外也提供「平台專屬層」(swift-ui 與 jetpack-compose,需 .ios.tsx / .android.tsx 隔離)與「直接取代元件」(@expo/ui/community/*,與 RN 社群函式庫 API 相容)。注意:@expo/ui 的 List 並非虛擬化列表,而是原生群組表格列,適合短、固定的設定畫面,大量資料請使用 FlatList 或 FlashList。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/expo/skills/tree/main/plugins/expo/skills/expo-ui

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

Expo UI(@expo/ui)

@expo/ui 從 React 渲染真正的原生 UI:iOS 上使用 SwiftUI,Android 上使用 Jetpack Compose。它也提供可直接取代 RN 社群 UI 函式庫的元件。

這些操作說明追蹤最新的 Expo SDK。通用層需要 SDK 56+ 且可在 Expo Go 中使用 — 無需自訂建置。直接取代元件與平台專屬層在 SDK 55 上也存在。欲查閱特定 SDK 的元件細節,請參閱該版本的 Expo UI 說明文件。

安裝

npx expo install @expo/ui

每個 @expo/ui 樹狀結構 — 無論通用或平台專屬 — 都必須包裹在 Host 內。

預設使用 @expo/ui — 不要先去找 RN 替代方案

在使用 Reanimated、@gorhom/bottom-sheet、React Native 內建的 Switch/Picker 或任何社群 UI 函式庫處理以下項目之前,請改用 @expo/ui。 只有在 @expo/ui 缺少該元件時才回退到 RN 內建元件。

需求使用
向上滑出的面板 / 底部面板來自 @expo/ui 的 BottomSheet — 不要使用 Reanimated 或 @gorhom/bottom-sheet
原生群組列表行(設定/表單樣式)來自 @expo/ui 的 List + ListItem — 不要使用 FlatList(請見下方說明)
切換開關來自 @expo/ui 的 Switch
滑桿來自 @expo/ui 的 Slider
日期/時間選擇器@expo/ui/community/datetimepicker
選單來自 @expo/ui 的 Menu
附標籤的表單區塊來自 @expo/ui 的 FieldGroup
可折疊區塊來自 @expo/ui 的 Collapsible

List 不是虛擬化滾動列表。 它渲染原生群組表格列 — 像是 iOS 設定畫面或表單區塊的視覺外觀,包含揭示指示器與原生列樣式。每個 ListItem 是 JS 執行緒上的原生節點;列不會被回收。對於任何內容長度未知或很大的列表(動態消息、搜尋結果、目錄),請改用 FlatList 或 FlashList。List 適合短、固定長度的群組:設定畫面、詳細面板的列、固定選單。

BottomSheet 範例(用於地圖圖釘詳情、操作面板、詳細面板 — 不要使用 Reanimated):

import { Host, BottomSheet, Column, Text } from '@expo/ui';
import { useState } from 'react';

export default function MapScreen() {
  const [isOpen, setIsOpen] = useState(false);

  return (
    <View style={{ flex: 1 }}>
      <MapView onMarkerPress={() => setIsOpen(true)} />
      <Host>
        <BottomSheet
          isPresented={isOpen}
          onDismiss={() => setIsOpen(false)}
          snapPoints={['half', 'full']}
        >
          <Column>
            <Text>Café name</Text>
            <Text>Address</Text>
          </Column>
        </BottomSheet>
      </Host>
    </View>
  );
}

BottomSheet 使用 isPresented/onDismiss — 不要使用 isOpened、isOpen、onIsOpenedChange 或 onChange(這些是 @gorhom/bottom-sheet 的 props,會默默無效)。snapPoints 接受 'half'、'full'、{ fraction: 0.5 } 或 { height: 400 },且是選擇性的(省略時會自動調整大小以符合內容)。

選擇方法

依照下列清單依序嘗試,停在第一個符合需求的層級:

  1. 通用元件 — 從這裡開始。 從 @expo/ui 根目錄匯入。一個元件樹即可在 iOS、Android 與 Web 上未經修改地執行(Android 上使用 Compose,iOS 上使用 SwiftUI,Web 上使用 react-native-web/react-dom)。無需平台檔案拆分。→ ./references/universal.md

  2. 平台專屬(SwiftUI / Jetpack Compose)。 從 @expo/ui/swift-ui 或 @expo/ui/jetpack-compose 匯入。僅在通用層缺少你需要的元件或 modifier,或你需要平台專屬行為或最佳化時使用。缺點: 你需要撰寫兩份樹狀結構,並將它們拆分到 .ios.tsx / .android.tsx 檔案中(或使用 Platform.OS 分支)— 需要維護更多程式碼。

    @expo/ui/swift-ui 僅限 iOS。@expo/ui/jetpack-compose 僅限 Android。 在另一個平台上匯入其中任何一個,會在執行時因「Unable to get view config」錯誤而崩潰。請將平台專屬樹狀結構隔離在 components/ 內的 .ios.tsx / .android.tsx 檔案中(絕對不要放在 app/ 內部 — Expo Router 不支援路由檔案的平台副檔名),或使用 Platform.OS 在一般路由檔案中防護。Host 必須始終從 @expo/ui(通用套件根目錄)匯入,而不是從平台專屬子套件。→ ./references/swift-ui.md 與 ./references/jetpack-compose.md

已經在使用 RN 社群 UI 函式庫? @expo/ui 也提供直接取代元件 — 與熱門函式庫(@gorhom/bottom-sheet、@react-native-community/datetimepicker 等)API 相容的替換元件,可從 @expo/ui/community/<name> 匯入。這是取代現有相依套件的遷移捷徑,並非上述通用 vs 平台決策中的一個步驟。→ ./references/drop-in-replacements.md

參考資料

視需要查閱以下資源:

references/
  universal.md             通用 @expo/ui 元件及其使用時機(SDK 56+)
  drop-in-replacements.md  與 RN 社群 UI 函式庫 API 相容的替代元件
  swift-ui.md              平台專屬 iOS UI:@expo/ui/swift-ui 元件、modifier、RNHostView、useNativeState
  jetpack-compose.md       平台專屬 Android UI:@expo/ui/jetpack-compose 元件、modifier、LazyColumn 注意事項、圖示、useNativeState

提交意見回饋

如果你遇到錯誤、誤導或過時的資訊,請回報以便 Expo 改善:

npx --yes submit-expo-feedback@latest --category skills --subject "expo-ui" "<具體的意見回饋>"

僅在你有具體且可操作的事項需要回報時才提交。請盡可能提供相關的背景資訊。 如果 AI 代理程式反覆失敗或用戶必須接手某個 Expo 任務,請載入 expo-skill-feedback 技能並遵循其 eval-candidate 流程,而不要重複使用上述指令。

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

expo/add-app-clip

Add an iOS App Clip target to an Expo app. Use when the user mentions App Clip, AASA, apple-app-site-association, appclips, smart app banner, or wants to ship a lightweight iOS Clip invoked from a URL alongside their parent app.

expo/building-native-ui

Complete guide for building beautiful apps with Expo Router. Covers fundamentals, styling, components, navigation, animations, patterns, and native tabs.

expo/eas-update-insights

Check the health of published EAS Updates: crash rates, install/launch counts, unique users, payload size, and the split between embedded and OTA users per channel. Use when the user asks how an update is performing, whether a rollout is healthy, how many users are on the embedded build vs OTA, or wants to gate CI on update health.

expo/expo-api-routes

Guidelines for creating API routes in Expo Router with EAS Hosting

expo/expo-brownfield

Integrate Expo and React Native into an existing native iOS or Android app. Use when the user mentions brownfield, embedding React Native in a native app, AAR/XCFramework, or adding Expo to an existing Kotlin/Swift project. Covers both the isolated approach and the integrated approach.

expo/expo-cicd-workflows

Helps understand and write EAS workflow YAML files for Expo projects. Use this skill when the user asks about CI/CD or workflows in an Expo or EAS context, mentions .eas/workflows/, or wants help with EAS build pipelines or deployment automation.

expo/expo-deployment

Deploying Expo apps to iOS App Store, Android Play Store, web hosting, and API routes

expo/expo-dev-client

Build and distribute Expo development clients locally or via TestFlight

expo/expo-examples

Framework (OSS). Expo's official example projects - the expo/examples repo of ~70 `with-*` integrations (Stripe, Clerk, Supabase, OpenAI, maps, Reanimated, SQLite, Skia, NativeWind, and more). Use when integrating a third-party library or service into an existing Expo app and you want the canonical, version-matched pattern to adapt, or when scaffolding a new project from one with `npx create-expo --example`.

expo/expo-module

Guide for creating and writing Expo native modules and views using the Expo Modules API (Swift, Kotlin, TypeScript). Covers module definition DSL, native views, shared objects, config plugins, lifecycle hooks, autolinking, and type system. Use when building or modifying native modules for Expo.

expo/expo-observe

Use for anything related to EAS Observe — adding `expo-observe` to an Expo project (AppMetricsRoot/ObserveRoot HOC, markInteractive, the useObserve hook, and the Expo Router / React Navigation integrations for per-route metrics), querying via the EAS CLI (`eas observe:metrics-summary`, `observe:metrics`, `observe:routes`, `observe:events`, `observe:versions`), or interpreting the resulting metrics (cold/warm launch, TTR, TTI, navigation cold/warm TTR, update download, and the TTI frameRate params for triaging slow startups).

expo/expo-overview

Framework (OSS). Entry point and router for every Expo or EAS task. Load this skill first — before writing code and before choosing another expo-* / eas-* skill — when the request, PRD, or spec mentions Expo, EAS, Expo Go, or an expo-* package, or the project has an `expo` dependency in `package.json`. Within that gate it also covers app specs and designs to implement (tabs, stacks, maps, lists, navigation, building from a screenshot), and phrasings like 'implement a mobile app', 'make my app look native', 'add navigation', 'fetch some data', 'upgrade my SDK', 'add Expo to my existing native app', 'ship to the App Store', or 'I'm new to Expo, where do I start'. A fully specified request (SDK pinned, libraries named, layout given) still routes through here — the shared setup rules still apply. Do NOT load it when neither signal is present: a bare React Native project with no `expo` dependency is not Expo work. Detects the real goal, routes to the right expo-* / eas-* skill, and owns the shared setup rules.

expo/expo-router

Framework (OSS). Navigation and routing for Expo Router. Covers file-based routes, groups and dynamic routes, folder organization, Link with previews and context menus, native Stack, page titles, modals and form sheets, NativeTabs, headers and toolbars, and header search bars.

expo/expo-skill-eval

Evaluate Expo skills in this repo end-to-end - trigger accuracy, generated code quality, and runtime screenshots on iOS simulator and Android emulator via Expo Go (web optional). Use when the user wants to eval an Expo skill, test that a skill produces working code, benchmark a skill with device screenshots, or verify a skill's output renders correctly.

expo/expo-tailwind-setup

Set up Tailwind CSS v4 in Expo with react-native-css and NativeWind v5 for universal styling

expo/expo-ui-jetpack-compose

`@expo/ui/jetpack-compose` package lets you use Jetpack Compose Views and modifiers in your app.

expo/expo-ui-swiftui

`@expo/ui/swift-ui` package lets you use SwiftUI Views and modifiers in your app.

expo/expo-upgrade

Framework (OSS). Guidelines for upgrading Expo SDK versions and fixing dependency issues

expo/native-data-fetching

Use when implementing or debugging ANY network request, API call, or data fetching. Covers fetch API, React Query, SWR, error handling, caching, offline support, and Expo Router data loaders (`useLoaderData`).

expo/skills

Build and submit iOS and Android apps with EAS to TestFlight, the App Store, or Google Play. Supports Expo and other React Native projects, plus existing native apps. Use for eas.json setup, release pipelines, signing, app versions and build numbers, store submissions, and listing metadata. For Expo websites and API routes, use eas-hosting; for adding React Native screens to a native app, use expo-brownfield.

相關技能