iimon TECH BLOG

iimonエンジニアが得られた経験や知識を共有して世の中をイイモンにしていくためのブログです

React NativeのExpoって何?Expo Go・EAS・Dev Client・ビルドの違いを整理してみた

はじめに

こんにちは!株式会社iimonでエンジニアをしているあめくです!

最近React Nativeで開発をしており、色々調べているとやたらと「Expo」という言葉が登場します。

みんなExpo, Expoっていうけど何なの?と私は毎日頭を悩ませておりました。
2025年は大阪で開催された日本国際博覧会(大阪・関西万博)、2027年は横浜で開催される国際園芸博覧会(GREEN×EXPO 2027)。スマホのアプリ開発界隈ではExpo!

世間を賑わすこのExpoですが、同じ名前でも役割がまったく異なります。

この記事ではReact Nativeで登場するさまざまな「Expo」を整理しながら、Expoとは何か、どんな種類があるのか、実機ではどうやって動くのか、ビルド方法は!?をみていければと思います!

※ React Native Expoを用いたアプリ開発に関しては我らがiimonのいまいーこと今井くんが以前記事として書いてくれてるのでそちらを参考ください!😉
スマホ向けアプリを気軽に作れる 「React Native EXPO」

さまざまなExpoの主な意味合い

React Nativeで「Expoつかってます!」と言われた場合、実は次のどれかを指しています!
Expo(フレームワーク・SDK)、Expo Go(動作確認アプリ)、EAS(クラウドサービス)

全部Expoやん!!🤯と気が狂いそうになりますが、まずは1つずつみていきましょう。

※ ExpoはReact Native開発に必須というわけではなく、Expoを使わず素のReact Nativeだけでアプリを開発することもできます。ただしReact Native公式は、新規アプリの開発ではExpoのようなフレームワークの利用を推奨しています。
参考: Get Started with React Native

Expo(フレームワーク・SDK)

Expoは、React Nativeをベースにしたアプリ開発用のフレームワークです。
カメラや位置情報、プッシュ通知などのネイティブ機能を、JavaScriptから簡単に利用できるSDKが多数用意されています。
例えば、expo-cameraexpo-locationといったパッケージを使えば、複雑なネイティブ実装を行わなくても各種機能をアプリに組み込めます。
これらはnpx expo installで個別に追加することが可能です。

こうしたExpoのパッケージは、土台となるexpoパッケージの上で動いています。
逆に言えば、素のReact Nativeプロジェクトでもexpoを組み込めば、必要なパッケージだけをピンポイントで導入できます。

参考: Install Expo modules in an existing React Native project

中でもよく名前を聞くのが、ファイルベースのルーティングを担うExpo Routerです。
フォルダやファイル構成に応じて画面遷移が自動的に設定されるため、React NativeでありながらNext.jsに近い感覚でルーティングを実装できます。
多くのプロジェクトで採用されており、単体で話題に上る機会も多いパッケージです。

Expo Go(動作確認アプリ)

Expo Goは、開発中のアプリをスマートフォンで簡単に動作確認できるアプリです。
通常はアプリをビルドしてインストールする必要がありますが、Expo Goを使えばQRコードを読み取るだけで実機でアプリを確認できます。そのため開発効率が高い一方で、独自のネイティブコードを追加したアプリは利用できないという制限があります。

EAS(Expo Application Services)

EASは、Expoが提供するクラウドサービスです。
クラウド上でアプリをビルドできる「EAS Build」、アプリストアを経由せずにJavaScript部分を更新できる「EAS Update」、アプリストアへの申請を支援する「EAS Submit」などの機能が提供されています。ローカル環境でビルド環境を構築する必要がなく、効率的にアプリを開発・配布できます。

なお、リリースにEASは必須ではなく、ローカルビルドや他のCI/CDでも配布は可能です。ただしiOSビルドにはMacが必要になるため、手元にMacがない場合などはクラウドでビルドできるEASが便利です。

参考: Can I develop iOS apps on a Windows computer?

(補足) ネイティブコードとは

ここまでで「ネイティブコード」という言葉が出てきましたが、簡単に補足します。
スマホアプリは最終的にiOS(Swift/Objective-C)やAndroid(Kotlin/Java)で書かれたコードとして動きます。これをネイティブコードと呼びます。

React NativeやExpoは、このネイティブコードをJavaScriptから操作できるようにする仕組みです。expo-cameraのような公式SDKも、内部的にはネイティブコードを呼び出しています。

通常はExpoが用意したSDK(ネイティブコード)だけで開発できますが、Expoが対応していないライブラリを使いたい場合や独自のネイティブ機能を実装したいといった場合、自分でネイティブコードを追加・変更する必要があります。

これらが、「ネイティブ開発」と呼ばれるものです。そして冒頭で説明したとおり、こうした独自のネイティブコードはExpo Goには組み込めないため、Dev ClientやEAS Buildが必要になります。

アプリの実行環境とビルド方法

Expo関連では「どこで動かすか」という実行環境と「どうやってビルドするか」というビルド方法、この2つがよく混同されると思います。
実はこれらは別の概念で、ここがExpoで最も混乱しやすいポイントでもあります。

実行環境とは、あなたのアプリが実際に動く「器」のようなものです。
同じJavaScriptコードでも、Expo Goという器で動かすのか、自分専用にビルドした器で動かすのか、ストアに並ぶ完成品として動かすのかで、できること・できないことが変わります。

実行環境は次の3つがあります。

実行環境

Expo Go

先述したExpo Goアプリそのものです。
Expo Goには予め決まったネイティブモジュールが組み込まれているため、expo-cameraのようなExpo公式SDKはそのまま動作します。
ただし、独自に追加したネイティブコードやConfig Pluginの設定はExpo Goには反映されないため動作確認できません。

起動する場合は次のコマンドを使います。

$ npx expo start # QRコードが表示され、Expo Goアプリでスキャンするとアプリがロードされる

--dev-clientをつけないのがポイントです。
ネイティブコードを追加する本格的なアプリ開発では、後述するDev Clientに切り替えるのが一般的です。

Development Build(Dev Client)

expo-dev-clientを組み込んだ、自分のアプリ専用の開発用ビルドです。
「自分専用のExpo Go」のようなイメージで、Expo Goでは動かせなかった独自のネイティブモジュールやConfig Pluginの設定もそのまま動作します。

# ローカルでビルドする場合(iOS / Android)
$ npx expo run:ios
$ npx expo run:android

# クラウドでビルドする場合(iOS / Android) developmentClient: trueにする必要あり
$ npx eas build --profile development --platform ios
$ npx eas build --profile development --platform android

eas build--profileeas.jsonに定義したビルド設定を指します。ビルドの構成や配布方式はこの設定で変わり、ストアへの配信には別途eas submitが必要ですが、本記事では実行環境とビルドの整理に絞るため詳細は割愛します。

Production Build(スタンドアロンアプリ)

App StoreやGoogle Playに公開する、最終的なアプリそのものです。
Development Buildに含まれていたデバッグ機能やJSサーバーへの接続機能が取り除かれ、リリース向けに最適化されています。

$ npx eas build --profile production --platform ios
$ npx eas build --profile production --platform android

ビルド方法に関して

ここまでの実行環境の説明で、すでにビルドのコマンドがいくつか出てきました。
よく見ると、同じDev Clientという実行環境を作るのにexpo runeas buildという2つの方法が登場していることに気づくと思います。
ここがExpoのビルドで最も混乱しやすいポイントだと感じますし自分もよくわからなかったです。

Dev Client = expo run ではなく、Dev Clientという実行環境を作る手段の1つがexpo runです。

ビルド方法は、用途別に次の3パターンを押さえておけば十分だと思います!

方法 何をするのか
expo run Dev Clientをローカルで作成してそのまま起動(開発用)
eas build --profile development Dev Clientをクラウドでビルドし、他の端末やチームメンバーとも共有できる(開発用)
eas build --profile production ストア提出用のリリースビルドを作成

※ Expo Goはビルドが不要のため上記には含めていない

expo runは、ネイティブプロジェクト(ios/android ディレクトリ)を生成し、 それをローカルでビルドして実機やシミュレータに直接インストール・起動するコマンドです。 開発をすぐ始めるための簡易コマンドという位置づけです。

このネイティブプロジェクトの生成だけを行うのが npx expo prebuild です。
app.json や Config Plugin の設定は、この prebuild のタイミングでネイティブプロジェクトへ反映されます。

そのため、これらを変更した場合はネイティブプロジェクトを更新したうえで再ビルドが必要になります。
なお、expo runは内部でexpo prebuildを実行してからビルドを行うため、通常はprebuildを意識する必要はありません。

一方 eas build は、eas.json のプロファイルに従ってビルドを実行します。
基本はクラウド上でビルドされますが、--local をつけると手元のマシンで同じ手順を再現できます。

ちなみに eas build には無料枠はあるものの基本的には課金して利用するサービスなので、--localはその課金を避けつつ EAS と同様のビルドを回したい場合や、CI 環境で再現したい場合に便利です。

再ビルドに関して

ビルド方法が整理できたのでいつ再ビルドが必要なのかを考えてみます。

これを理解するには、Dev Clientが実機上でどう動いているのかを知るのがいいと思います。

Dev Clientは「ネイティブ」と「JavaScript」の二層でできている

Dev Clientが実機やシミュレータ上でどう動いているのかを順に追ってみたいと思います。

まず、実機やシミュレータには、ビルドして作ったDev Clientアプリがインストールされています。
このアプリは、ネイティブコードとJavaScriptという二層で成り立っています。

このうちネイティブコードの部分は、ビルドした時点でアプリ本体に組み込まれた状態です。
これはあとからMetroサーバー経由で受け取るものではありません。

一方JavaScriptの部分はアプリ本体には含まれていません。
Dev Clientは起動すると、PC側で動いているMetroサーバー(npx expo start --dev-clientで立ち上がるもの)に接続し、そこからJavaScriptを受け取って実行します。 つまり、PCのMetroサーバーが配るのはあくまでJavaScriptだけで、ネイティブコードは端末のDev Clientアプリにあらかじめ組み込まれています。

このネイティブコードとJavaScriptという二層構造が、Dev Clientの動き方となります。

この二層構造が分かると、いつ再ビルドが必要なのかもはっきりします。
JavaScriptだけを変更した場合は再ビルドは不要で、都度Metroが新しいコードを配り直してくれるので、Fast Refreshで即座に画面へ反映されます。
一方、ネイティブライブラリの追加やConfig Pluginの変更をした場合は再ビルドが必要です。

これらはアプリ本体に組み込まれているネイティブコード側に手を入れることになるため、すでに端末にあるDev Clientに後からJavaScriptを配っても反映されません。
「JavaScriptを触ったのか、ネイティブを触ったのか」再ビルドが要るか迷ったら、この二層のどちらに手を入れたかを思い出すと判断できます。

自分自身がハマったポイント

React Native初心者(私)が特によく遭遇するトラブルをまとめます。
いずれも「どの実行環境で動かしているのか」を意識するだけで解決しやすくなります。

Expo Goでネイティブライブラリが動かない

Expo Goには事前に組み込まれたネイティブモジュールしか動作しません。
そのため、Expo Goがサポートしていないライブラリを追加してもExpo Go上では動作しません。 この場合はDev Clientに切り替える必要があります。
「ライブラリのREADMEにはインストール方法が書いてあるのに動かない...」と感じたら、まず実行環境を確認してみましょう。

npx expo installしたのに認識されない

npx expo installはJavaScriptパッケージのインストールまでは行いますが、ネイティブコードの組み込みは行いません。
インストールしたパッケージがネイティブモジュールを含む場合、expo runやeas buildでネイティブコードを含めた再ビルドが必要です。
インストールしただけで動くのはExpo Goで動作するSDKのみ、と覚えておくと混乱しにくくなります。

expo runしたあとExpo Goで動かなくなったと思ってしまう

expo runでビルドしたアプリはDev Clientとして動作するため、起動時にexpo start --dev-clientで立ち上げたMetroサーバーへの接続が必要です。Expo Goアプリから開こうとしても動作しません。
「壊れた?」と焦る前に、Dev ClientアプリとExpo Goアプリを混同していないか確認してみましょう。

Dev ClientとExpo Goの違いが分からない

見た目が似ているため混同しやすいですが、実態はまったく異なります。
Expo GoはExpoが配布する共通アプリで、Dev Clientは自分のプロジェクト専用にビルドしたアプリです。
スマホに両方インストールされている場合、アイコンが似ていて間違えることもあるので注意が必要です。

まとめ

実際に手を動かして調べてみると、Expoは一つの製品ではなく開発を支援するさまざまなツールやサービスの総称でした。
そして本題のビルドまわりは、次の2つの構造を押さえるだけで、ぐっと見通しが良くなります。

1つ目は、「実行環境(Expo Go/Dev Client/Production)」と「ビルド方法(expo run/ eas build)」が別物だということです。 実行環境はアプリが動く「器」、ビルド方法はその器を作るための「手段」であり、混同しないことが重要だと感じました。

2つ目は、Dev Client が「ネイティブ層 + JavaScript層」の二層構造でできているということです。 JavaScript だけを変更したのか、ネイティブに手を入れたのかで再ビルドの要否が決まります。

最初は覚えることが多く感じるかもしれませんが、「ネイティブコードを追加したかどうか」を基準に考えるだけで、ツール選びで迷う場面はぐっと少なくなります。この記事が、Expoという言葉で私のように気が狂った方の助けになれば幸いです!

最後に

現在弊社ではエンジニアを募集しています!

この記事を読んで少しでも興味を持ってくださった方は、ぜひカジュアル面談でお話ししましょう!

iimon採用サイト / Wantedly / Green

最後まで読んでいただきありがとうございました!

参照