← Expo2CONTENT HISTORY
WHAT CHANGED
Update to Expo2
Snapshot Nov 6, 2026 · 18:22 UTC · version 1.14.6
Collection source: downloaded plugin package.
First saved snapshot
No earlier snapshot is available to establish a change.
Save Expo2 and check future changes in Following.
Up to 3 plugins free · no card required.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"description": "Build native components with @expo/ui, using SwiftUI on iOS and Jetpack Compose on Android. Use for sheets, pickers, sliders, toggles, menus, grouped rows and forms, or replacing community UI libraries. Covers universal and platform-specific components. For virtualized lists, use FlatList or FlashList; for navigation, use expo-router; for custom animation, use expo-animation.",
"included_files": [
{
"relative_path": "agents/openai.yaml",
"size_in_bytes": 722
},
{
"relative_path": "references/drop-in-replacements.md",
"size_in_bytes": 2085
},
{
"relative_path": "references/jetpack-compose.md",
"size_in_bytes": 5517
},
{
"relative_path": "references/swift-ui.md",
"size_in_bytes": 4397
},
{
"relative_path": "references/universal.md",
"size_in_bytes": 4792
},
{
"relative_path": "scripts/list-components.js",
"size_in_bytes": 7343
}
],
"name": "expo-ui",
"skill_md_contents": "---\nname: expo-ui\ndescription: Build native components with @expo/ui, using SwiftUI on iOS and Jetpack Compose on Android. Use for sheets, pickers, sliders, toggles, menus, grouped rows and forms, or replacing community UI libraries. Covers universal and platform-specific components. For virtualized lists, use FlatList or FlashList; for navigation, use expo-router; for custom animation, use expo-animation.\nlicense: MIT\n---\n\n# Expo UI (`@expo/ui`)\n\n`@expo/ui` renders real native UI from React: SwiftUI on iOS, Jetpack Compose on Android. It also ships drop-in replacements for migrating off RN community UI libraries.\n\n> These instructions track the latest Expo SDK. The **universal** layer requires **SDK 56+** and works in Expo Go — no custom build needed. Drop-in replacements and the platform-specific layers also exist on SDK 55. For component details on a specific SDK, refer to the Expo UI docs for that version.\n\n## Installation\n\n```bash\nnpx expo install @expo/ui\n```\n\nEvery `@expo/ui` tree — universal or platform-specific — must be wrapped in `Host`.\n\n## Use @expo/ui by default — don't reach for RN alternatives first\n\n**Before using Reanimated, `@gorhom/bottom-sheet`, React Native's built-in `Switch`/`Picker`, or any community UI library for the items below, use `@expo/ui` instead.** Only fall back to RN built-ins when `@expo/ui` is missing the component.\n\n| Need | Use |\n|------|-----|\n| Slide-up sheet / bottom sheet | `BottomSheet` from `@expo/ui` — **not** Reanimated or `@gorhom/bottom-sheet` |\n| Grouped native list rows (settings/form-style) | `List` + `ListItem` from `@expo/ui` — **not** `FlatList` (see note below) |\n| Toggle | `Switch` from `@expo/ui` |\n| Slider | `Slider` from `@expo/ui` |\n| Date/time picker | `@expo/ui/community/datetimepicker` |\n| Menu | `Menu` from `@expo/ui` |\n| Form section with label | `FieldGroup` from `@expo/ui` |\n| Collapsible section | `Collapsible` from `@expo/ui` |\n\n> **`List` is NOT a virtualized scrolling list.** It renders native grouped table rows — the visual look of an iOS Settings screen or a form section, with disclosure indicators and native row styling. Each `ListItem` is a native node on the JS thread; rows are not recycled. For any list with large or unknown-length data (feeds, search results, catalogs), use **`FlatList`** or **`FlashList`** instead. `List` is the right choice for short, fixed-length groups: a settings screen, a detail panel's rows, a fixed menu.\n\n**`BottomSheet` example** (use this for map pin details, action sheets, detail panels — not Reanimated):\n\n```tsx\nimport { Host, BottomSheet, Column, Text } from '@expo/ui';\nimport { useState } from 'react';\n\nexport default function MapScreen() {\n const [isOpen, setIsOpen] = useState(false);\n\n return (\n <View style={{ flex: 1 }}>\n <MapView onMarkerPress={() => setIsOpen(true)} />\n <Host>\n <BottomSheet\n isPresented={isOpen}\n onDismiss={() => setIsOpen(false)}\n snapPoints={['half', 'full']}\n >\n <Column>\n <Text>Café name</Text>\n <Text>Address</Text>\n </Column>\n </BottomSheet>\n </Host>\n </View>\n );\n}\n```\n\n`BottomSheet` uses `isPresented`/`onDismiss` — **not** `isOpened`, `isOpen`, `onIsOpenedChange`, or `onChange` (those are `@gorhom/bottom-sheet` props and will silently do nothing). `snapPoints` accepts `'half'`, `'full'`, `{ fraction: 0.5 }`, or `{ height: 400 }` and is optional (auto-sizes to content when omitted).\n\n## Choosing an approach\n\nWork down this list and stop at the first layer that meets the need:\n\n1. **Universal components — start here.** Import from the `@expo/ui` root. One component tree runs unmodified on iOS, Android, and web from a single source (Compose on Android, SwiftUI on iOS, `react-native-web`/`react-dom` on web). No platform file splits. → `./references/universal.md`\n\n2. **Platform-specific (SwiftUI / Jetpack Compose).** Import from `@expo/ui/swift-ui` or `@expo/ui/jetpack-compose`. Use **only** when the universal layer is missing a component or modifier you need, or when you need platform-specific behavior or optimization. **Downside:** you write two trees and split them into `.ios.tsx` / `.android.tsx` files (or branch on `Platform.OS`) — more code to maintain.\n\n > **`@expo/ui/swift-ui` is iOS-only. `@expo/ui/jetpack-compose` is Android-only.** Importing either in a file that runs on the other platform will crash at runtime with \"Unable to get view config\" errors. Isolate platform-specific trees in `.ios.tsx` / `.android.tsx` files placed in `components/` (never inside `app/` — Expo Router does not support platform extensions for route files), or guard with `Platform.OS` in a regular route file. `Host` must always be imported from `@expo/ui` (the universal package root), not from the platform-specific sub-packages. → `./references/swift-ui.md` and `./references/jetpack-compose.md`\n\n**Already using an RN community UI library?** `@expo/ui` also ships **drop-in replacements** — API-compatible swaps for popular libraries (`@gorhom/bottom-sheet`, `@react-native-community/datetimepicker`, and more), imported from `@expo/ui/community/<name>`. This is a migration side-path for replacing an existing dependency, not a step in the universal-vs-platform decision above. → `./references/drop-in-replacements.md`\n\n## References\n\nConsult these resources as needed:\n\n```\nreferences/\n universal.md Universal @expo/ui components and when to use them (SDK 56+)\n drop-in-replacements.md API-compatible replacements for RN community UI libraries\n swift-ui.md Platform-specific iOS UI: @expo/ui/swift-ui components, modifiers, RNHostView, useNativeState\n jetpack-compose.md Platform-specific Android UI: @expo/ui/jetpack-compose components, modifiers, LazyColumn caveat, icons, useNativeState\n```\n\n## Submitting Feedback\nWhen the user requests feedback submission, use:\n```bash\nnpx --yes @expo/agent-cli@1.0.23 feedback --category skills --subject \"expo-ui\" \"<actionable feedback>\"\n```\nInclude only relevant technical details; keep credentials, private data, and conversation contents out of feedback.\n"
}SHA-256 of public snapshot: ccaa336d4f37d001521c61192a83137e3482d7f161bbbb6544617d7d484ecfd7