Reference version

This is documentation for the next SDK version. For up-to-date documentation, see the latest version (SDK 56).

Universal

Cross-platform components for building shared UIs across Android, iOS, and web with @expo/ui.

Android
iOS
Web
Included in Expo Go

The universal components in @expo/ui are a single-API layer over the platform-native UI toolkits. On Android, they delegate to @expo/ui/jetpack-compose. On iOS, they delegate to @expo/ui/swift-ui. On web, they're JS implementations using react-dom or react-native-web and are picked per component to suit the control.

Installation

Terminal
npx expo install @expo/ui

If you are installing this in an existing React Native app, make sure to install expo in your project.

Usage

Universal components must still be wrapped in a Host, but you import everything, including Host, from the package root. The universal Host dispatches to the platform-native host on Android and iOS, so there's no need to reach for @expo/ui/swift-ui or @expo/ui/jetpack-compose directly.

UniversalExample.tsx
import { Host, Column, Button, Text } from '@expo/ui'; export default function Example() { return ( <Host style={{ flex: 1 }}> <Column spacing={12} alignment="center"> <Text>Hello, world!</Text> <Button label="Press me" onPress={() => alert('Pressed')} /> </Column> </Host> ); }

Available components

CategoryComponents
ContainerHost, the required root for every universal subtree.
LayoutColumn, Row, Spacer, ScrollView
DisplayText, Icon
ControlsButton, Switch, Checkbox, Slider, TextInput, Picker
Disclosure and presentationBottomSheet, Collapsible
Collections and formsList (with ListItem), FieldGroup

When to use this versus jetpack-compose/swift-ui

  • Reach for universal components when you want one component tree that runs unmodified on Android, iOS, and web. The platform-native look and feel is preserved on Android and iOS because the components delegate to Jetpack Compose/SwiftUI under the hood.
  • Reach for @expo/ui/jetpack-compose or @expo/ui/swift-ui directly when you need platform-specific controls, modifiers, or behavior that the universal API doesn't surface.