Expo SDK 58 ベータ公開:iOS 27、Expo Modules 2.0、Rust 製バンドラー

SDK 58 beta では iOS 27 と Liquid Glass への対応、Expo Modules 2.0、コールドスタート時のバンドルが約2倍速くなる Rust トランスフォーマー、そして一連の破壊的変更が導入される。Expo Go は当面 CLI 経由でしかインストールできない。

日本語
コピー
深色底上的 Expo SDK 58 beta 宣传图,标注 SDK 58 beta 包含 React Native 0.88 Release Candidate

SDK 58 の beta 期間は今日から3〜4週間。 beta 期間は、開発者が新バージョンを試し、自分のシステムやアプリ構成でリグレッションが入っていないか確認するための期間です。この間も修正と改善を出し続けます。

SDK 58 は iOS 27 向けにビルドされています。今すぐ iOS 27 対応が必要なら、beta 版のままリリースして構いません。SDK 58 beta には React Native 0.88(Release Candidate)が含まれます。0.88 はまだ正式リリースされていないため beta では RC を使っており、0.88 が正式リリースされ次第 stable に切り替え、その後まもなく SDK 58 をリリースします。SDK 58 の完全な release notes は stable まで出ませんが、今回のリリースの規模と破壊的変更は expo/expo リポジトリの各 changelog で今すぐ確認できます。beta が終わったら、すべての changelog をルートの CHANGELOG.md に統合します。

SDK 58 の Expo Go は現時点では Expo CLI 経由でしかインストールできません。対応するのは Android の実機とエミュレータ、iOS シミュレータです。iOS 実機は eas go から(詳細)。App Store と Google Play の Expo Go は stable リリース後まもなく SDK 58 に更新されるので、ストア版が SDK 57 のサポートを切る前にアップグレードする時間はあります。

Discord でoffice hoursも開きます。今回のリリースのテストに協力したい人はぜひ。

SDK 58 は iOS 27 向けにビルド

iOS 27 では UIKit の scene ライフサイクルが必須になり、iPhone アプリはリサイズ可能になります。iOS 27 SDK でビルドしたアプリはこの2つを自動的に得ます。Expo アプリは iOS 27 で正しく起動するために scene ライフサイクルへ移行しました(#46733)。これにより app delegate コールバックの配送方法が変わるので、AppDelegate.swift をカスタマイズしている場合はscene ライフサイクル移行ガイドを読んでください。Expo の各パッケージは UIScreen.main からジオメトリ情報を読まなくなり(#48172#48315#48316#48170#48169)、expo-modules-core も scene を認識するジオメトリユーティリティを提供します(#48168)。

iOS 27 では requireFullScreen でアプリのリサイズを無効化できなくなり、アプリがリサイズ可能なときは ScreenOrientation.lockAsync がまったく効かない可能性があります。requireFullScreen の config plugin はこれに対応済みです(#48175)。iOS 27 以降での画面向き固定も参照してください。iOS 27 SDK でビルドしたアプリでは、expo-glass-effectisLiquidGlassAvailabletrue として報告します(#49850)。

beta 期間中は、iPhone Duo SDK が開発者に開放された初日から深い統合を実現できるよう、引き続き改善を進めます。

Xcode 27 と SDK 58 ツールチェーンを載せた EAS Build イメージはまもなく提供予定で、使えるようになり次第この記事を更新します。それまでは latestEAS Build イメージに Xcode 26.6 が入っています。

Xcode 27 の Device Hub 対応

Xcode 27 では Simulator.app が Device Hub に置き換わりました。Expo CLI は Device Hub を認識してシミュレータを起動し、devices:// のディープリンクで対象デバイスにフォーカスします(#46757#46809)。エディタを離れたくない人には、新しい expo-device-hub 開発ツールプラグインがあります。ブラウザがローカルデバイスのパネルになり、すべての iOS シミュレータと Android エミュレータのライブ画面を直接タップ・スワイプ・入力でき、起動/シャットダウン操作、CPU/メモリ/ネットワークのグラフ、外観・Liquid Glass・文字サイズ・アクセシビリティ設定のトグルも使えます。インストールして(npx expo install expo-device-hubnpx expo start を実行すると、ターミナルにリンクが表示されます。同じ体験を Xcode や Android Studio のないマシンで求めるなら、近日公開のクラウドシミュレータサービス EAS Simulator に注目してください。

ブラウザ内の expo-device-hub パネル。左側に iOS 27 の iPhone 17 Pro Max シミュレータと Pixel 9 シミュレータが並び、中央にはアプリのライブ画面、右側には CPU、メモリ、ネットワークのグラフと、外観、Liquid Glass、文字サイズ、アクセシビリティなどのデバイス設定が表示される。
expo-device-hub が、iOS 27 を実行する iPhone 17 Pro Max のシミュレータをストリーミングしている。出典:Nathan Schroeder の X への投稿。

App Intents:アプリを Siri と Apple Intelligence に公開する

expo-app-intents を使うと、Expo アプリで Apple の App Intents(Siri、ショートカット、Spotlight、Apple Intelligence)を宣言できます(#47207)。App Intent の型は app-intents ディレクトリ内の Swift inline module に書きます。Apple がビルド時にメタデータを抽出できるのは app target 内のコードだけだからです。このパッケージは呼び出しを JavaScript に配送し、entity の値を保持します。npx expo-app-intents init を実行するとこのディレクトリが作成されます(#47223)。このライブラリはまだ alpha で、ドキュメントとサンプルは追って追加されます。

例:Siri でタスクを完了させる

ある onboarding チェックリストアプリが「タスクを完了する」という intent と、タスクの entity を宣言している。Siri にタスクを完了したいと話しかけると、Siri がアプリ内のタスクを一覧表示してどれか尋ねる。選ぶと intent があなたの JavaScript で実行され、アプリがそれを完了済みにする。アプリを前面に出す必要は一切ない。

iPhoneのスクリーンショットが2枚。左側ではSiriが「Which task did you complete?」と尋ね、アプリ内のオンボーディングタスク(「Sign offer letter」「Upload ID documents」など)を一覧表示している。右側ではSiriがアプリのリストの上に「Marking Upload ID documents as done」と表示し、そのタスクにはチェックが入っている。
Expo アプリから公開された App Intent:Siri がどのタスクを完了するのかを尋ね、アプリ内でその intent を実行する。

Expo UI:iOS のネイティブナビゲーション、新しい Compose コンポーネント、その他いろいろ

すべてのコンポーネントにドキュメントのプレビュー画像が付いた

Expo UI のリファレンスドキュメントでは、各コンポーネントの API の隣にスクリーンショットが表示されるようになった。props を読む前に、何を選ぼうとしているのかが一目で分かる。ドキュメント内の SwiftUIJetpack Compose のギャラリーを見てほしい。

ドキュメントに並べて表示された Expo UI コンポーネントのプレビューグリッド。左が iOS の SwiftUI コンポーネント、右が Android の Jetpack Compose コンポーネント。
Expo UI のドキュメントにある、SwiftUI と Jetpack Compose のコンポーネントギャラリーの一角。

iOS ナビゲーション。 @expo/uiNavigationStackToolbarNavigationLinkNavigationDestination コンポーネント、navigationTitle 修飾子、close ボタンロールが追加された(#49940#49991)。NavigationSplitView は 2 カラムと 3 カラムのレイアウトに対応した(#50075)。

SwiftUI。 backgroundtintborderstrokeBordercontainerBackgroundpresentationBackgroundforegroundStyle の各修飾子が任意の ShapeStyle を受け取れるようになり、ビューをマテリアルやグラデーションで着色できる(#48905#49621#49767#49838)。新しく加わったのは Background コンポーネント(#48904)と、scrollClipDisabled#49780)、geometryGroup#48838)、listRowSeparatorTint#48810)、alignmentGuide#49247)、menuStyle および menuIndicator#48448)の各修飾子。

Jetpack Compose。 新しく追加されたのは Image#48521)、DateRangePickerDateRangePickerDialog#49788)、VerticalSlider#49612)コンポーネント。DropdownMenu には cornerRadiusshadowElevation が加わり(#49515#49896)、RadioButton には enabledcolors が加わった(#49852)。

共通コンポーネント。 BottomSheetcontentPaddingcontainerColorcontentColor が加わり、ListItemcolors に対応した(#48902#49575)。Web では BottomSheet がメンテナンスされなくなった vaul を外し、自前の HTML <dialog> に切り替えた(#49509)。

ホストされた React Native ビュー。 <RNHostView> の中に置いたビューが、SwiftUI と Jetpack Compose が配置する位置に基づいて測定されるようになった(#48969#48970)。これにより、タップが失われる、ジェスチャーを外側のスクロールコンテナに取られる、BottomSheetPopoverAlertDialogDropdownMenu の内部がタップできないといった問題が直った。ホストされたテキストフィールドの外側をタップするとキーボードが閉じるようになった(#48788)。SwiftUI の Menu を閉じるタップが、その下にある React Native ビューを押してしまうこともなくなった(#48463#49775)。

Expo と EAS Observe

EAS Observe は本番環境でアプリのパフォーマンスとエラーを監視するツールで、8 月 20 日から正式に利用できるようになった。SDK 58 では expo-observeObserve.registerIntegration#48245)、ObserveErrorBoundaryreportError#47341#47871)、errorHandlingEnabled オプション(#48506)、expo-image 連携(#47145)、そして Observe.clientId——各イベントに記録される EAS client ID——が加わった(#49599)。AppMetrics は廃止され、Observe に置き換わった。詳しくは廃止項目を参照。

EAS Observe の概要パネル。アクティブユーザー、セッション、3 バージョンのリリース比較表を表示し、操作可能になるまでの時間、初回描画時間、クラッシュなしセッション率、クラッシュなしユーザー率、エラー数、影響を受けたユーザー数を確認できる。
EAS Observe の概要:バージョン間で起動指標・クラッシュフリー率・エラーを比較できます。

@expo/agent-cli:agent のために設計された新しい CLI

これまで agent が Expo を学ぶのは我流だった。Expo Go を起動し、Expo Go が対応していない native module を足してランタイムエラーにぶつかり、development build を使うべきだと自力で推測する。どこで Expo CLI を使い、どこで EAS CLI を使うべきかも把握しなければならない。@expo/agent-cli は agent が作り、agent のために設計した新しい実験的 CLI だ。Expo CLI、EAS CLI、expo-doctor の上に載っていて、Expo CLI にフォールバックする。だから agent にこれまでのツールの代わりに使わせればいい。

いくつか便利なコマンドがある。status はアプリを起動せずに Expo Go との互換性を答える。dev はコマンド1つでアプリを動かす。web フレームワークがサーバーとブラウザを同時に立ち上げるのに似ていて、ビルドが必要かどうかは自分で判断し、最速の方法でアプリを起動しようとする。コマンドが次の一手を出力するので、agent はそのまま進められる。smokedev にスクリーンショットと停止を足したもので、手元のマシンで開発を始められることを確認するために使う。skills:syncnode_modules にある同じ位置の agent skills を自分のプロジェクトにインストールする。

まず npx @expo/agent-cli@latest agents:setup から始めて、agent には Expo CLI の代わりに @expo/agent-cli を使わせよう。

もっと短い名前がよければ、expo-agent-cli がエイリアスだ。このパッケージ名を譲ってくれた Kazutoyo Tokai に感謝する。この CLI はまだ活発に開発中で、いずれブログで詳しく書く。それまでは試してみて、感想を聞かせてほしい

ホーム画面ウィジェットが Android に登場

expo-widgets に Android 実装が加わった。ウィジェットは専用の Hermes ランタイムで自分の JS bundle を実行し、インタラクションと Material Colors に対応する(#46961#47035#48454)。iOS では Live Activities の LiveActivity.start()update()staleDate オプションが増え(#46343)、ActivityKit の識別子が安定し(#48589)、ウィジェット設定が実行時の変更に対応した(#47533)。

Swift Package Manager ビルド

React Native 0.87 に実験的な Swift Package Manager サポートが入り、CocoaPods に代わる選択肢となった。SDK 58 は Expo アプリの下地を整えた形だ。Expo の iOS ソースはリファクタリングされ、Swift、Objective-C、C++ がそれぞれ独立した SwiftPM target としてコンパイルされる(#45906#49820#49821#49832)。React Native npx react-native spm パイプライン向けの Expo autolinking プラグインは review 中で(#49823)、beta 期間中にプレビューとして公開する予定だ。CocoaPods は引き続きデフォルトでサポートされる経路であり、プリコンパイル済みの Expo module もこれまでどおり動作する。

Expo Modules:ビルドが速く、呼び出しが速く、書き方が簡単に

プリコンパイル済み expo-modules-core で Android ビルドを高速化

expo-modules-core は Android 向けにプリコンパイル済みのネイティブライブラリを提供するようになった。これまでクリーンビルドのたび、CI のたび、EAS Build のたびに libexpo-modules-core.so の C++ をソースからコンパイルしており、Expo を使った Android ビルドで最も高くつく工程だった。今は npm パッケージに4つの ABI すべての .so ファイルが含まれ、debug と release の両バリアントをカバーする。空の SDK 58 プロジェクトで計測したところ、4つの ABI の Android debug クリーンビルドは Apple M3 Pro で約80秒、expo-modules-core の C++ コンパイルを飛ばすと約39秒まで縮まり、ほぼ半分になる。コア数の少ないマシン(CI runner など)では削減幅はさらに大きい。省かれるコンパイル量は4つの ABI を合計すると10分を超えるが、12コアのマシンでは多数のファイルを並列に処理することでこれまで隠れていた。

速くなった Expo モジュール

native module の呼び出しは無料ではない。Swift や Kotlin に跨り、値を双方向に変換する固定費がかかり、安価な呼び出しではコストの大半がここに消える。SDK 56 は両プラットフォームでこの部分に手を入れた。iOS ではObjective-C++ レイヤーを取り除き、呼び出しが1.6〜2.3倍速くなった。Android ではリフレクションを Kotlin コンパイラプラグインに置き換えRecord の変換が約6倍速くなり、初回レンダリング時間が約30%短縮した。

SDK 58 は iOS 側でもう一段進めた。単純な値を受け渡し・返却する呼び出しが安くなり(#49761)、長い文字列を双方向に渡すのが最大3.8倍速くなり(#49678)、async 関数が返す promise の生成と resolve のオーバーヘッドも下がった(#49718)。必要な作業は何もない。SDK 58 に上げれば、自分で書いていないものも含めすべての Expo module が速くなる。

Expo Modules 2.0 beta

もう一つの話は、コードを書くときに向き合う API だ。既存の DSL 定義で native module を記述する代わりに、普通の Swift または Kotlin クラスをそのまま書き、JavaScript に公開したいメソッドとプロパティにアノテーションを付けるだけでよくなった。覚えることはこのアノテーション以外に何もなく、コーディング agent にとっても扱いやすい。独自 DSL をまず説明する必要はなく、Swift と Kotlin そのものだから、モデルはもともとよく知っている。

その改良の上に、さらに速い。アノテーションのおかげで、実行時に探すのではなくビルド時に最も直接的な binding を生成できる。同じ SDK で iPhone 16 Pro の Release ビルドを計測したところ、同期呼び出しは DSL より 2.5 倍から 5.6 倍速い。Expo Modules 2.0 抢先看にはベンチマークデータがあり、この API についてもより深く解説している。

Android の Kotlin 側でも同じパターンが見られ、今回は React Native の TurboModules とも比較した。12 項目のマイクロベンチマークで、Expo Modules 2.0 はすべての項目で Expo Modules 1.0 より速く、100 個の数値配列を渡す場合の 1.2 倍から、数値を伴うイベントを送る場合の 39.9 倍まで幅がある。TurboModule との比較でも全項目で上回った。引数なしの呼び出しで 112 ns 対 2,837 ns、20 個のオブジェクト配列を渡す場合で 10.7 µs 対 149.8 µs、オブジェクトを伴うイベント送信で 963 ns 対 8,080 ns だ。

Android のマイクロベンチマーク12項目で TurboModule、Expo Modules 1.0、Expo Modules 2.0 を比較した。2.0 はどの項目でもバーが最も短く、引数なしの関数呼び出しからオブジェクト付きイベントの送信まで一貫している。
Expo Modules 2.0 と Expo Modules 1.0 / TurboModule の Android マイクロベンチマーク。短いほど良い。緑のラベルは 2.0 と 1.0 の比較。

SDK 57 では iOS マクロが実験的にリリースされた。SDK 58 beta では、Expo Modules 2.0 が iOS と Android の両方で beta になる。ドキュメントは beta 期間中に整備される予定で、それまでは抢先看のブログ記事が最良の手引きになる。

fingerprint の新しいデフォルト:不要なネイティブ再ビルドを減らす

バージョン番号を変えたり、node_modules 内のファイルに触れたりしても、fingerprint は変化しなくなった。SDK 58 では fingerprint のデフォルトが balanced プリセットに変わった(#47668)。app.jsonversion を更新するといったよくあるケースを無視し、native module のハッシュをファイルやディレクトリではなくパッケージ名とバージョンで計算する。追加設定は不要で、ハッシュは安定したままになる。異なるトレードオフが必要な場合はfingerprint プリセットを参照してほしい。

実験的:Rust 製トランスフォーマーでコールドバンドルを約 2 倍高速化

Metro のキャッシュがあればホットバンドルは速いが、コールドバンドルは——プロジェクト全体でも変更されたモジュールでも——ほとんどの時間を Babel が占める。SDK 58 では実験的な代替手段を導入する。それが「Noxcturnal」、oxc をベースにした Rust 製の module transformer で、napi-rs を通じて Node.js に公開される。社内テストでは、単一モジュールの変換時間が約 3 倍、エンドツーエンドのコールドバンドルが約 2 倍速くなった(#48443)。最大のテストアプリでは、約 5,500 ファイルのコールドバンドルが Babel の 5.26 秒から新しいトランスフォーマーの 2.46 秒に短縮され、そのうち 443 ファイルは依然として Babel にフォールバックしている。

同じアプリの変換時間を2通りで比較した。Noxcturnal を有効にすると 5,477 ファイルが 2.46 秒で完了し、Babel では 5,494 ファイルに 5.26 秒かかる。
最大のテストアプリをコールドビルドしたときの変換 worker の動きを示したものだ。上が新しい変換器、下が Babel。出典:Phil Pluckthun の X への投稿。

app config で experiments.noxcturnalTransformWorker を設定すると試せる。プロジェクトにカスタム transform worker や Babel プラグイン/プリセットがない場合にのみ有効で、Reanimated や Worklets の Babel transform が必要なファイルはスキップされる。まだ非常に初期の取り組みで、実装も数値も安定するまで変わりうる。カスタム Babel transform を使うプロジェクトを含め、より多くのプロジェクトで使えるよう設定項目を追加する予定だ。

Expo Router:データローダーとネイティブタブが安定、ナビゲーションコアを改善

データローダーサーバーサイドレンダリングミドルウェアはすべて安定機能になり、実験的なフラグは不要になった。ネイティブタブツールバー標準ナビゲーション統合も安定した。

Expo Router のナビゲーションコアも書き直され、ナビゲーション状態が決定的で推論しやすくなり、fork された React Navigation API の大部分を抱えなくなった。ほとんどのアプリは気づかないだろう。ただしカスタム navigator を書いたり、expo-router/react-navigation からインポートしたりしていた場合、一部の API は移行または削除されている。必要なものが見当たらない場合は、何をしたいのかを添えてissue を立ててほしい

その他の変更は以下に列挙する。ドキュメントへのリンクは順次追加していく。

  • Navigator の移行:JavaScript の TabsTopTabsDrawerNativeTabs と同じ standard-navigation 統合を使うようになり、挙動がより一貫した。

  • Loader キャッシュloader 内で expo-server から setResponseHeaders({ 'Cache-Control': 'private, max-age=60' }) を呼ぶと、クライアントがそのレスポンスを 60 秒間キャッシュできる。

  • React transitions と Activity:ナビゲーションは React transitions を使い、次の画面が読み込まれる間も現在の画面を表示し続ける。navigator や screen に activityEnabled を設定するか、NavigationAwareActivity で画面の一部を包むと、状態を保ち effect をクリーンアップしつつ、非アクティブなコンテンツを隠せる。

  • Web では非同期ルーティングがデフォルトで有効expo-router 設定プラグインが web 向けに asyncRoutes を自動で有効にする。ルートファイルは個別の JavaScript chunk に分割され、ブラウザがそのルートに遷移したときに読み込まれる。asyncRoutes: { web: false } を設定すればオフにできる。

  • カスタム router APIextendRouter で組み込み router の一部を上書きしたり、extendRouterActions でカスタムナビゲーションアクションに handler を追加したりできる。

  • スクリーン単位のエラーバウンダリ:layout に unstable_settings.screenErrorBoundary を設定するか、<Stack unstable_screenErrorBoundary={MyErrorBoundary} /> を渡せば、エラーを投げたスクリーンにフォールバック UI を表示しつつ、navigator はマウントされたままにできる。

  • オプションの依存関係:Android で md prop 付きの NativeTabs.Trigger.Icon を使うには expo-symbols のインストールが必要で、Stack.Toolbar を使うには @expo/ui が必要。どちらもオプションの peer 依存関係になった。

アップグレードの際は移行ガイドを読んでほしい。カスタム navigator を使っている場合や expo-router/react-navigation からインポートしている場合は特に。

プロキシとトンネル経由で dev server に接続する

dev server がプロキシの背後やリモートマシン上で動いていたり、トンネル経由で公開されていたりする場合、development build が安定して接続できるようになったはずだ。これまで development build は起動時に取得する manifest で使用する bundle URL と debugger hostname を受け取っていたが、サーバーがプロキシの背後にある場合や Bonjour で検出された場合、そのアドレスはクライアントから到達できないことがあった。クライアントが対応していれば、manifest は相対 URL を使うようになった(#47255#48997)。

RCT_METRO_PORT はプリコンパイル済み React Native ではコンパイル時マクロで、8081 に固定されている。そのため expo-dev-client を持たない bare アプリは常に 8081 としか通信せず、そうしたアプリを2つ同時に動かすと互いの reload コマンドに応答してしまう。prebuild はポートを Info.plistRCTMetroPort キーに書き込み、アプリは起動時にそれを読むようになった(#48098)。Expo CLI のポート選択も一貫性が増し、非対話実行時に即座に失敗するのではなく、次の空きポートにずれるようになった(#47771#48300)。

より速く、より信頼できる Expo CLI トンネル

Expo CLI に @expo/ws-tunnel 2.0 ベースの新しいトンネル実装が入った(#46696)。接続が速く、安定し、@expo/ngrok も不要になった。試すには:

EXPO_UNSTABLE_TUNNEL_V2=1 expo start --tunnel

使うには Expo アカウントへのログインが必要(expo login)。

EXPO_UNSTABLE_TUNNEL_V2 スイッチは SDK 58 beta の後半で削除され、これがデフォルトのトンネル実装になる。

React Native 0.88(Release Candidate)

SDK 58 beta は React Native を 0.86 から 0.88 release candidate に引き上げ、React Native 0.87React Native 0.88 release candidate の変更を同時に取り込んだ。0.88 の要点は:

  • Swift Package Manager ツール:オプションの npx react-native spm コマンドと SwiftPM パッケージ生成。CocoaPods は引き続きデフォルトでサポートされる経路。

  • Text 上の fontVariationSettings:オブジェクト構文で可変フォントの軸を設定でき、同じバージョンで expo-font に入った可変フォント対応とうまく噛み合う。

  • TurboModules の ArrayBuffer:JavaScript の ArrayBuffer 値が Android と iOS の両方でネイティブ表現を持ち、バイト所有権の取り決めも明示された。

  • React Native DevTools:実験的なパフォーマンススナップショットと、Network パネルでの WebSocket 検査。

詳細は React Native 0.87 release notesReact Native 0.88.0-rc.0 release notes を参照。React Native 0.88 のブログが出たら、ここにリンクを追加する。

PostHog 連携

コマンド1つで Expo アプリに PostHog を組み込めるようになり、捕捉されるすべてのイベントがどの EAS update 由来かを把握できる。eas integrations:posthog:connect を実行すると、EAS CLI が PostHog プロジェクトを作成または連携し、SDK とその設定プラグインをインストールし、環境変数をプロジェクトと EAS に書き込む。PostHog は eas/update_ideas/build_ideas/channeleas/runtime_version といったプロパティを認識し、expo.dev に紐づける。これは EAS CLI の機能なので、どの SDK バージョンでも使える。PostHog 連携 changelogPostHog の使い方ガイドも読んでほしい。

その他の注目すべき変更

  • expo-cameraCameraView.scanDocumentAsync を追加。Android と iOS で複数ページのドキュメントスキャンができる(#47362)。

  • expo-file-systemFile.digest() を追加。MD5/SHA-1/SHA-256/SHA-384/SHA-512 ハッシュに対応する(#48089)。ネイティブプレビューフロー向けの File.preview()File.canPreview() も追加。

  • expo-audio:プレイリスト付きのロック画面コントロールを追加(#46020)。AudioStream.startFileRecordingAsync で WAV/PCM ファイルを録音できるようにもなった(#46771)。

  • expo-imagetransition.skipOnCacheHit を追加。キャッシュヒット時にトランジションをスキップする(#48181)。さらに svgVariables prop を追加。SVG 内で var() から参照する CSS カスタムプロパティの値を置き換えるもので、同じドキュメントの別々の部分に異なる色を割り当てても画像はベクターのまま保てる(#48663)。値は色に限らない。var() を使う SVG は、この prop を渡さなくてもフォールバック値でレンダリングされるようになった。

  • expo-secure-store:Android に requireConfirmation を追加。認証が必要な読み書きに使う(#48556)。

  • expo-dev-launcherdisableFab=1disableAutoLaunch=1 という 2 つの URL パラメータを追加。フローティングボタンを隠し、起動時に dev menu が自動で開くのを防ぐ(#49651)。

  • expoURLURLSearchParams を書き直し、IDNA/TR-46 に対応(#47813)。TextDecoder は速度のために書き直した(#48877)。

  • expo-sqlite:同梱の agent skill でベストプラクティスを agent に共有できる。npx @expo/agent-cli skills:sync を実行すれば自分のプロジェクトにインストールできる(#49867)。

  • expo-font:Android、iOS、web で可変フォントに対応。1 つのフォントファイルで複数のウェイトや字形を含む family を提供できる。useFontsloadAsync、設定プラグインのいずれからも使える(#48129#48621#48432#49486#49487#49485)。詳しくはこちら

  • expo-notifications:iOS では、通知センターへの呼び出しが別のライブラリが登録した UNUserNotificationCenterDelegate に転送される。これにより expo-notifications は他のプッシュライブラリと同じアプリ内で共存できる(#48313)。通知は threadIdentifier でグループ化できるようにもなった(#49429)。Android では、日付と繰り返しのトリガーに delivery: 'alarmClock' オプションを追加。AlarmManager.setAlarmClock() を使う——OEM の省電力ポリシーでも遅延しない——ので、時間に敏感なアラームに向く(#49687)。設定プラグインには largeIcon 属性を追加(#49481)。詳しくはこちら

  • expo-location:位置プロバイダーの抽象化レイヤーを中心に expo-location を書き直している。よりシンプルな位置情報 API、位置の監視、バックグラウンドでの位置更新、iOS の一時的な全精度をリクエストするなどの新しい権限オプションが入る(#49849#49972#49988)。この書き直しはオプトインのプレビューとして既存 API と併存するので、この beta にある expo-location のコードは何も変更しなくていい。試せるようになったら改めて詳しく書く。

  • @expo/cli:Android 仮想デバイス(AVD)と adb の管理を書き直し、失敗に対してより堅牢にした(#49258)。

非推奨

  • expo-file-systemFile.md5 を非推奨。File.digest() を使う(#48089)。

  • expo-modules-coreNativeArrayBuffer を非推奨。ArrayBuffer を使う(#47106)。

  • expo-observeAppMetrics のエクスポートを非推奨。Observe を使う(#48901)。

  • expo-sqliteuseLibSQL 設定プラグインの属性を非推奨。今後は何の効果もない(#48543)。

  • @expo/ui:iOS では backgroundOverlay を非推奨。background を使う(#49621)。borderstrokeBordercolor パラメータを非推奨。content を使う(#49838)。

注目すべき破壊的変更

  • React Native の strict TypeScript API:React Native 0.87 で strict TypeScript API がデフォルトになった。react-native/Libraries/* からの deep import は型エラーになり、一部の型の形も変わった。最も目立つのは ref で、ViewInstanceTextInputInstance といったインスタンス型を使うようになっている。移行ガイドに沿って進めるか、migrate-to-strict-api skill を使って agent に任せてもいい。移行を先送りしたい場合は tsconfig.json"customConditions": ["react-native", "react-native-legacy-deep-imports"] を設定する("react-native" は残し、expo/tsconfig.base は設定済み)。このオプトアウトは React Native 0.88 以降で削除される予定なので、SDK 58 のサイクル中に移行を終わらせる計画でいる。

  • React Native API の削除InteractionManagerrequestIdleCallback に移行)、Touchable のルートエクスポート、NativeMethods 型、Modalanimated prop、そして非推奨だった StatusBarbackgroundColortranslucentnetworkActivityIndicatorVisible がすべて削除された。ImageBackground は非推奨となり、View に絶対配置の Image を置く形に変わった。全リストは 0.870.88.0-rc.0 の release notes を参照。

  • iOS の scene ライフサイクル:iOS 27 SDK が UIScene ライフサイクルを要求するため、npx expo prebuildSceneDelegate.swiftInfo.plistUIApplicationSceneManifest エントリを生成するようになり、UIWindowdidFinishLaunchingWithOptions ではなく scene delegate が生成する(#46733#46734)。Expo は URL、user activity、Handoff、ライフサイクル、クイックアクションの各イベントを ExpoAppDelegate のオーバーライドと購読者に転送するので、これらに依存する config plugin やモジュールはこれまでどおり動作する(#49925#50032)。ios ディレクトリを手動で管理している場合、bare React Native アプリを使っている場合、あるいは app delegate のメソッドを直接オーバーライドしている場合は、移行ガイドを参照。

  • NODE_ENV と env ファイル:Expo CLI の各コマンドは .env ファイルと app config を読み込む前に NODE_ENVdevelopment または production に設定するようになった。これで動的な app.config.js.env のカスケードがモード間で常に一致する(#48554#48741#48839)。以前はどのコマンドも継承した NODE_ENV をそのまま使い、expo config は設定すらされなかったため、NODE_ENV=test npx expo start.env.test を読み込んでいた。今後は継承した値は無視され、このコマンドは .env.development を読み込む。テスト内では引き続き Jest が NODE_ENV=test を設定し、@expo/env はそこでも .env.test.local.env.test.env を解決する。詳しくは環境変数ガイドを参照。

  • Android アプリテンプレート:release ビルドは gradle.propertiesandroid.enableMinifyInReleaseBuilds=true を通じてデフォルトで R8 を有効にする(#50108)。R8 は Java/Kotlin コードを縮小・最適化・難読化し、パッケージサイズを減らして起動時間を改善する。アプリは proguard-android-optimize.txt プリセットで最適化される。リフレクションに依存するライブラリには ProGuard keep ルールが必要になることがある。無効にするには expo-build-propertiesandroid.enableMinifyInReleaseBuildsfalse に設定する。

  • expo-routerナビゲーションコアの変更によりナビゲーション状態と route key が決定的になり、ナビゲーションの dispatch は commit 後まで遅延され、fork された react-navigation API のかなりの部分が削除された。@expo/uiexpo-symbols はオプションの peer 依存になった。移行ガイドが項目ごとに扱っており、全リストは expo-router changelog にある。

  • expo-file-systemFile.write() が非同期になり promise を返すようになった。元の挙動が必要な場合は File.writeSync() を使う(#45992)。

  • expo-sqlite:libSQL サポートを削除——syncLibSQL()libSQLOptions もなくなった(#48543)。

  • expo-notifications:フォアグラウンド通知は、setNotificationHandler が別途指示しない限りデフォルトで表示されるようになり、handler が遅くても通知が失われなくなった(#49072)。このリリースにおける expo-notifications のその他の変更はその他の注目すべき変更を参照。

  • @expo/fingerprint:デフォルトプリセットが balanced になった(#47668)。

  • @expo/ui:iOS では <Host> が中央揃えではなく上揃えになり、flex: 1 の host が Android と一致するようになった(#47561)。HStackVStackGlassEffectContainer は未設定の spacingnil として SwiftUI に転送し、システムデフォルトの間隔を使うようになった。spacing={0} を渡せば元のレイアウトを維持できる(#48441)。Android では RNHostViewstyle prop が削除され、modifiers に置き換わった(#48970)。

  • expo-localization:iOS でデバイス言語に基づいて supportsRTL が RTL を強制しなくなった。レイアウト方向は I18nManager に従う(#48086)。

  • expo-media-library:iOS の Asset.getUri()AssetInfo.uri が Photos 内の動画の現在のバージョンを解決するようになった。従来の動作にするには version: AssetUriVersion.ORIGINAL を渡す(#48640)。

  • @expo/cliexpo login はデフォルトでブラウザログインを使うようになった。従来の動作にするには --no-browser--username/--password を使う(#46832)。

ツールのバージョン要件

  • Node.js:Expo ツールチェーンは Node.js 22 系なら 22.13 以上、24 系なら 24.3 以上、または Node.js 26 以上を要求するようになった。23 や 25 のような奇数バージョンはサポートされない(#47202)。

  • Android Gradle Plugin:Expo modules ツールチェーンが AGP 9 に対応した(#46766#46769)。

既知のリグレッション

  • 現時点で報告はない。beta 期間中に新たな報告があればこのセクションを更新する。

この beta 版を試すには

SDK 58 beta で新規プロジェクトを作成

# npm
npx create-expo-app@latest --template default@next
# bun
bun create expo-app --template default@next
# pnpm
pnpm create expo-app --template default@next
# yarn
yarn create expo-app --template default@next

注意create-expo-app は使用中のパッケージマネージャーで依存関係をインストールする。例えば npx なら npm、yarn create なら yarn。

既存プロジェクトのアップグレード

Claude Code と組み合わせて、私たちの expo-upgrade skill でアプリを beta にアップグレードできる。問題があればぜひフィードバックしてほしい。今後数週間でさらに改善していく。

以下は手動でのアップグレード手順。

  • すべての依存関係を SDK 58 に合わせてアップグレード
npx expo install expo@next --fix

テストしてほしいこと

問題の報告方法

  • 適切な issue テンプレートを使うissue を作成するときは対応するテンプレートを選び、最小再現例を添える。

  • 可能なら根本原因を特定する:これは常に非常に役立ち、修正が早くなる。

  • SDK 58 beta を使っていると明記する:それに応じて優先度を調整する。

beta をテストしてくれてありがとう、本当に感謝している!

出典: Expo Changelog← ホームへ戻る