Expo iOS HIG Best Practices
Design rules for building iOS 26 apps in Expo (React Native) that feel genuinely native under Apple's Human Interface Guidelines. Contains 46 rules across 8 categories, prioritized by how much each decision affects native feel and HIG compliance. Every example is TSX/Expo — the decisions you make in React Native and TypeScript, not Swift.
The core idea: a React Native app feels native when it reaches for the platform — the system navigation controller, system controls, semantic colors, SF Symbols, real haptics, the system share sheet — instead of re-implementing iOS in JavaScript. These rules say which decision earns the native feel and which one quietly forfeits it.
When to Apply
Reference these guidelines when:
- Building or reviewing iOS screens, navigation, lists, or forms in an Expo app
- Choosing navigation: Expo Router native stack vs JS stack, native tabs, sheets, modals, large titles
- Picking controls: when to use the native
Alert, ActionSheetIOS, date picker, Switch, SF Symbols, or drop to @expo/ui
- Styling for the platform: safe areas, dark mode, semantic colors, the iOS type scale, spacing, Liquid Glass
- Making interaction feel native: touch targets, press feedback, swipe actions, pull-to-refresh, gestures, haptics
- Adding motion, loading/empty states, accessibility, permissions, and launch polish
When NOT to Use This Skill
- The
@expo/ui component API — for how to use @expo/ui/swift-ui components, Host boundaries, and modifiers, use the expo-ui skill. This skill says which decisions make an app native and points to @expo/ui when dropping to SwiftUI is the right call; it does not re-document that API.
- The cross-platform design system itself — for the shared Unistyles theme, design tokens, variant-driven component APIs, and making components feel native on web as well as iOS, use the
expo-design-system skill. This skill governs iOS native feel; that one governs the token and component architecture that the two frontends share.
- Native Swift / SwiftUI — for HIG in a native Swift codebase, use
ios-hig or ios-design. This skill's examples are all React Native/TSX.
- Android — these rules target iOS conventions. Use platform-adaptive code so Android gets Material; don't apply iOS idioms there.
Rule Categories by Priority
| Priority |
Category |
Impact |
Prefix |
| 1 |
Native Navigation Architecture |
CRITICAL |
nav- |
| 2 |
Native Component Fidelity |
CRITICAL |
native- |
| 3 |
Layout & Adaptivity |
HIGH |
layout- |
| 4 |
Touch, Gestures & Haptics |
HIGH |
touch- |
| 5 |
Visual System & Liquid Glass |
HIGH |
visual- |
| 6 |
Motion & Feedback |
MEDIUM-HIGH |
motion- |
| 7 |
Accessibility |
MEDIUM-HIGH |
acc- |
| 8 |
System Integration & Polish |
MEDIUM |
system- |
Quick Reference
1. Native Navigation Architecture (CRITICAL)
nav-native-stack — Use Expo Router's native Stack for screen hierarchy
nav-native-tabs — Adopt native tabs for top-level sections
nav-large-titles — Enable large titles on top-level screens
nav-sheet-detents — Present secondary tasks as sheets with detents
nav-push-vs-present — Push for hierarchy and present for self-contained tasks
nav-search-in-header — Place search in the navigation bar
nav-system-back — Keep the system back button and swipe-back gesture
2. Native Component Fidelity (CRITICAL)
native-avoid-material-ui — Avoid Material Design component kits on iOS
native-sf-symbols — Use SF Symbols for iconography
native-system-alert — Use the native alert for confirmations
native-action-sheet — Use an action sheet to choose among actions
native-datetime-picker — Use the native date and time picker
native-switch-toggle — Use the platform Switch for boolean settings
3. Layout & Adaptivity (HIGH)
layout-safe-area-insets — Respect safe-area insets with the safe-area context
layout-edge-to-edge — Extend scrollable content under translucent bars
layout-keyboard-avoidance — Keep inputs visible above the keyboard
layout-dark-mode-semantic — Drive colors from the active color scheme
layout-content-inset-under-bars — Inset list content past the tab bar and home indicator
layout-readable-width-ipad — Constrain reading width on iPad and large screens
4. Touch, Gestures & Haptics (HIGH)
touch-hit-target — Size touch targets to at least 44pt
touch-pressable-feedback — Give every control immediate press feedback
touch-swipe-actions — Offer swipe actions on list rows
touch-pull-to-refresh — Use RefreshControl for pull-to-refresh
touch-gesture-handler-thread — Drive interactive gestures with Gesture Handler
touch-haptics-on-outcome — Pair haptics with meaningful outcomes
5. Visual System & Liquid Glass (HIGH)
visual-semantic-colors — Use semantic system colors instead of hardcoded hex
visual-system-font — Use the system font for interface text
visual-type-scale — Map text styles to the iOS type scale
visual-spacing-rhythm — Derive spacing from a single base unit
visual-liquid-glass-gated — Apply Liquid Glass through a version-gated native view
visual-tint-discipline — Reserve the accent tint for interactive elements
6. Motion & Feedback (MEDIUM-HIGH)
motion-ui-thread-animation — Run animations on the UI thread
motion-virtualized-lists — Render long lists with a virtualized list
motion-loading-states — Show content-shaped placeholders while loading
motion-empty-states — Design empty states that guide the next action
motion-optimistic-updates — Apply optimistic updates for user actions
7. Accessibility (MEDIUM-HIGH)
acc-roles-labels — Label interactive and icon-only controls for VoiceOver
acc-dynamic-type — Let text scale with Dynamic Type
acc-reduce-motion — Honor the Reduce Motion setting
acc-state-and-hint — Expose control state to assistive technology
acc-grouping-focus — Group related elements for a logical focus order
8. System Integration & Polish (MEDIUM)
system-permissions-jit — Request permissions just in time with a rationale
system-status-bar — Match the status bar style to the content behind it
system-keyboard-type — Configure each text field for its content
system-share-sheet — Share through the system share sheet
system-app-icon-launch — Configure a real app icon and launch screen
How to Use
Read individual reference files for detailed explanations and code examples:
- Section definitions — Category structure and impact levels
- Rule template — Template for adding new rules
- Reference files:
references/{prefix}-{slug}.md
Each rule file contains a short explanation of why it matters for native feel, an Incorrect (non-native) TSX example, a Correct (native) example that is a minimal diff from it, and an authoritative reference URL. Where relevant, rules add a "When NOT to use this pattern" or "Alternative" section.
Related Skills
expo-ui — @expo/ui/swift-ui component API reference. Use it when the rules here point you to native SwiftUI components.
ios-hig / ios-design — HIG and Apple design principles for native Swift/SwiftUI codebases.
expo — Expo React Native performance optimization, complementary to the motion/list rules here.
1---2name: expo-ios-hig3description: Expo / React Native iOS interface conforming to Apple Human Interface Guidelines (iOS 26) — native navigation (Expo Router native stack and tabs), platform controls (Alert, ActionSheetIOS, SF Symbols via expo-symbols), safe areas, dark mode, Dynamic Type, haptics, Liquid Glass, accessibility, and 60fps motion. Covers architecture and styling decisions made in React Native/TypeScript; for the @expo/ui SwiftUI component API use the expo-ui skill, and for native Swift use ios-hig. Trigger when building, reviewing, or refactoring such an app — even when the user does not say "HIG" or "native feel" but is writing TSX screens, navigation, lists, forms, or styling for iOS in Expo.4---5# Expo iOS HIG Best Practices
6
7Design rules for building iOS 26 apps in **Expo (React Native)** that feel genuinely native under Apple's Human Interface Guidelines. Contains **46 rules across 8 categories**, prioritized by how much each decision affects native feel and HIG compliance. Every example is **TSX/Expo** — the decisions you make in React Native and TypeScript, not Swift.
8
9The core idea: a React Native app feels native when it *reaches for the platform* — the system navigation controller, system controls, semantic colors, SF Symbols, real haptics, the system share sheet — instead of re-implementing iOS in JavaScript. These rules say which decision earns the native feel and which one quietly forfeits it.
10
11## When to Apply
12
13Reference these guidelines when:
14
15- Building or reviewing iOS screens, navigation, lists, or forms in an Expo app
16- Choosing navigation: Expo Router native stack vs JS stack, native tabs, sheets, modals, large titles
17- Picking controls: when to use the native `Alert`, `ActionSheetIOS`, date picker, `Switch`, SF Symbols, or drop to `@expo/ui`
18- Styling for the platform: safe areas, dark mode, semantic colors, the iOS type scale, spacing, Liquid Glass
19- Making interaction feel native: touch targets, press feedback, swipe actions, pull-to-refresh, gestures, haptics
20- Adding motion, loading/empty states, accessibility, permissions, and launch polish
21
22## When NOT to Use This Skill
23
24- **The `@expo/ui` component API** — for how to use `@expo/ui/swift-ui` components, Host boundaries, and modifiers, use the **`expo-ui`** skill. This skill says *which decisions* make an app native and points to `@expo/ui` when dropping to SwiftUI is the right call; it does not re-document that API.
25- **The cross-platform design system itself** — for the shared Unistyles theme, design tokens, variant-driven component APIs, and making components feel native on **web** as well as iOS, use the **`expo-design-system`** skill. This skill governs iOS native feel; that one governs the token and component architecture that the two frontends share.
26- **Native Swift / SwiftUI** — for HIG in a native Swift codebase, use **`ios-hig`** or **`ios-design`**. This skill's examples are all React Native/TSX.
27- **Android** — these rules target iOS conventions. Use platform-adaptive code so Android gets Material; don't apply iOS idioms there.
28
29## Rule Categories by Priority
30
31| Priority | Category | Impact | Prefix |
32|----------|----------|--------|--------|
33| 1 | Native Navigation Architecture | CRITICAL | `nav-` |
34| 2 | Native Component Fidelity | CRITICAL | `native-` |
35| 3 | Layout & Adaptivity | HIGH | `layout-` |
36| 4 | Touch, Gestures & Haptics | HIGH | `touch-` |
37| 5 | Visual System & Liquid Glass | HIGH | `visual-` |
38| 6 | Motion & Feedback | MEDIUM-HIGH | `motion-` |
39| 7 | Accessibility | MEDIUM-HIGH | `acc-` |
40| 8 | System Integration & Polish | MEDIUM | `system-` |
41
42## Quick Reference
43
44### 1. Native Navigation Architecture (CRITICAL)
45
46- [`nav-native-stack`](references/nav-native-stack.md) — Use Expo Router's native Stack for screen hierarchy
47- [`nav-native-tabs`](references/nav-native-tabs.md) — Adopt native tabs for top-level sections
48- [`nav-large-titles`](references/nav-large-titles.md) — Enable large titles on top-level screens
49- [`nav-sheet-detents`](references/nav-sheet-detents.md) — Present secondary tasks as sheets with detents
50- [`nav-push-vs-present`](references/nav-push-vs-present.md) — Push for hierarchy and present for self-contained tasks
51- [`nav-search-in-header`](references/nav-search-in-header.md) — Place search in the navigation bar
52- [`nav-system-back`](references/nav-system-back.md) — Keep the system back button and swipe-back gesture
53
54### 2. Native Component Fidelity (CRITICAL)
55
56- [`native-avoid-material-ui`](references/native-avoid-material-ui.md) — Avoid Material Design component kits on iOS
57- [`native-sf-symbols`](references/native-sf-symbols.md) — Use SF Symbols for iconography
58- [`native-system-alert`](references/native-system-alert.md) — Use the native alert for confirmations
59- [`native-action-sheet`](references/native-action-sheet.md) — Use an action sheet to choose among actions
60- [`native-datetime-picker`](references/native-datetime-picker.md) — Use the native date and time picker
61- [`native-switch-toggle`](references/native-switch-toggle.md) — Use the platform Switch for boolean settings
62
63### 3. Layout & Adaptivity (HIGH)
64
65- [`layout-safe-area-insets`](references/layout-safe-area-insets.md) — Respect safe-area insets with the safe-area context
66- [`layout-edge-to-edge`](references/layout-edge-to-edge.md) — Extend scrollable content under translucent bars
67- [`layout-keyboard-avoidance`](references/layout-keyboard-avoidance.md) — Keep inputs visible above the keyboard
68- [`layout-dark-mode-semantic`](references/layout-dark-mode-semantic.md) — Drive colors from the active color scheme
69- [`layout-content-inset-under-bars`](references/layout-content-inset-under-bars.md) — Inset list content past the tab bar and home indicator
70- [`layout-readable-width-ipad`](references/layout-readable-width-ipad.md) — Constrain reading width on iPad and large screens
71
72### 4. Touch, Gestures & Haptics (HIGH)
73
74- [`touch-hit-target`](references/touch-hit-target.md) — Size touch targets to at least 44pt
75- [`touch-pressable-feedback`](references/touch-pressable-feedback.md) — Give every control immediate press feedback
76- [`touch-swipe-actions`](references/touch-swipe-actions.md) — Offer swipe actions on list rows
77- [`touch-pull-to-refresh`](references/touch-pull-to-refresh.md) — Use RefreshControl for pull-to-refresh
78- [`touch-gesture-handler-thread`](references/touch-gesture-handler-thread.md) — Drive interactive gestures with Gesture Handler
79- [`touch-haptics-on-outcome`](references/touch-haptics-on-outcome.md) — Pair haptics with meaningful outcomes
80
81### 5. Visual System & Liquid Glass (HIGH)
82
83- [`visual-semantic-colors`](references/visual-semantic-colors.md) — Use semantic system colors instead of hardcoded hex
84- [`visual-system-font`](references/visual-system-font.md) — Use the system font for interface text
85- [`visual-type-scale`](references/visual-type-scale.md) — Map text styles to the iOS type scale
86- [`visual-spacing-rhythm`](references/visual-spacing-rhythm.md) — Derive spacing from a single base unit
87- [`visual-liquid-glass-gated`](references/visual-liquid-glass-gated.md) — Apply Liquid Glass through a version-gated native view
88- [`visual-tint-discipline`](references/visual-tint-discipline.md) — Reserve the accent tint for interactive elements
89
90### 6. Motion & Feedback (MEDIUM-HIGH)
91
92- [`motion-ui-thread-animation`](references/motion-ui-thread-animation.md) — Run animations on the UI thread
93- [`motion-virtualized-lists`](references/motion-virtualized-lists.md) — Render long lists with a virtualized list
94- [`motion-loading-states`](references/motion-loading-states.md) — Show content-shaped placeholders while loading
95- [`motion-empty-states`](references/motion-empty-states.md) — Design empty states that guide the next action
96- [`motion-optimistic-updates`](references/motion-optimistic-updates.md) — Apply optimistic updates for user actions
97
98### 7. Accessibility (MEDIUM-HIGH)
99
100- [`acc-roles-labels`](references/acc-roles-labels.md) — Label interactive and icon-only controls for VoiceOver
101- [`acc-dynamic-type`](references/acc-dynamic-type.md) — Let text scale with Dynamic Type
102- [`acc-reduce-motion`](references/acc-reduce-motion.md) — Honor the Reduce Motion setting
103- [`acc-state-and-hint`](references/acc-state-and-hint.md) — Expose control state to assistive technology
104- [`acc-grouping-focus`](references/acc-grouping-focus.md) — Group related elements for a logical focus order
105
106### 8. System Integration & Polish (MEDIUM)
107
108- [`system-permissions-jit`](references/system-permissions-jit.md) — Request permissions just in time with a rationale
109- [`system-status-bar`](references/system-status-bar.md) — Match the status bar style to the content behind it
110- [`system-keyboard-type`](references/system-keyboard-type.md) — Configure each text field for its content
111- [`system-share-sheet`](references/system-share-sheet.md) — Share through the system share sheet
112- [`system-app-icon-launch`](references/system-app-icon-launch.md) — Configure a real app icon and launch screen
113
114## How to Use
115
116Read individual reference files for detailed explanations and code examples:
117
118- [Section definitions](references/_sections.md) — Category structure and impact levels
119- [Rule template](assets/templates/_template.md) — Template for adding new rules
120- Reference files: `references/{prefix}-{slug}.md`
121
122Each rule file contains a short explanation of *why* it matters for native feel, an **Incorrect** (non-native) TSX example, a **Correct** (native) example that is a minimal diff from it, and an authoritative reference URL. Where relevant, rules add a "When NOT to use this pattern" or "Alternative" section.
123
124## Related Skills
125
126- **`expo-ui`** — `@expo/ui/swift-ui` component API reference. Use it when the rules here point you to native SwiftUI components.
127- **`ios-hig`** / **`ios-design`** — HIG and Apple design principles for native Swift/SwiftUI codebases.
128- **`expo`** — Expo React Native performance optimization, complementary to the motion/list rules here.