今日、React Native 0.82 をリリースできることを嬉しく思います。これは New Architecture(新アーキテクチャ)で完全に動作する最初の React Native であり、重要なマイルストーンです。今回のリリースは新時代の始まりだと考えています。今後のバージョンでは Legacy Architecture(旧アーキテクチャ)に残るコードを削除し、インストールサイズの削減とコードベースの簡素化を進めていきます。さらに、0.82 では実験的なオプトインとして新しい Hermes 版である Hermes V1 の提供を開始します。React を 19.1.1 に更新していくつかの React 機能を有効化し、DOM Node API のサポートも搭載しています。
ハイライト
- New Architecture のみ
- 実験的な Hermes V1
- React 19.1.1
- DOM Node APIs
New Architecture のみ
React Native 0.76 で New Architecture がデフォルトになったことを発表しました。それ以降、New Architecture はテストと改善を重ね、今回以降のバージョンではこれを唯一のアーキテクチャとすることに自信を持っています。つまり、Android で newArchEnabled=false を設定したり、iOS で RCT_NEW_ARCH_ENABLED=0 を指定して CocoaPods をインストールしても、それらは無視され、アプリは New Architecture で動作します。
マイグレーション方法
まだ New Architecture に移行していない場合は、まずプロジェクトを React Native 0.81 または Expo SDK 54 に移行することを推奨します。これらは Legacy Architecture を使える最後のバージョンであり、New Architecture への移行を支援する警告やパフォーマンス改善が含まれています。0.81 で New Architecture を有効にし、アプリケーションが正常に動作することを確認してください。その状態で React Native 0.82 に安全にアップデートできます。もし互換性のないサードパーティ依存が移行を妨げる場合は、ライブラリのメンテナに直接連絡することをお勧めします。React Native コアのバグが原因で移行できない場合は、Issue トラッカーを通じてご連絡ください。
Interop Layers とサードパーティライブラリの互換性
互換レイヤー(interop layers)は当面の間コードベースに残します。interop layers が必要とするクラスや関数はすぐに削除されることはありません。Interop Layers の削除に関しては今後さらに情報を共有します。旧アーキテクチャと両対応するサードパーティライブラリは、New Architecture のみが有効な 0.82 でも引き続き動作することを確認しています。
Legacy Architecture クラスの削除
後方互換性を確保し、破壊的変更を減らすため、本バージョンでは React Native コアから Legacy Architecture の API を削除しません。Legacy Architecture を削除することで全体のバンドルサイズを大幅に削減できるため、削除作業は次のバージョンから開始する予定です。詳細は RFC0929: Removal of the Legacy Architecture of React Native を参照してください。
実験的 Hermes V1
React Native 0.82 では Hermes V1 へのオプトインをサポートします。Hermes V1 は Hermes の次の進化形で、社内アプリで実験を行ってきました。コンパイラと VM の改善により Hermes の性能が向上しています。初期のテストやベンチマークでは、さまざまなシナリオで現行 Hermes を上回る性能を示しています。バンドル読み込み時間や TTI(Time To Interactive)の改善が見られますが、改善幅はアプリの構成に依存します。
実世界かつ複雑なアプリである Expensify アプリでは、以下の改善が確認されました:
| 指標 | Android(ローエンドデバイス) | iOS |
|---|
| Bundle Load Time | 3.2% faster | 9% faster |
| Total TTI | 7.6% faster | 2.5% faster |
| Content TTI | 7.2% faster | 7.5% faster |
- Total TTI: バンドル読み込みからアプリ内の最初の画面がレンダリングされ、インタラクティブになるまでの時間。
- Content TTI: コンポーネント自身の最初のレンダリングから、そのコンポーネントがインタラクティブになるまでの時間。
Hermes V1 にはまだ JS→ネイティブのコンパイル(以前「Static Hermes」と呼ばれていたもの)や、React Native EU 2023 で示された JIT コンパイルは含まれていません。引き続きこれらの機能をテスト中で、進捗に応じて情報を共有します。
Hermes V1 を有効にする方法
info: Hermes V1 は実験段階にあるため、試すには React Native をソースからビルドする必要があります。将来的に Hermes V1 がデフォルトとして搭載されれば、この制約は解除されます。
Hermes V1 を自分のプロジェクトで試すには、次の手順を行ってください。
-
package.json の該当セクションを修正して、Hermes V1 の実験版コンパイラパッケージを解決させます(実験段階のバージョニング慣例は現時点のものです):
"resolutions": {
"hermes-compiler": "250829098.0.1"
}
"overrides": {
"hermes-compiler": "250829098.0.1"
}
-
Android で Hermes V1 を有効化するには、android/gradle.properties に以下を追加します:
android/gradle.properties
hermesV1Enabled = true
-
React Native をソースからビルドするよう設定するために、android/settings.gradle を編集します(依存置換の例):
android/settings.gradle
includeBuild('../node_modules/react-native') {
dependencySubstitution {
substitute(module("com.facebook.react:react-android")).using(project(":packages:react-native:ReactAndroid"))
substitute(module("com.facebook.react:react-native")).using(project(":packages:react-native:ReactAndroid"))
substitute(project(":packages:react-native:ReactAndroid:hermes-engine")).using(module("com.facebook.hermes:hermes-android:250829098.0.1"))
}
}
-
iOS で Hermes V1 を有効化するには、RCT_HERMES_V1_ENABLED=1 環境変数を付けて pods をインストールします:
RCT_HERMES_V1_ENABLED=1
bundle exec pod install
注意: Hermes V1 は事前コンパイル済みの React Native ビルドとは互換性がないため、pods インストール時に RCT_USE_PREBUILT_RNCORE フラグを使用しないでください。
アプリが Hermes V1 を実行しているか確認するには、アプリ内または DevTools コンソールで次のコードを実行します。これにより Hermes のバージョンが返され、手順 1 で指定したバージョン(250829098.0.1)と一致するはずです:
HermesInternal.getRuntimeProperties()['OSS Release Version'];
React 19.1.1
この React Native リリースには最新の安定版 React である React 19.1.1 を同梱しています。React 19.1.1 は React Native における owner stacks を完全にサポートします。React Native 0.80 で 19.1.0 のサポートを出した際、@babel/plugin-transform-function-name Babel プラグインを使用していると owner stacks が完全にサポートされない旨をお伝えしましたが、本リリースではその制限を解除し、すべての React Native ユーザーに対して owner stacks を有効にします。
また、React 19.1.1 は Suspense 境界内での useDeferredValue と startTransition の信頼性を改善します。これらはアプリの応答性を高めるための重要な機能です。以前は React Native で Suspense と併用するとフォールバックコンポーネントが誤って表示される問題がありましたが、React 19.1.1 では Web と同様に期待通りの挙動をするようになっています。
DOM Node APIs
React Native 0.82 からは、ネイティブコンポーネントが refs 経由で DOM ライクなノードを提供します。以前はネイティブコンポーネントは measure や setNativeProps といった限定的なメソッドを持つ React Native 固有のオブジェクトを返していました。今回のリリース以降、UI ツリーを横断したりレイアウトを測定したりするための DOM API のサブセットを実装するノードが返されます。例えば:
function MyComponent(props) {
const ref = useRef()
useEffect(() => {
const element = ref.current
// New methods
element.parentNode
element.parentElement
element.childNodes
element.children
const bounds = element.getBoundingClientRect()
const doc = element.ownerDocument
const maybeElement = doc.getElementById('some-view')
// Legacy methods are still available
element.measure((x, y, width, height, pageX, pageY) => {
/* ... */
})
}, [])
return <View ref={ref} />
}
さらに、Text コンポーネントが作るリーフテキストノードや、React Native のルートノードを表す document ノードへのアクセスも公開されます。これは後方互換性のある変更であり、新しいノードは従来のメソッド(例: measure)も引き続き実装します。詳細はドキュメントを参照してください。
その他の変更
Web Performance APIs(Canary)
React Native は Web の一部の Performance API を実装しています(Canary リリースで利用可能):
- High Resolution Time:
performance.now() と performance.timeOrigin を定義
- Performance Timeline:
PerformanceObserver と performance オブジェクトのエントリ取得メソッド(getEntries(), getEntriesByType(), getEntriesByName())
- User Timing:
performance.mark と performance.measure
- Event Timing API:
PerformanceObserver に報告されるイベントエントリタイプ
- Long Tasks API:
PerformanceObserver に報告される longtask エントリタイプ
これらにより、実行時のパフォーマンスを(テレメトリ目的で)追跡でき、将来的に React Native DevTools の performance パネルで可視化されます。現在は canary レベルでのみ利用可能で、将来のバージョンで安定版としてリリースされます。
Android の最適化された debug ビルドタイプ
React Native 0.82 から、開発体験を高速化する debugOptimized ビルドタイプが利用可能になります。これまで Android はデフォルトで次の 2 つのビルドバリアントを作成していました:
debug: 開発時にデフォルトで使用され、React Native DevTools、Metro、Android の JVM/C++ デバッガに接続可能
release: 本番用で最適化・難読化が有効になりデバッグが難しい
多くの React Native 開発者は開発時に C++ デバッガを使う必要がないため、debugOptimized ビルドタイプを導入しました。debugOptimized ではいくつかの C++ 最適化が有効になっているため、アニメーションや再レンダリングが高速になります。一方で、JavaScript のデバッグは引き続き React Native DevTools で可能です。debugOptimized では C++ ネイティブデバッガは使えませんが、debug ビルドタイプを使えば引き続き利用できます。
アプリで debugOptimized バリアントを実行するには次を呼び出します:
npx react-native run-android --mode debugOptimized
または(Expo):
npx expo run:android --variant debugOptimized
info: debugOptimized は React Native 0.81 と Expo SDK 54 にもバックポートされています。サンプルでは複数のアニメーションを描画している画面で debug は約 ~20FPS、debugOptimized は約 ~60FPS で動作しています。
破壊的変更
Uncaught promise rejections は console.error を発生させるように
前バージョンで未捕捉の JavaScript エラーの報告を改善したのに続き、今回から未捕捉の Promise(reject)も同じ仕組みで報告されます。以前のバグによりこれらは完全に無視されていたため、React Native 0.81 以降にアップグレードすると既存のエラーが表面化することが予想されます。その結果、これまで報告されていなかったエラーがバックエンドに送られ、レポートが急増する可能性があります。
その他の破壊的変更
- 一般
ReactNativeFeatureFlags を src/private に移動しました。一般的に ReactNativeFeatureFlags に依存すべきではありません(これはプライベート API です)。
Appearance.setColorScheme() の型が更新され、nullable 値を受け取らなくなりました。カラースキームをリセットする必要がある特殊ケースでは null/undefined の代わりに 'unspecified' を使ってください。
- iOS
RCTDisplayLink をマイグレーションしました。
詳細や最新情報は公式ドキュメントと Issue トラッカーを参照してください。