第5章 React Nativeの開発環境を整える
プロジェクト作成から実機やシミュレータでの起動、デバッグまでを、モバイル特有のつまずきどころに絞って進めます。
本章では、実際にExpoアプリを動かせる状態までを順を追って整えていきます。普段のWebフロントエンド開発と重なる部分が大半なので、引っかかりやすい「モバイル特有のところ」に絞って説明します。
必要なもの
最低限揃えるのは次の3つです。
- Node.jsの新しいLTSバージョン(対応バージョンはExpo SDKのリリースノートに明記されています。執筆時点では22 LTSが無難)
- Expo CLIに対応したパッケージマネージャ(npm/pnpm/yarn/bunのいずれか)
- 動作確認用の端末またはシミュレータ・エミュレータ
iOSのシミュレータを使うにはmacOSとXcodeが必要です。Androidのエミュレータを使うにはAndroid Studioが必要です。ただし、後述するExpo Goを使えば、シミュレータ・エミュレータの準備をスキップしていきなり実機で動かせます。さらに、EASでDevelopment Buildをクラウドビルドすれば、macOSがなくてもiPhone実機上でアプリ固有のネイティブ機能を含めて開発できます。
手元の環境によって最短経路が変わるので、先に整理しておきます。Android実機を持っているならExpo Goが最速で、OSがWindowsでもLinuxでもmacOSでも同じように進められます。MacがあるならiOSシミュレータも無料で使えます。一方、iPhone実機しかなくMacもない場合は、第4章で触れたとおりExpo Goの入手にApple Developer Program(年間99ドル)が必要になります。この場合だけは、無料で始められる経路がない点に注意してください。
Node.jsのバージョン
Expo SDKの新しいバージョンが要求するNode.jsのバージョンは、SDKごとにリリースノートで指定されています。本書執筆時点では22 LTSが扱いやすい選択です。古いバージョンが入っている場合は、nvmやfnm、nodenvなどのバージョン管理ツールで切り替えてください。
# nvmの場合
nvm install 22
nvm use 22
# fnmの場合
fnm install 22
fnm use 22
パッケージマネージャ
npm/pnpm/yarn/bunのどれを使っても構いません。Expo CLIはどれにも対応しています。普段使っているものを使うのが一番です。
本書のコマンド例では基本的にnpm(とnpx)を使いますが、pnpm dlx、yarn dlx、bunxに置き換えても動きます。
プロジェクトを作成する
新規プロジェクトを作るコマンドは1行です。
npx create-expo-app@latest my-first-app
my-first-appの部分はプロジェクト名(ディレクトリ名)です。実行するとテンプレートの選択を聞かれることがあります。デフォルト(Default)を選べば、TypeScriptとExpo Routerがセットアップされた初期プロジェクトが作られます。
完成直後のプロジェクトは、ホーム/エクスプローラの2タブを持つサンプル画面が含まれた状態になっています。これをひな形に、自分のコードを書き足していきます。
my-first-app/
├── app/ # Expo Routerのルートディレクトリ。ここに画面ファイルを置く
├── assets/ # アイコン、スプラッシュ、画像などの静的ファイル
├── components/ # 再利用可能なコンポーネント
├── app.json # Expoの設定ファイル
├── package.json
└── tsconfig.json
Webフロントエンドの感覚に近い構成なので、迷うことはあまりないと思います。
app/ディレクトリの中身がそのまま画面のルートになる仕組みは、Next.jsのApp Routerと同じ発想です。app/index.tsxがトップページに、app/about.tsxが/aboutに、というファイルベースのルーティングです。詳しくは第9章で扱います。
なお、app/やcomponents/をルート直下ではなくsrc/app/、src/components/のようにsrc/配下にまとめる構成にも対応しています。チームの好みに合わせて選んでください(参考: Expo公式のsrc directoryのページ)。
開発サーバーを起動する
プロジェクトディレクトリに移動して、開発サーバーを起動します。
cd my-first-app
npx expo start
ターミナルにQRコードと操作メニューが表示されます。開発中のアプリを動かす方法は、実機を使う2通りと、シミュレータ/エミュレータを使う2通りの、計4通りです。

1. 実機 + Expo Go(Android実機なら最速)
第4章で見たとおり、SDK 55以降はExpo Goの入手経路が端末ごとに変わりました。ここでは入手後に開発サーバーへ繋ぐ手順に絞ります。
Android実機の場合は、USB接続した状態でnpx expo startからaキーを押せば、Expo CLIがSDKに対応したExpo Goを取得してインストールしてくれます。以降はQRコードでも接続できます。ストアから入れていた頃とほぼ同じ手軽さです。
iPhone実機の場合は、第4章で触れたeas go(Apple Developer Programが必要)でExpo Goを受け取ってから接続します。
端末にExpo Goが入ったら、あとは共通です。
- 開発マシンとスマホを同じWi-Fiに接続する
- ターミナルに表示されたQRコードを読み取る(iOSはカメラアプリ、AndroidはExpo Goアプリ内のスキャナ)
- Expo Goが開発サーバーに接続し、アプリが端末上に表示される
ファイルを保存すると、ホットリロードで即座に反映されます。Webの開発体験そのままです。
なお、iPhoneしか手元になくApple Developer Programにも入っていない場合は、この経路はいったん諦めて、Macがあるなら次の「iOSシミュレータ」、Androidも持っているならそちらで進めるのが手っ取り早いです(費用の整理は第4章を参照)。
2. 実機 + Development Build
Expo Goに入っていないネイティブモジュールを使う場合は、アプリ専用のDevelopment Buildを実機へ入れます。expo-dev-clientを追加し、EASのクラウドビルドでiOS/Android用のDevelopment Buildを作成する方法です。インストール後はExpo Goと同じくnpx expo startに接続でき、JavaScriptの変更はFast Refreshで即座に反映されます。
この経路には2つの作り方があります。WindowsやLinuxではEASのクラウドビルドを使えば、iOS実機向けのDevelopment Buildを作れます。ローカルでXcodeを動かす必要はありません。一方、macOS + Xcodeがある場合はEASを使わずローカルでビルドすることもできます。
# 接続したiPhoneを選んで、ローカルでDevelopment Buildをビルド・インストール
npx expo run:ios --device
npx expo run:ios --deviceはネイティブプロジェクトを生成・更新し、Xcode経由で実機へインストールします。ネイティブ依存を追加・更新したときは、このローカルビルドをもう一度実行します。どちらの経路でもiOS実機へ入れるにはApple Developer Programへの登録と、端末UDIDの登録が必要です。iOSシミュレータの起動だけはmacOS + Xcodeが必要です。
Development Buildの作成手順とインストール方法は、第18章「EAS Buildでビルドして配布する」で実際に扱います。第4章で見たとおり、iPhone実機しか手元にない場合はここから入るのが結局は近道です。Android実機やMacがあるなら、まずはExpo Goで開発サーバーへの接続を試してから戻ってきても構いません。
3. iOSシミュレータ(macOSのみ)
Xcodeをインストールしておくと、ターミナルでiキーを押すとシミュレータが起動してアプリが立ち上がります。Xcodeは本体だけで15GB前後あり、初回起動時に追加コンポーネントのダウンロードとライセンス受諾(sudo xcodebuild -license accept)が必要なので、時間と空き容量に余裕を持って準備してください。インストール後はxcode-select --installでCommand Line Toolsも併せて入れておきます。
› Press i │ open iOS simulator
4. Androidエミュレータ
Android Studioをインストールし、AVD ManagerでエミュレータをセットアップしておけばOKです。aキーを押すとエミュレータでアプリが起動します。
› Press a │ open Android
エミュレータのセットアップが面倒に感じる場合は、Android端末を持っているならUSB接続+Expo Goのほうが早いです。USB接続で動かす場合は、Android端末側で「設定 → ビルド番号を7回タップ → 開発者向けオプション → USBデバッグを有効化」という事前設定が必要になります。
expo-doctorで健康診断
新規プロジェクトを作ったタイミング、依存ライブラリを更新したタイミング、SDKバージョンを上げたタイミングなど、節目ごとに走らせておきたいのがexpo-doctorです。
npx expo-doctor
このコマンドは、
- 依存ライブラリのバージョンがExpo SDKと整合しているか
app.json/app.config.tsの設定に問題がないか- 古い形式のAPIや設定が残っていないか
といった点をチェックしてくれます。
警告が出たらすぐ直しておくと、ビルドや配布の段階で詰まるリスクをかなり減らせます。「動いているから後回し」にしがちですが、SDKアップグレードの直後はとくに走らせる価値があります。
環境変数を扱う
Next.jsで.envにNEXT_PUBLIC_API_URLを書いてきた感覚は、Expoでもほぼそのまま通用します。プロジェクト直下に.envを置き、EXPO_PUBLIC_で始まる名前を並べるだけです。
# .env
EXPO_PUBLIC_API_URL=https://api.example.com
const apiUrl = process.env.EXPO_PUBLIC_API_URL;
npx expo startを実行すると、Expo CLIが.envを読み込み、コード中のprocess.env.EXPO_PUBLIC_API_URLをビルド時に値へ置き換えます。NEXT_PUBLIC_がEXPO_PUBLIC_になっただけ、と考えて構いません。.envと.env.localを使い分ける作法も同じで、マシン固有の値を書く.env.localは.gitignoreに入れておきます。
ただし、Webの感覚のままだと引っかかる点が3つあります。
接頭辞が付いた値だけが対象です。 EXPO_PUBLIC_が付いていない変数は、アプリ側のコードからは読めません。逆に言えば、接頭辞を付けた時点でその値はアプリのバンドルに焼き込まれ、解析すれば誰でも読み出せます。APIキーやシークレットを置く場所ではない、という線引きは第10章と第18章で詳しく扱います。
静的な置換なので、書き方に制約があります。 process.env.EXPO_PUBLIC_API_URLのように直接書けば置換されますが、次のような読み方では置換が効きません。
// ✕ どちらも置換されず undefined になる
const { EXPO_PUBLIC_API_URL } = process.env;
const url = process.env["EXPO_PUBLIC_API_URL"];
Webでは普通に動いていた書き方なので、値がundefinedになったらまずここを疑ってください。
変更を反映するにはリロードが要ります。 .envを書き換えたとき、CLIの再起動やキャッシュクリアまでは不要ですが、Fast Refreshでは反映されません。端末をシェイクしてメニューから「Reload」を選ぶなど、明示的なリロードが必要です。
ビルドプロファイルごとに値を切り替えたい場合や、ストア提出用の鍵のようにクライアントへ出したくない値を扱う話は、第18章でまとめて扱います。
トラブルシューティングの基本
セットアップで詰まった時の見るべきポイントを、よくある順に並べます。
Wi-Fi接続の問題
実機 + Expo Goで接続できない場合、9割は同じWi-Fiにいないか、開発マシン側のファイアウォールが通信を弾いているケースです。
社内Wi-FiやゲストWi-Fiでは、端末同士の通信を遮断している場合があります。その場合は、
- 個人のテザリングで開発マシンとスマホを同じネットワークに乗せる
npx expo start --tunnelでngrokベースのトンネル接続を経由する- AndroidならUSB接続して
adb reverse tcp:8081 tcp:8081で開発サーバーへ転送する
のいずれかで解決できることが多いです。
Expo SDKと依存パッケージのバージョン不整合
expo-cameraなどのモジュールを追加する際は、npm installではなく npx expo install を使ってください。npx expo install は、現在のExpo SDKに対応したバージョンを自動で選んでくれるので、SDKと依存ライブラリのバージョン不整合による「動くはずなのに動かない」を予防できます。
# Good: SDKに合ったバージョンを入れてくれる
npx expo install expo-camera
# Avoid: SDKと不整合なバージョンが入る場合がある
npm install expo-camera
キャッシュ問題
「コードを変えたのに反映されない」「謎のエラーが出る」場合は、Metro(React NativeのJSバンドラ。WebでいうWebpack/Viteに相当)のキャッシュをクリアして再起動してみてください。
npx expo start --clear
これで多くの「気持ち悪い」状態は解消されます。
デバッグの手段
「コードが動いているか/止まっているか」を確認する手段は、Webと使い分けが少し違います。基本の3つを押さえておけば困りません。
console.logを見る
console.logはそのまま使えます。出力先は、開発サーバーを起動しているターミナルか、後述のReact Native DevToolsのコンソールです。エラー時のスタックトレースもここに出ます。
React Native DevToolsで調べる
Chrome DevToolsベースのReact Native DevToolsが標準で開けます。開発サーバーを起動した状態でjキーを押すと、Chromeに似た見慣れたUIが立ち上がります。
- SourcesでJSコードにブレークポイントを置いて止める
- Consoleで式を評価する
- NetworkでfetchやWebSocketのリクエストを確認する
- PerformanceプロファイルでJSスレッドの重い処理を探す
ブラウザのDevToolsとほぼ同じ感覚で、エディタのソースに対してブレークポイントが効きます。Web開発の流儀がそのまま通用するので、debugger文や条件付きブレークポイントもふつうに使えます。
ネイティブログを覗く
JS側で完結しないトラブル(ビルドエラー、ネイティブクラッシュ、起動直後の挙動)はネイティブのログを見るのが早道です。
- iOSシミュレータ: ターミナルで
npx expo startした後、Xcodeを開いてWindow → Devices and Simulatorsからログを開く、またはxcrun simctl spawn booted log stream --predicate 'subsystem contains "..."' - Android:
adb logcat(adb logcat *:Eでエラーだけに絞り込み)
JS側のconsole.logはadb logcatにも流れるので、Androidの実機トラブル時に重宝します。
本章のまとめ
- Node.jsの新しいLTS(22 LTSなど)とパッケージマネージャがあれば下準備は完了
npx create-expo-appでプロジェクト作成、npx expo startで開発サーバー起動- 入門はAndroid実機 + Expo Goが最速。iPhone実機でExpo Goを使うには
eas goとApple Developer Programが要る - 独自ネイティブ機能が必要なら実機 + Development Build、シミュレータ/エミュレータは必要に応じて
expo-doctorを節目ごとに走らせる- 環境変数は
.envにEXPO_PUBLIC_付きで書く。直接参照でないと置換されず、反映にはリロードが要る - 依存追加は
npx expo install、詰まったら--clear - デバッグはReact Native DevTools(
j)とネイティブログ(adb logcat/Xcodeログ)の合わせ技
次章からはReact Nativeの基礎パートに入ります。まずは画面を組み立てるときに最初に出会うコアコンポーネントから見ていきます。