Skip to content

Native UI with Expo UI

A React Native guide for coding agents. Also covers swiftui, jetpack compose, native state.

Choose native UI when platform fidelity is more important than identical cross-platform rendering. Expo UI exposes universal components backed by SwiftUI on iOS and Jetpack Compose on Android, with platform-specific escape hatches when a shared abstraction stops fitting.

Choose a Rendering Lane

  1. Use React Native components for highly branded, cross-platform surfaces.
  2. Use Expo UI universal components for settings, forms, lists, menus, controls, and other platform-shaped surfaces.
  3. Use platform files when the interaction is conceptually shared but its implementation should differ.
  4. Use direct SwiftUI or Jetpack Compose bindings for a platform-exclusive capability or modifier.

If a design requires continuously fighting a universal component's native behavior, it is probably in the wrong lane.

Adopt the Native Layout Model

Universal native trees live inside Host. Compose them with Column, Row, and Spacer, not React Native Flexbox assumptions. A Host can carry environment such as color scheme and Android seed color.

SwiftUI and Compose share useful concepts but not identical APIs:

IntentSwiftUICompose
Vertical compositionVStackColumn
Horizontal compositionHStackRow
LayeringZStackBox
Transformationmodifier chainmodifier chain

Modifier order can change layout, clipping, background, and interaction. Treat the chain as execution order, not a bag of CSS properties.

Use a Styling Escape Ladder

Start with the smallest mechanism that preserves the universal contract:

  1. Universal style props for basic dimensions and spacing.
  2. Text-specific styling for typography.
  3. Native modifiers for platform behavior and appearance.
  4. .ios.tsx and .android.tsx implementations behind one typed interface.
  5. A custom native view or module only when necessary.

Restart Metro after adding a new platform-specific file if resolution does not update.

Keep High-Frequency State Native

Text input selection, gesture progress, and other per-frame state should not round-trip through React state unless React must render from it. Native state and worklets can keep interaction responsive, then commit meaningful state at boundaries such as submit, blur, or gesture completion.

Do not create two competing sources of truth. Document which layer owns live state and when it synchronizes with application state.

Platform Quality Checklist

  • Dynamic type and screen-reader labels work.
  • Android uses Material 3 conventions where applicable.
  • iOS and Android each have appropriate navigation and control behavior.
  • Safe-area and keyboard behavior is tested inside the host.
  • A shared abstraction does not erase meaningful platform differences.

Sources

Check the current Expo UI overview, universal components, and native state documentation because these APIs are evolving.

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-react-native-guide({ topic: "expo-native-ui" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems
Native UI with Expo UI: React Native guide for coding agents | Better Design