コンテンツにスキップ
Webフロントエンドエンジニアのための React Native 実践入門
Esc
navigateopen⌘Jpreview
このページの内容

第2章 React Nativeとは何か

JSXがiOSとAndroidの本物のネイティブUIに変わるしくみと、FlutterやPWAとの立ち位置の違い、そしてReact Nativeを選ぶコストを整理します。

React Nativeのアーキテクチャ

React Nativeは、JavaScript(TypeScript)で書いたコードからiOS/Androidの本物のネイティブUIを動かすためのフレームワークです。

ここで重要なのは「本物のネイティブUI」という点です。WebViewの中でHTMLを描画しているわけではありません。たとえばコードの中で <Text>こんにちは</Text> と書くと、画面にはiOSならUILabel、AndroidならTextViewという、それぞれのOSが標準で提供しているテキスト描画用の部品が実際に配置されます。同じく <View> ならiOSのUIView、Androidのandroid.view.View(画面の四角い領域=コンテナ)に対応します。JSXで宣言したツリーがそのままネイティブのビュー階層へ写されていく、というイメージです。

この仕組みのおかげで、見た目もアニメーションのなめらかさも、操作した時の感触も、ネイティブで作ったアプリと変わりません。WebViewベースのフレームワークがしばしば指摘されてきた「ネイティブ感の欠如」とは、根本的に出発点が違います。

JSXからiOSとAndroidのネイティブUIが作られる流れ

JSXのツリーはWebViewへ描画されるのではなく、各OSのネイティブUIへ変換されます。

なお、React Nativeの内部アーキテクチャは2024〜2026年にかけて「New Architecture」と呼ばれる新しい仕組みに完全に置き換わりました(0.76でデフォルト有効化、0.82でレガシーが凍結)。本書はこのNew Architectureを前提に書いています。詳しい内部仕組みを知らなくても困らないようになっているので、いったんは「今から始める人は気にしなくてよい」と覚えておけば十分です。

Hermes ― React Native向けのJavaScriptエンジン

実行エンジンも知っておくと役立ちます。

React NativeはJavaScriptCoreの代わりに、Meta製のHermesという軽量エンジンを標準採用しています。Hermesはモバイルでのアプリ起動時間とメモリ使用量を最適化するために作られたもので、ビルド時にJavaScriptをバイトコードへ事前変換しておくことで起動を高速化する、といった特徴があります。

2026年に向けては、現行Hermesの後継として、JavaScriptを事前にネイティブコードへコンパイルするStatic Hermesの取り込みが進んでいます。エンジン側の進化が、そのままアプリのパフォーマンス改善につながる構造です。

他のクロスプラットフォーム手法との比較

React Nativeを正しく位置づけるために、よく比較される選択肢を見ておきます。

Flutter

Googleが開発するクロスプラットフォームフレームワーク。Dartという独自言語を使い、画面を自前で描画します。かつては2DグラフィックスエンジンのSkiaを使っていましたが、現在はiOSと、Android API 29以上ではImpellerがデフォルトのレンダリングエンジンです(Vulkan非対応環境やAPI 29未満ではSkiaベースのレンダラーにフォールバックします)。

ネイティブUIを呼び出すReact Nativeとは設計思想が逆で、Flutter自身が画面の見た目を全部描いてしまいます。これにより両プラットフォームでピクセル単位で同じUIを出しやすい一方、OS標準のUIから微妙に外れる、ネイティブの新しい意匠(iOSのLiquid Glassなど)への追従はFlutter側の対応待ちになる、といった特性があります。

React Nativeはこの逆で、ナビゲーションバーやタブバーのようにOSが提供する部品をそのまま使っている箇所は、OS側の意匠変更にそのまま乗れます。

ただし「何もしなくても付いてくる」わけではありません。iOS 26のLiquid Glassのときも、React Native本体やreact-native-screens、Expo Routerといった周辺ライブラリ側の対応を待つ期間がありましたし、新しいXcodeでビルドし直して出し直す手間もかかります。加えて、<View><Text>を自分でスタイリングして組んだ部分 ― アプリの中身の大半 ― は自動追従の対象外で、Liquid Glassを自前のUIに使いたければexpo-glass-effectGlassViewのような専用のAPIを明示的に使うことになります。

Flutterとの差は「追従できる/対応待ちになる」という白黒ではなく、待ちの短さと、追従してくれる範囲の広さの差だと捉えるのが実態に近いです。実際にReact NativeでLiquid Glassへ対応させたときの作業はReact NativeでLiquid Glassに対応するにまとめてあります。

PWA(Progressive Web App)

Webサイトをアプリのように振る舞わせる技術群。WebView上で動くため、ブラウザの能力を超えるネイティブ機能(高度なカメラ操作、Live Activity、Widget、ヘルスケア連携など)には基本的に手が届きません。

「Webの延長で済む範囲ならPWA、ネイティブの能力を引き出したいならReact Native」と整理しておくと選びやすくなります。

ネイティブ開発(Swift / Kotlin)

OSの機能を100%使えて、最高のパフォーマンスを出せます。ただしiOSとAndroidでコードベースが完全に分かれるため、人員と工数がそのまま2倍になります。

React Nativeは「OSの能力をほぼ取りこぼさず、コードベースを大幅に共通化する」ところを狙う選択肢です。

React Nativeで実現できないことはあるか

もう少し踏み込んだ問いに答えます。「React Nativeを採用した場合、ネイティブで作ったアプリと比べて、できないことはあるのか?」という疑問です。

結論から言えば、ネイティブの知識を組み合わせれば、React Nativeで実現できないことはないと考えています。

理由は、React Nativeが最初から「ネイティブ連携」を設計に組み込んでいるからです。

  • Native Modules: ネイティブ(Swift/Kotlin)で書いたAPIを、JavaScript側から呼び出せる仕組み
  • Expo Modules API: 上記をより安全・型安全に扱うための、Expoが提供する仕組み
  • Expo Config Plugins: ネイティブプロジェクトの設定ファイル(Info.plist、AndroidManifest.xmlなど)をJavaScript側から書き換える仕組み
  • expo-apple-targets: WidgetやLive ActivityなどのiOSサブプロジェクトをExpoプロジェクトに組み込むためのライブラリ
  • React Native Skia: 高度なグラフィックス描画を可能にするレンダリングエンジン

「JS側で書ける範囲だけがReact Nativeの守備範囲」というイメージは、もはや古い見方です。本書の第19章で具体的な引き出しを紹介します。この問いだけを掘り下げた記事も別に書いているので、気になる方はReact Nativeで実現できないことはあるのか?もあわせてどうぞ。

「JS+ネイティブ」のいいとこ取り

実際のプロダクション開発では、画面の大部分をJavaScriptで書き、ごく一部の特殊な要件(動画プレイヤー、ネイティブ広告SDK、Live Activityなど)だけをExpo Modulesで包む、というハイブリッド構成が一般的です。

JS側で書ける範囲はWebの感覚で素早く作り、必要なところだけネイティブに降りる。React Nativeはこのバランスを取りやすいフレームワークだと言えます。

代表的な事例として、DiscordはiOS/Androidで共通のReact Native基盤を持ちつつ、チャット機能のようにパフォーマンスや細かい制御が重要な部分はネイティブで実装する、というハイブリッド戦略を取っています。「ネイティブ実装はReact Nativeアプリの弱点ではなく、むしろスーパーパワーだ」と社内では位置づけているそうです(参考: DiscordのReact Native活用についての解説記事)。

こうした事例はDiscordだけではありません。React Native公式サイトのShowcaseには、MetaのFacebookやInstagram、MicrosoftのOffice・Outlook・Teams・Xbox Game Pass、AmazonのShopping・Alexa・Kindle、Shopifyのアプリ群などが並んでいます。「小規模なアプリ向けの技術」ではなく、数千万人規模のプロダクトが実際に載っている土台だということは、頭の片隅に置いておくとよいと思います。

なかでも「動くコードをまるごと読める実例」として飛び抜けているのがBlueskyです。X(旧Twitter)風のSNSがExpo + React Native(Web版はReact Native for Web)で作られていて、しかもbluesky-social/social-appとしてソースが公開されています。ストアに並ぶ実プロダクトのコードをそのまま追えるので、Expo ModulesやConfig Pluginsでのネイティブ連携(第19章)、独自スタイリング基盤のALF(第7章)、ライブラリのパッチ管理、Lingui + Crowdinでの多言語対応、StyleSheet.hairlineWidthやモーダルのpresentation指定といったネイティブ感の作り込みまで、参考にできる実装が数多くあります。どこがどう学べるかはBlueskyから学ぶReact Native / Expo開発にまとめました。

React Nativeを選ぶコスト

ここまで利点を並べてきたので、引き受けることになるコストのほうも先に開示しておきます。「できる」ことと「ラクにできる」ことは別の話です。

  • アップグレードへの追従が続く: Expo SDKは数か月に一度のペースでリリースされ、その間隔はさらに短くなる方向にあります。古いまま放置すると、EAS Buildのサポート期限やストアの要件に引っかかって新規提出そのものができなくなるので、定期的なアップグレードは選択肢ではなく前提になります(第21章)
  • ネイティブ層から完全には逃げられない: 日常的な実装はJavaScriptで完結しますが、ビルドエラー、署名や証明書、権限設定、iOSとAndroidで挙動が割れる部分は残ります。Expoはここを大幅に薄くしてくれますが、ゼロにはなりません(第5章、第18章)
  • 新しいOS機能はライブラリの対応を待つ: 先ほどのLiquid Glassのように、OSの新しい意匠や機能に手が届くまでには、React Native本体や周辺ライブラリ側の対応期間が挟まります。ネイティブ開発なら発表と同時に試せるものが、少し遅れて使えるようになる、という形です
  • 問題の切り分けが多層になる: 不具合が出たとき、原因が自分のJSコードなのか、React Nativeなのか、ライブラリなのか、ネイティブのビルド設定なのかを切り分ける必要があります。ブラウザとDevToolsで完結していたWebに比べると、見るべき層が増えます(第5章)
  • アプリのサイズと起動時間では不利: JavaScriptのランタイムとバンドルを同梱するぶん、ネイティブだけで書いたアプリよりバイナリは大きく、起動も遅くなりがちです

どれも「致命的だからやめておけ」という類のものではありませんし、Expoを使えばかなりの部分が軽くなります。ただ、ゼロだと思って始めると面食らうので、最初に知っておいたほうがよい種類のコストです。

実務でぶつかる細かいつらみを具体的に知りたい場合は、ここがつらいよReact Nativeと、その後の状況を追ったRe: ここがつらいよReact Nativeにまとめてあります。数年運用してみて、どれが解消されてどれが残ったかが分かる内容です。

サイズと起動の差は、縮んではいる

最後のひとつだけ補足しておきます。JavaScriptのランタイムとバンドルをアプリに積む以上、ネイティブだけで書いたアプリと比べればバイナリは大きくなり、起動にも時間がかかります。これは構造的なもので、ゼロにはなりません。正直に認めるべき差です。

ただ、この差が放置されているわけでもありません。Hermesがビルド時にJavaScriptをバイトコードへ事前変換して起動を早め、New Architectureが土台そのものを作り直し、さらに先ほど触れたStatic Hermesではネイティブコードへの事前コンパイルが進んでいます。エンジンと基盤の改善が続いているぶん、差は地道に縮んできました。多くのアプリでは、ユーザーが体感して気にする水準ではなくなってきている、というのが現時点の見立てです。

向かないケースは意外と少ない

コストを並べたので「では、どういうときに選ぶべきでないのか」も気になると思います。ただ実のところ、はっきり向かないと言い切れる場面はそれほど多くありません。よくある心配も、見た目ほど決定的ではないからです。

「出すのはiOSだけ」でも、選ぶ理由は残ります。 たしかにコードベースを共通化する利得は生まれません。それでも、Reactの知識がそのまま使えること、保存すればすぐ反映されるホットリロードの速さ、EASによるビルド・配布・OTA更新といった利点は、プラットフォームの数と関係なく効きます。SwiftとXcodeを一から覚える時間と比べれば、1プラットフォームでもReact Nativeのほうが速く形になることは珍しくありません。

OSの新機能も、待つ以外の手があります。 ライブラリの対応を待たずに、Expo Modulesで自分でネイティブAPIを呼んでしまえばよいからです(第19章)。手間は増えますが、詰むわけではありません。

そのうえで残る、はっきり分が悪いケースは2つくらいです。ひとつは、チームにJavaScript/TypeScriptの資産がまったくなく、ネイティブエンジニアだけで完結してしまう場合。React Nativeは層をひとつ増やすだけになります。もうひとつは、UnityやUnrealのようなゲームエンジンが土台として必要な規模のアプリです。

逆に言えば、2つのプラットフォームに同じ体験を届けたい、画面とデータのやりとりが中心、チームにJavaScript/TypeScriptの資産がある ― という条件が揃うほどReact Nativeの利得は大きくなります。本書が想定している読者は、たいていこの条件に当てはまるはずです。

本章のまとめ

  • React NativeはJavaScriptで書いたコードから本物のネイティブUIを動かすフレームワーク
  • 内部アーキテクチャはNew Architectureに置き換わっており、本書もそれを前提にしている
  • FlutterやPWAと比べると「ネイティブUIをそのまま使える」点が独自の立ち位置
  • ネイティブ連携の引き出しが豊富で、できないことはほぼない
  • 一方でアップグレードへの追従、ネイティブ層の知識、切り分けの多層さといったコストは残る。それを織り込んだうえでの選択になる

次章では、ReactとReact Nativeの間で何が共通していて、何が違うのかを具体的に整理します。

最終更新 2026年7月24日