Reference version

This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.

Jetpack Compose

Jetpack Compose components for building native Android interfaces with @expo/ui.

Android
Included in Expo Go
Recommended version:
~58.0.10

The Jetpack Compose components in @expo/ui/jetpack-compose allow you to build fully native Android interfaces using Jetpack Compose from React Native.

Installation

Terminal
- npx expo install @expo/ui
- yarn expo install @expo/ui
- pnpm expo install @expo/ui
- bun expo install @expo/ui

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

Usage

Using a component from @expo/ui/jetpack-compose requires wrapping it in a Host component. The Host is a container for Jetpack Compose views.

import { Host, Button } from '@expo/ui/jetpack-compose'; export function SaveButton() { return ( <Host matchContents> <Button onClick={() => alert('Saved!')}>Save changes</Button> </Host> ); }
Extending with Jetpack Compose

Create custom Jetpack Compose components and modifiers that integrate with Expo UI.

Available components

Examples

Modifiers

Modifiers are applied with the modifiers prop, in array order. Put background before paddingAll so the padding sits inside the background rather than outside it.

ComposeModifiersExample.tsx
import { Column, Host, Text } from '@expo/ui/jetpack-compose'; import { background, border, fillMaxWidth, paddingAll, shadow, } from '@expo/ui/jetpack-compose/modifiers'; export default function ComposeModifiersExample() { return ( <Host style={{ flex: 1 }}> <Column verticalArrangement={{ spacedBy: 16 }} modifiers={[paddingAll(16)]}> <Text color="#FFFFFF" modifiers={[ fillMaxWidth(), shadow(4), background('#6750A4'), paddingAll(16), ]}> Background, shadow and padding </Text> <Text color="#1D192B" modifiers={[ fillMaxWidth(), background('#E8DEF8'), border(2, '#6750A4'), paddingAll(16), ]}> Background, border and padding </Text> </Column> </Host> ); }

Settings screen

Combine ListItem slots with a Switch and an Icon to build a Material 3 settings screen.

ComposeSettingsScreenExample.tsx
import { Column, Host, Icon, ListItem, Switch, Text, useMaterialColors, } from '@expo/ui/jetpack-compose'; import ChevronRight from '@expo/material-symbols/chevron_right.xml'; import Flight from '@expo/material-symbols/flight.xml'; import Wifi from '@expo/material-symbols/wifi.xml'; import { useState } from 'react'; export default function ComposeSettingsScreenExample() { const [airplaneMode, setAirplaneMode] = useState(true); const colors = useMaterialColors(); return ( <Host style={{ flex: 1 }}> <Column> <ListItem> <ListItem.LeadingContent> <Icon source={Flight} tint={colors.onSurfaceVariant} contentDescription="Airplane mode" /> </ListItem.LeadingContent> <ListItem.HeadlineContent> <Text>Airplane mode</Text> </ListItem.HeadlineContent> <ListItem.TrailingContent> <Switch value={airplaneMode} onCheckedChange={setAirplaneMode} /> </ListItem.TrailingContent> </ListItem> <ListItem> <ListItem.LeadingContent> <Icon source={Wifi} tint={colors.onSurfaceVariant} contentDescription="Wi-Fi" /> </ListItem.LeadingContent> <ListItem.HeadlineContent> <Text>Wi-Fi</Text> </ListItem.HeadlineContent> <ListItem.SupportingContent> <Text>Expo Guest</Text> </ListItem.SupportingContent> <ListItem.TrailingContent> <Icon source={ChevronRight} tint={colors.onSurfaceVariant} contentDescription="Open" /> </ListItem.TrailingContent> </ListItem> </Column> </Host> ); }

Brightness row

A common pattern for brightness or volume controls is to flank a Slider with icons. Give the Slider a weight modifier so it takes the space left over by the icons.

ComposeBrightnessRowExample.tsx
import { Host, Icon, Row, Slider, useMaterialColors, } from '@expo/ui/jetpack-compose'; import { paddingAll, weight, } from '@expo/ui/jetpack-compose/modifiers'; import BacklightHigh from '@expo/material-symbols/backlight_high.xml'; import BacklightLow from '@expo/material-symbols/backlight_low.xml'; import { useState } from 'react'; export default function ComposeBrightnessRowExample() { const [brightness, setBrightness] = useState(0.5); const colors = useMaterialColors(); return ( <Host style={{ flex: 1 }}> <Row verticalAlignment="center" horizontalArrangement={{ spacedBy: 12 }} modifiers={[paddingAll(16)]}> <Icon source={BacklightLow} tint={colors.onSurfaceVariant} contentDescription="Dimmer" /> <Slider value={brightness} onValueChange={setBrightness} modifiers={[weight(1)]} /> <Icon source={BacklightHigh} tint={colors.onSurfaceVariant} contentDescription="Brighter" /> </Row> </Host> ); }

Secondary text

Use ListItem.SupportingContent for the second line, and useMaterialColors for a text color that follows the light and dark themes.

ComposeSecondaryTextExample.tsx
import { Column, Host, ListItem, Text, useMaterialColors, } from '@expo/ui/jetpack-compose'; export default function ComposeSecondaryTextExample() { const colors = useMaterialColors(); return ( <Host style={{ flex: 1 }}> <Column> <ListItem> <ListItem.HeadlineContent> <Text>Chrome</Text> </ListItem.HeadlineContent> <ListItem.SupportingContent> <Text color={colors.onSurfaceVariant}> Last used: Today </Text> </ListItem.SupportingContent> <ListItem.TrailingContent> <Text color={colors.onSurfaceVariant}>1.57 GB</Text> </ListItem.TrailingContent> </ListItem> </Column> </Host> ); }