SDK 55のExpo UI:React NativeアプリでJetpack Composeが利用可能に
Product • React Native • Development • March 17, 2026 • 6分で読める
著者:
- Kudo Chien(エンジニアリング)
- Nishan Bende(エンジニアリング)
- Aleksander Mikucki(エンジニアリング)
SDK 55のExpo UIは、Jetpack Composeをベータ版として提供し、SwiftUI APIをAppleの規約に合わせることで、あなたのネイティブフレームワークの知識を直接活用できるようになりました。
Expo UIは、SwiftUIとJetpack ComposeをReact Nativeアプリに直接組み込みます。ネイティブコンポーネントをJavaScriptで再実装する代わりに、本物を公開します — ネイティブ開発者が得るのと同じコンポーネント、動作、プラットフォームの洗練性です。
SDK 54では、SwiftUIサポートとJetpack Composeの初期アルファ版でExpo UIを導入しました。それ以来、開発者はそれを使って構築しており、私たちはexpo-widgetsの基盤としてExpo UIを使用し、実際のプロダクション使用でアプローチを検証しました。
しかし、Jetpack Composeサポートはまだアルファ版で、完全なアプリに対してテストしていませんでした。SDK 55はその両方に対処しています。Jetpack Composeは現在ベータ版となり、完全なアプリを構築するのに十分なMaterial Design 3コンポーネントを備え、SwiftUI APIはAppleのものと密接に一致するよう再設計されました。そのため、どちらのフレームワークの既存知識も直接活用できます。
なぜこれが重要なのか
AppleとGoogleはSwiftUIとJetpack Composeに継続的に大きく投資しており、多くの最新APIとコンポーネントがそこに最初に登場します。それらをJavaScriptで再実装するのは多くの作業で、追いつくのが困難です。
Expo UIは異なるアプローチを取ります:ネイティブフレームワークを直接公開するのです。プラットフォーム機能が出荷されると同時に利用でき、API表面がSwiftUIとJetpack Composeの規約に従うため、これらのフレームワークを既に知っている開発者(またはAI)は、新しいことを学ぶことなくExpo UIコードを書くことができます。
Jetpack Compose:アルファからベータへ
Compose APIが実際の使用に準備できているかテストするため、私たちはExpo UIコンポーネントのみを使用してWikiReader(@nsh07のオリジナルのクローン)という完全なアプリを構築しました。何が不足しているか、どこに粗い部分があるかを見つけたかったのです。
アプリは全体を通してMaterial Design 3コンポーネントを使用しています — Card、LazyColumn、ListItem、DockedSearchBar、ModalBottomSheetなど。アプリが必要とするたびにコンポーネントを追加しました。すべてのコンポーネントは、アプリの実際の問題を解決することでその存在価値を証明する必要がありました。
Expo UIとJetpack Composeを使った設定画面は次のようになります:
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>
);
}
Jetpack Composeを使ったことがあれば、コンポーネント名と構造が馴染み深く見えるはずです — arrangementとpaddingを持つLazyColumn、modifierチェーン、leadingとtrailingコンテンツを持つListItem。Composeでは、これらをcomposableラムダパラメータとして渡します。Expo UIでは、Reactの複合コンポーネントパターン(ListItem.Leading、ListItem.Trailing)を使用して、JSXで同じレイアウトを表現します。
また、modifierシステムも整合させました。Jetpack Composeには独自のmodifierチェーンがあり、SwiftUI用の@expo/uiと同じスタイルでJSXに持ち込んだため、modifierは両プラットフォーム間で一貫して動作します:
<Box modifiers={[size(100, 100), background(Color.android.dynamic.primaryContainer)]}>
<Text modifiers={[padding(16)]}>Hello from Compose</Text>
</Box>
これにはスコープ付きmodifierも含まれます:RowとColumnは、Composeと同様に、weightやmatchParentSizeなどの独自の特定オプションを取得します。modifierについて詳しく学ぶ。
また、Material SymbolsのXMLベクタードローアブルをネイティブにレンダリングするIconコンポーネントも追加しました。Material SymbolsをXMLドローアブルとして使用することは、Jetpack Compose開発の一般的な慣行です。Material SymbolsからアイコンをAndroid drawable XMLファイルとしてダウンロードし、直接参照します:
<Icon source={require('./path/to/symbol.xml')} />
個別のXMLファイルをダウンロードするのが余分な作業に感じる場合は、AIエージェントに生成してもらうことを試してみてください。私たちの使用例ではうまく機能しました — AIはExpo UIコードとアイコンXMLファイルの両方を一緒に作成しました。
私たちはすべてのMaterial Design 3コンポーネントをラップすることを目指していません。WikiReaderクローンが必要とするものを追加し、需要に基づいて拡張し続けます。これらのコンポーネントの追加を手伝ってくれたすべての外部貢献者に感謝します。
@expo/ui/jetpack-composeドキュメントから詳しく学んでください。
SwiftUI:今やSwiftUIのように感じる
SDK 55では、SwiftUIコンポーネントをSwiftUIの対応するものと一致するよう名前変更と再構築を行いました。DateTimePickerはDatePickerに、SwitchはToggleに、CircularProgressはProgressViewになりました。
以前にSwiftUIで作業したことがあれば、コンポーネント名、modifier名、全体的な構造が馴染み深く感じるはずです。Appleのドキュメントで何かを調べるとき、それはExpo UIに直接マップされます。そのため、Appleのドキュメントを直接フォローし、翻訳レイヤーの学習をスキップでき、AIツールは既存のトレーニングデータから正しいコードを生成できます。
すべてのSwiftUIビューとmodifierをカバーできないため、Expo UIを拡張可能にしました。まだカバーしていないものについて、独自のカスタムSwiftUIビューとmodifierを作成できます。
hot-chocolateショーケースアプリはSDK 55と最新APIに更新されました。ExpoでSwiftUIを使った構築の完全な例として確認してください。
@expo/ui/swift-uiドキュメントから詳しく学んでください。
AIとの構築
ネイティブフレームワークとの整合の実用的な利点の一つは、AIとの連携の良さです。Expo UIはSwiftUIとJetpack Composeの規約に従うため、AIツールは既にパターンの深い知識を持っています。
私たちは、AIアシスタントにExpo UIの詳細を教えるexpo/skillsにスキルを追加し、より密接な統合のためにexpo-mcpを構築することで、これを活用しました。
ワークフロー:スクリーンショットをアップロードするか、欲しいものを説明すると、AIが既に知っているパターンを使用してSwiftUIとJetpack Compose両方のExpo UIコードを生成します。
今日このプロンプトを試してみてください:
@expo/ui/jetpack-composeコンポーネント(Column、Row、Switch、Slider)を使用してAndroid設定スタイルの画面を構築し、行アイコンにMaterial Symbolsを使用し、グループ化されたセクション(Network、Display、Sound、Privacy)にトグルスイッチと明度スライダーを備えたものを作成してください。
次は何か
私たちはExpo UIでのユニバーサルコンポーネントに向けて取り組んでいます:SwiftUIとJetpack Compose(そして潜在的にはwebでも)で動作する共有コンポーネントAPIです。
しかし今は、SDK 55についてのフィードバックをお聞かせください。Expo UIでアプリを構築してみてください — @expo/ui/swift-ui側でも@expo/ui/jetpack-compose側でも — そして結果を教えてください。どのコンポーネントが不足していますか?何が違和感を感じますか?あなたの意見が、私たちが次に構築するものを直接形作ります。