Expo ui full reference
Skill AlshehriAli0/agent-skills/skills/expo-ui-full-reference
Agent skill: my custom skills
npx -y skills add AlshehriAli0/agent-skills --skill expo-ui-full-referenceAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 2 stars2 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Build native UI from React with @expo/ui: real SwiftUI on iOS and Jetpack Compose on Android, in an Expo or React Native + TypeScript app. Use whenever building or reviewing native-feeling UI that plain React Native handles poorly: a settings screen, grouped form, native picker, context menu, action/bottom sheet, segmented control, toggle, slider, or any Host/RNHostView tree. Also when choosing universal ('@expo/ui') vs platform-specific ('@expo/ui/swift-ui', '@expo/ui/jetpack-compose') components, applying SwiftUI/Compose modifiers, swapping an RN community library for an '@expo/ui/community/*' drop-in, or fixing 'Unable to get view config' crashes. Not for custom native modules, Expo Router navigation, Reanimated, or data fetching.
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
8.1 KB, as published. Nobody here has run it
Expo UI Full Reference (@expo/ui)
The complete @expo/ui reference: every layer (universal, SwiftUI, Jetpack Compose), the full
modifier catalogs, drop-in replacements, screen templates, and tooling. Read the mental model
below, then load the one reference file the task needs (map at the bottom).
@expo/ui renders real native UI from React: SwiftUI views on iOS, Jetpack Compose on
Android. It is a primitives library (like <div>/<span> for the OS), not a styled design
kit. Reach for it when you want controls that look and behave exactly like the system: settings
forms, pickers, sheets, menus, toggles, sliders. Keep plain React Native View/Text
(NativeWind, flexbox) for custom-branded, heavily-styled UI. The two mix freely at the
component level.
Mental model (the one thing to get right)
Every @expo/ui tree is an island of native UI bridged into your RN tree by a Host.
Think of Host like <svg> in the DOM or <Canvas> in Skia: the bridge boundary. This drives
the #1 rule agents get wrong:
Flexbox / Yoga styles apply to the
Hostonly. Inside a Host, there is no Yoga. Lay out children with native primitives and their props/modifiers, never with RNstyle={{ flex, flexDirection, justifyContent, alignItems, gap }}:
- Universal/SwiftUI:
Row/Column/HStack/VStackwithspacing+alignment.- Compose:
Row/ColumnwithhorizontalArrangement/verticalArrangement+modifiers={[...]}from@expo/ui/jetpack-compose/modifiers. Puttingstyle={{ flex: 1 }}on aButton/Text/Rowinside a Host is a no-op or a bug.scripts/audit-expo-ui.jscatches this automatically.
Host is always imported from the @expo/ui root, even when its children are
platform-specific. Host itself takes either matchContents (size to content, best for inline
widgets) or style={{ flex: 1 }} / explicit size (required when it wraps a scrollable like
List, ScrollView, LazyColumn).
Choosing a layer (stop at the first that fits)
- Universal first: import from
@expo/ui. One tree runs unmodified on iOS, Android, and web (web is experimental). No.ios.tsx/.android.tsxsplit. Covers the common kit: layout,Text,Icon,Button,Switch,Checkbox,Slider,TextInput,Picker,BottomSheet,Collapsible,List,FieldGroup. →references/universal.md - Platform-specific: import from
@expo/ui/swift-ui(iOS) or@expo/ui/jetpack-compose(Android). Use only when universal lacks the component, modifier, or platform behavior you need (e.g. SwiftUIForm/ContextMenu/glassEffect, ComposeDockedSearchBar/FloatingActionButton/Material 3). Cost: two trees and a file split. →references/swift-ui.md,references/jetpack-compose.md - Drop-in replacements:
@expo/ui/community/<name>. A migration side-path for swapping out an RN community UI dependency (@gorhom/bottom-sheet,@react-native-community/datetimepicker, ...), not part of the decision above. →references/drop-in-replacements.md
Rules agents get wrong (read before writing code)
- Platform packages crash on the wrong OS. Importing
@expo/ui/swift-uion Android or@expo/ui/jetpack-composeon iOS throwsUnable to get view config. Isolate platform trees in.ios.tsx/.android.tsxfiles undercomponents/(never insideapp/, where Expo Router rejects platform suffixes on route files with a "no fallback sibling" error), or guard withPlatform.OS. Re-export from a plain route file. - The callback prop name differs by layer. Universal
Buttonand SwiftUIButtonuseonPress; ComposeButtonusesonClick. Don't assume. TextInput/TextFieldvalue is not a plain string when usinguseNativeState: it takes anObservableStatefor flicker-free worklet updates, and needsreact-native-worklets. See the universal/platform references.List/LazyColumnitems run on the JS thread (each row is a JSX node): fine for settings-sized lists, not for large data sets.- Modifiers mirror native APIs. Apple/Google sample code is roughly a search-and-replace
away. Apply them via the
modifiers={[...]}prop (order matters), importing from@expo/ui/swift-ui/modifiersor@expo/ui/jetpack-compose/modifiers.
SDK gating (confirm against the installed version)
- Universal layer needs SDK 56+. Platform-specific (
swift-ui,jetpack-compose) and drop-ins also work on SDK 55. - On SDK 56+,
@expo/uiships in Expo Go, sonpx expo startruns it directly. On SDK 55, build a dev client (npx expo run:ios/run:android).
Source of truth: this skill is a fast map, not the territory
@expo/ui is versioned with the Expo SDK and its props/modifiers shift between cycles, so the
tables here are a fast map keyed to SDK 56, never the authority. When the map is ambiguous,
looks stale, conflicts with what is installed, or is missing a component / prop / modifier you
need, stop guessing and confirm against the real source, in this order of authority:
- The installed package (authoritative for the project's version). Prop shapes live in
node_modules/@expo/ui/build/<layer>/<Component>/index.d.ts. Enumerate what is installed:node <skill-root>/scripts/list-components.js <project-path> # component + modifier names node <skill-root>/scripts/list-components.js <project-path> --docs # + one-line modifier descriptions - The docs, matched to the project's SDK. Expo serves agent-friendly Markdown: append
/index.mdto any page, e.g.https://docs.expo.dev/versions/latest/sdk/ui/swift-ui/button/index.md.versions/latesttracks the newest SDK (57 as of writing), so if the project is on 56 usehttps://docs.expo.dev/versions/v56.0.0/...to match. Full page index:https://docs.expo.dev/llms.txt; UI overview:.../sdk/ui/index.md.
Installed types win over the docs; the docs win over this map. Never invent a prop or modifier to fill a gap: confirm it exists first.
Reference map (load only the one you need)
references/
universal.md '@expo/ui' cross-platform components, START HERE (SDK 56+)
swift-ui.md '@expo/ui/swift-ui' iOS components (SDK 55+, iOS only)
swift-ui-modifiers.md full SwiftUI modifier catalog (~95), load for any non-obvious modifier
jetpack-compose.md '@expo/ui/jetpack-compose' Android components (SDK 55+, Android only)
jetpack-compose-modifiers.md full Compose modifier catalog
drop-in-replacements.md '@expo/ui/community/*' API-compatible swaps (migration side-path)
assets/
universal-screen.tsx copy-paste universal settings screen (Expo Router)
swiftui-screen.ios.tsx copy-paste SwiftUI-only screen
compose-screen.android.tsx copy-paste Compose-only screen
install.md install + config snippet
scripts/
list-components.js enumerate components/modifiers in the *installed* version
audit-expo-ui.js flag flexbox-on-@expo/ui and avoidable platform imports
A task touching one platform pulls in only that one reference file. Shared concepts (Host, the flexbox rule, the layer decision, SDK gating, source of truth) live here and are not repeated in the references.