---
title: 'Expo UI in SDK 55: Jetpack Compose now available for React Native apps'
authors: Kudo Chien, Nishan Bende, Aleksander Mikucki
published: March 17, 2026
categories: Product, React Native, Development
tags: Expo UI, SDK 55
---

Expo UI brings SwiftUI and Jetpack Compose directly into your React Native app. Instead of reimplementing native components in JavaScript, it exposes the real thing — the same components, behavior, and platform polish that native developers get.

In [SDK 54](https://expo.dev/blog/liquid-glass-app-with-expo-ui-and-swiftui), we introduced Expo UI with SwiftUI support and an early alpha for Jetpack Compose. Since then, developers have been building with it — and we used Expo UI as the foundation for [expo-widgets](https://docs.expo.dev/versions/latest/sdk/widgets/), which validated the approach for real production use. But Jetpack Compose support was still in alpha, and we hadn't tested it against a complete app yet.

SDK 55 addresses both. Jetpack Compose is now in beta with enough [Material Design 3](https://m3.material.io/) components to build a complete app, and SwiftUI APIs have been reworked to closely match Apple's; so your existing knowledge of either framework transfers directly.

## Why this matters

Apple and Google continue to invest heavily in SwiftUI and Jetpack Compose, and many of the newest APIs and components arrive there first. Reimplementing them in JavaScript is a lot of work that's hard to keep up with.

Expo UI takes a different approach: **expose the native frameworks directly**. You get new platform features as they ship, and because the API surface follows SwiftUI and Jetpack Compose conventions, any developer (or AI) that already knows those frameworks can write Expo UI code without learning something new.

## Jetpack Compose: from alpha to beta

To test whether the Compose APIs were ready for real use, we built a complete app called [WikiReader](https://github.com/expo/wiki-reader) (a clone of [@nsh07](https://github.com/nsh07)'s [original](https://github.com/nsh07/WikiReader)) using only Expo UI components. We wanted to find out what was missing and where the rough edges were.

![Jetpack Compose: from alpha to beta](https://cdn.sanity.io/images/9r24npb8/production/909ca141a32f59fca0866a1d3084026ef46e116e-1600x1318.png)

The app uses Material Design 3 components throughout — `Card`, `LazyColumn`, `ListItem`, `DockedSearchBar`, `ModalBottomSheet`, and more. We added each component as the app needed it. Every component had to earn its place by solving a real problem in the app.

Here's what the settings screen looks like in Expo UI with Jetpack Compose:

```typescript
import { useState } from "react";
import { useColorScheme } from "react-native";
import { Host, Switch, Icon, ListItem, LazyColumn } from "@expo/ui/jetpack-compose";
import { clip, Shapes } from "@expo/ui/jetpack-compose/modifiers";

export default function SettingsScreen() {
  const colorScheme = useColorScheme() ?? "light";
  const [wifi, setWifi] = useState(true);
  const [bluetooth, setBluetooth] = useState(false);
  const [darkMode, setDarkMode] = useState(false);

  return (
    <Host style={{ flex: 1 }} colorScheme={colorScheme}>
      <LazyColumn
        verticalArrangement={{ spacedBy: 2 }}
        contentPadding={{ start: 16, end: 16, top: 8, bottom: 16 }}
      >
        <ListItem headline="Wi-Fi" supportingText="Connected" modifiers={[clip(Shapes.RoundedCorner({ topStart: 12, topEnd: 12 }))]}>
          <ListItem.Leading>
            <Icon source={require("../../assets/icons/wifi.xml")} tintColor="#1d1b20" />
          </ListItem.Leading>
          <ListItem.Trailing>
            <Switch value={wifi} onValueChange={setWifi} />
          </ListItem.Trailing>
        </ListItem>
        <ListItem headline="Bluetooth" supportingText="Off">
          <ListItem.Leading>
            <Icon source={require("../../assets/icons/bluetooth.xml")} tintColor="#1d1b20" />
          </ListItem.Leading>
          <ListItem.Trailing>
            <Switch value={bluetooth} onValueChange={setBluetooth} />
          </ListItem.Trailing>
        </ListItem>
        <ListItem headline="Dark mode" modifiers={[clip(Shapes.RoundedCorner({ bottomStart: 12, bottomEnd: 12 }))]}>
          <ListItem.Leading>
            <Icon source={require("../../assets/icons/dark_mode.xml")} tintColor="#1d1b20" />
          </ListItem.Leading>
          <ListItem.Trailing>
            <Switch value={darkMode} onValueChange={setDarkMode} />
          </ListItem.Trailing>
        </ListItem>
      </LazyColumn>
    </Host>
  );
}
```

If you've used Jetpack Compose, the component names and structure should look familiar — `LazyColumn` with arrangement and padding, modifier chains, `ListItem` with leading and trailing content. In Compose, you'd pass these as composable lambda parameters. In Expo UI, we use React's compound component pattern (`ListItem.Leading`, `ListItem.Trailing`) to express the same layout in JSX.

We also aligned the modifier system. Jetpack Compose has its own modifier chain, and we brought that to JSX in the same style as `@expo/ui` for SwiftUI, so modifiers work consistently across both platforms:

```typescript
<Box modifiers={[size(100, 100), background(Color.android.dynamic.primaryContainer)]}>
  <Text modifiers={[padding(16)]}>Hello from Compose</Text>
</Box>
```

This includes scoped modifiers: `Row` and `Column` get their own specific options like `weight` and `matchParentSize`, just like in Compose. [Learn more about modifiers](https://docs.expo.dev/versions/latest/sdk/ui/jetpack-compose/modifiers/).

We also added an [`Icon`](https://docs.expo.dev/versions/latest/sdk/ui/jetpack-compose/icon/) component that natively renders Material Symbols XML vector drawables using Material Symbols as XML drawables is a common practice in Jetpack Compose development. You download icons from [Material Symbols](https://fonts.google.com/icons) as Android drawable XML files and reference them directly:

```typescript
<Icon source={require('./path/to/symbol.xml')} />
```

If downloading individual XML files feels like extra work, try asking your AI agent to generate them for you. It worked well for our use case — the AI created both the Expo UI code and the icon XML files together.

We don't aim to wrap every Material Design 3 component. We added what the WikiReader clone needed and will keep expanding based on demand. Thank you to all the external contributors who helped add these components.

[Learn more from `@expo/ui/jetpack-compose` documentation](https://docs.expo.dev/versions/latest/sdk/ui/jetpack-compose/).

## SwiftUI: now it feels like SwiftUI

In SDK 55, we've renamed and restructured SwiftUI components to match their SwiftUI counterparts. `DateTimePicker` is now `DatePicker`, `Switch` is now `Toggle`, and `CircularProgress` is now `ProgressView`. If you've worked with SwiftUI before, the component names, modifier names, and overall structure should feel familiar. When you look something up in Apple's documentation, it maps directly to Expo UI; so you can follow Apple's documentation directly, skip learning a translation layer, and AI tools can generate correct code from their existing training data.

Since we can't cover every SwiftUI view and modifier, we've also made Expo UI extensible. You can [create your own custom SwiftUI views and modifiers](https://docs.expo.dev/guides/expo-ui-swift-ui/extending/) for anything we don't cover yet.

The [hot-chocolate showcase app](https://github.com/expo/hot-chocolate) has been updated to SDK 55 and the latest APIs. Check it out for a complete example of building with SwiftUI in Expo.

[Learn more from `@expo/ui/swift-ui` documentation](https://docs.expo.dev/versions/latest/sdk/ui/swift-ui/)

## Building with AI

One of the practical advantages of aligning with native frameworks is how well it works with AI.

Because Expo UI follows SwiftUI and Jetpack Compose conventions, AI tools already have deep knowledge of the patterns. We leaned into this by adding skills to [expo/skills](https://github.com/expo/skills) that teach AI assistants the Expo UI specifics, and built [expo-mcp](https://docs.expo.dev/eas/ai/mcp/) for tighter integration.

The workflow: upload a screenshot or describe what you want, and the AI generates Expo UI code for both SwiftUI and Jetpack Compose using patterns it already knows. Try this prompt today:

> _Build an Android Settings-style screen using `@expo/ui/jetpack-compose` components (Column, Row, Switch, Slider) with Material Symbols for row icons, featuring grouped sections (Network, Display, Sound, Privacy) with toggle switches and a brightness slider._

## What's next

We're working toward **universal components** in Expo UI: a shared component API that works across SwiftUI and Jetpack Compose (and potentially on web as well).

But right now, we'd love your feedback on SDK 55. Try building an app with Expo UI — whether it's the [`@expo/ui/swift-ui`](https://docs.expo.dev/versions/latest/sdk/ui/swift-ui/) or [`@expo/ui/jetpack-compose`](https://docs.expo.dev/versions/latest/sdk/ui/jetpack-compose/) side — and tell us how it goes. _What components are missing? What feels off?_ Your input directly shapes what we build next.