本記事は React Native Advent Calendar 2025 2日目の記事です。
OpenAIやGeminiなどのLLMを活用した機能をモバイルアプリに組み込みたいシーンは増えています。
多くのLLMのAPIはバックエンドで呼び出す仕様になっていますが、React Nativeでモバイル先行で作ったアプリだとバックエンドはサーバーレスで薄めだったり、あるいはバックエンドがないアプリもあるでしょう。
そんなケースを想定して、本記事では、React NativeアプリにAI機能を統合するための方法を比較してみます。
実際に複数のアプローチを実装し、それぞれのメリット・デメリットを検証してみました。
想定するケース
- React Nativeでモバイル先行で作っている
- バックエンドは無い or サーバーレスで最小限
- バックエンドをゴリゴリ作りたくないが、TypeScriptで書きたい
- インフラの管理はあまり手をかけたくない
- 単純にLLMのAPIを呼ぶだけでなく、AIワークフローや将来的にはAIエージェントのようなこともやりたい
今回検証した構成パターン
以下の4つの候補を検証しました:
- Firebase Genkit + Cloud Functions
- Dify + Expo Server
- Mastra + Expo Server
- Firebase AI Logic
検証のポイント
各候補について、以下のポイントで検証しました:
🎯ワークフローやエージェントなど複雑なAI機能を実装できるか
単純なLLM API呼び出しだけでなく、将来的には複数のLLM呼び出しを組み合わせたワークフローや、自律的に動作するAIエージェント機能への拡張も見据えています。そのため、複雑なAIロジックを実装できるかどうかを検証ポイントとしました。
また、生成アプリではプロンプトの最適化が重要になるため、プロンプトのチューニングや評価の仕組みが提供されているかも確認しました。
🎯サーバー構築のシンプルさ
React Nativeはクライアントアプリのため、GiminiやOpenAIのAPIキーをアプリのコードの中に仕込むことはできません。このAPIキーはサーバー環境に保持する必要があります。そのサーバー環境を簡単に導入できるかを一つのポイントとしました。
🎯クライアント・サーバー間の認証
また、そのサーバー環境とクライアントの間には何らかの認証が必要になります。今回検証する中で、その方法は大きく2通りありました。1つが Firebase Auth などを用いて正規のユーザーであることを認証する、もう1つが Firebase App Check などを用いた正規のクライアントであること認証する仕組みです。
| 認証方式 | 認証対象 | 主な用途 | 実装例 |
|---|---|---|---|
| ユーザー認証 | 正規のユーザー(誰がアクセスしているか) | ユーザーごとのアクセス制御、個人情報の保護、利用状況の追跡 | Firebase Auth、OAuth、JWT |
| クライアント認証 | 正規のクライアントアプリ(何がアクセスしているか) | アプリの改ざん防止、APIキーの保護、ボット対策 | Firebase App Check |
この二種類の認証は相互に補完し合うもので、片方でも良いけど、できれば両方ある方がベターという関係になっています。
これらの認証の導入しやすさをポイントとしています。
🎯インフラ管理する手間が少ないか
サーバーのインフラ管理の手間もできるだけ減らしたいと考えました。
少人数チームでメインがReact Nativeのクライアントエンジニアの場合、インフラの手間にあまり工数を割けないことは、実際の現場でも多いのではないでしょうか。
🎯TypeScriptで実装できるか
React Nativeエンジニアであれば、基本的にTypeScriptで実装していることが多いでしょう。今回は、サーバー側のコードもTypeScriptで実装したいという要件があります。Pythonは使用しません。
検証結果
1. Firebase Genkit + Firebase Function
Firebase Genkitは、Firebaseが提供するAIワークフロー構築フレームワークです。Cloud Functions for Firebase(以下Cloud Functions)と組み合わせることで、サーバーレス環境でAI機能を実装できます。
実際には、Genkitは非常に薄いTypeScript製のAIフレームワークで、Firebaseだけでなく、あらゆるNode.js環境のサーバーに組み込むことができます。とは言え、やはりFirebaseとのコンビネーションが魅力なので、今回はCloud Functionsにデプロイしてみました。
アーキテクチャ図
実装例
GenkitのFlow機能でワークフローを定義し、onCallGenkitでCloud Functionsとして公開します。認証はauthPolicyで簡単に設定できます。
// サーバー側(Cloud Functions)
const weatherFlow = ai.defineFlow({ name: "weatherFlow", ... }, async (input) => {
// ワークフローの処理
// LLMを呼び出すなど
});
export const generateWeatherActivities = onCallGenkit(
{
// authPolicyで認証要件を設定
authPolicy: (auth) => auth !== null,
// API KEYはsecret managerで管理
secrets: [apiKey]
},
weatherFlow
);
クライアント側からは、Cloud FunctionsのhttpsCallableを使用して呼び出します。認証は自動的にFirebase AuthのIDトークンで行われます。
// クライアント側(React Native)の実装
import { httpsCallable } from 'firebase/functions';
const generateWeatherActivities = httpsCallable(functions, 'generateWeatherActivities');
const result = await generateWeatherActivities({ city });
Genkitではブラウザベースのデバッグツールが提供されています。ブラウザ上でプロンプトを入力し、中間出力を含めて結果をトレースできます。このツールにより、プロンプトチューニングを大幅に効率化できます。
所感
GenkitをCloud Functionsにデプロイしてみましたが、CLIでfirebase initを実行し、そこからデプロイまでつまずくことなく非常にスムーズにできました。
もしすでにバックエンドにFirebaseを使っていて、データベースにFirestoreを使っている場合などは、連動も楽なので選択肢としてかなり有力かと思いました。
Firebase Authによる認証が暗黙的に行われるので、もしすでにFirebase Authを導入しているなら、追加の認証実装が不要で非常にスムーズに統合できます。
Genkitのデバッグツールもプロンプトチューニングにおいて強力なツールだと思いました。
後述のMastraよりはAI周りの機能は劣りますが、ある程度のワークフローを作るのであれば十分かと思います。フレームワークとしてして薄いのですが、逆に普通のTypeScriptの文法知識で書けるので、学習コストはMastraよりも低いと感じます。
評価
✅ メリット
- Firebase認証が自動的に統合される(
authPolicyで簡単に設定可能) - インフラ管理が不要(Cloud Functionsが完全にマネージド)
- デプロイがスムーズ(
firebase initからデプロイまでつまずきにくい) - ブラウザベースのデバッグツールが強力(プロンプトチューニングに有効)
- GenkitのFlow機能でワークフローを宣言的に記述できる
- フレームワークが薄いため、TypeScriptで通常の処理を多く書ける(学習コストが低い)
- Firestoreとの連動も容易
- Cloud Secret ManagerでAPIキーを安全に管理できる
❌ デメリット
- Mastraと比較してAI周りの機能は劣る(エージェント機能はまだ発展途上)
- ある程度のワークフローには対応できるが、マルチエージェントなどはβだったりする
| 評価項目 | 評価 | 備考 |
|---|---|---|
| 認証 | ⭐⭐⭐⭐⭐ | Firebase Authと完全統合 |
| インフラ管理 | ⭐⭐⭐⭐⭐ | 完全マネージド |
| 実装のシンプルさ | ⭐⭐⭐⭐ | Genkitの概念理解が必要 |
| ワークフロー実装 | ⭐⭐⭐⭐ | Flow機能が強力 |
| TypeScript対応 | ⭐⭐⭐⭐⭐ | - |
2. Dify + Expo Server
Difyは、ノーコードでAIワークフローを構築できるプラットフォームです。
Difyで作成したワークフローはAPIとして公開でき、外部のシステムからAPI経由で呼び出すことができます。今回はそのAPI機能を利用して、React Nativeアプリと連携します。
Difyのデプロイには公式のDify Cloudまたはセルフホストが選択できますが、今回はインフラ管理を容易にするという点からDify Cloudを使用します。
DifyのAPIキーをセキュアに管理するために、バックエンドサーバーが必要になります。今回はExpo公式が提供するExpo ServerとEAS Hostingを利用しました。
またユーザー認証として Firebase Auth を利用しました
アーキテクチャ図
実装例
Expo ServerでDify APIへのプロキシサーバーを実装します。認証を検証した後、Dify APIにリクエストを転送します。
// サーバー側(Expo Server API Route)
export async function POST(request: Request) {
// AuthorizationヘッダーからBearerトークンを取得
const parts = request.headers.get('Authorization')?.split(' ');
const idToken = parts?.length === 2 && parts[0] === 'Bearer' ? parts[1] : null;
// Firebase Admin SDKにてユーザー認証
await adminApp.auth().verifyIdToken(idToken);
// Dify APIにリクエストを転送
const response = await fetch(`https://api.dify.ai/v1/workflows/run`, {
headers: { 'Authorization': `Bearer ${DIFY_API_KEY}` },
body: JSON.stringify({ inputs: { city } }),
});
return Response.json(await response.json());
}
クライアント側からは通常のfetchで呼び出します。
// クライアント側(React Native)の実装
const idToken = await auth.currentUser?.getIdToken();
const response = await fetch(`${EXPO_SERVER_URL}/api/weather-workflow`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${idToken}`,
},
body: JSON.stringify({ city }),
});
const result = await response.json();
所感
個人的にはDifyのようなGUIよりもコードで書いた方が早いのであまりメリットを感じませんが、チーム構成によっては誰でもAIワークフローが組めるDifyは魅力的なのかもしれません。
Difyとは関係ないですが、今回利用したExpo Serverは非常に開発体験が良かったです。チュートリアルに沿って設定からデプロイまで非常にスムーズにできました。
アプリのコードとサーバーのコードが同じソースコードで管理できるのは新時代な感じがあります。Next.jsに慣れていると理解がスムーズかもしれません。
APIキーをサーバーでセキュアに管理したいというプロキシサーバー的な用途では、まさにExpo Serverはぴったりでしょう
評価
✅ メリット
- ノーコードでワークフローを構築できる(非エンジニアでも可能)
- Dify Cloudを使えばインフラ管理が不要
- Expo ServerとEAS Hostingの開発体験が良い(設定からデプロイまでスムーズ)
- プロキシサーバーとしてAPIキーをセキュアに管理できる
❌ デメリット
- EAS Hosting + Dify Cloudと管理するバックエンドが増える
- GUIでのワークフロー構築は、コードで書くよりも時間がかかる場合がある
| 評価項目 | 評価 | 備考 |
|---|---|---|
| 認証 | ⭐⭐⭐⭐ | Firebase Auth等で実装が必要 |
| インフラ管理 | ⭐⭐⭐⭐ | Dify Cloudを利用すれば楽 |
| 実装のシンプルさ | ⭐⭐⭐⭐ | プロキシサーバーの実装はシンプル |
| ワークフロー実装 | ⭐⭐⭐⭐ | ノーコードで強力だが、コード管理が難しい |
| TypeScript対応 | ⭐⭐⭐ | APIレスポンスの型定義が必要 |
3. Mastra + Expo Server
Mastraは、Gatsbyのチームが開発しているTypeScript製のAIフレームワークです。AIエージェントやワークフローの構築に特化しており、エージェント機能(Tools、Scorers、メモリー)、ワークフロー、評価ツールなど、AIアプリケーション開発に必要な機能がフルスタックで搭載されています。
実行環境としては、Node.jsのサーバーであれば組み込むことができます。既存のNode.jsアプリケーション(Next.js、Expressなど)に統合することも、スタンドアロンのREST APIサービスとしてデプロイすることも可能です。
今回は、Expo Server(Expo RouterのAPI Routes)と組み合わせることで、React Nativeアプリから直接呼び出せるようにしました。
ユーザー認証は今回もFirebase Authを利用しました。
アーキテクチャ図
実装例
Expo ServerのAPI RouteでMastraワークフローを呼び出します。認証はFirebase Authです。
// サーバー側(Expo Server API Route)
export async function POST(request: Request) {
// AuthorizationヘッダーからBearerトークンを取得
const parts = request.headers.get('Authorization')?.split(' ');
const idToken = parts?.length === 2 && parts[0] === 'Bearer' ? parts[1] : null;
// Firebase Admin SDKにてユーザー認証
await adminApp.auth().verifyIdToken(idToken);
// Mastraワークフローを実行
const workflow = mastra.getWorkflow('weatherWorkflow');
const result = await workflow.start({ inputData: { city } });
return Response.json(result);
}
ワークフローとエージェントは別ファイルで定義し、createWorkflowとcreateStepで組み立てます。エージェントにはToolsやScorersを設定できます。
クライアント側からはDifyのときと同様に、通常のfetchで呼び出します。
所感
ワークフローエージェント、メモリー評価ツールなど、AIアプリケーション開発の機能がフルスタックで搭載されている印象です。genkitよりも機能は豊富です。
ブラウザでプロンプトチューニングを試せるプレイグラウンドが非常に使いやすいです。
もしすでにNode.js環境のサーバーがあるのなら、そこにMastraを導入することも可能なので、その選択肢はかなり有力だと思います。
しかし一方で、これからMastra用のサーバーを用意するのなら、デプロイ先は少し悩みます。公式のMastra Cloudというものがありますが、現状はまだベータで、試してみたところ、デフォルトのサンプルコードでもデプロイに失敗したりして、なかなか苦労しました。認証についても、公式の用意するFirebase認証ライブラリは、Firestoreと連動する必要があるなど、少し癖が強い印象でした。
個人的には、今回試したExpo Serverと組み合わせるのがスムーズに感じました。
評価
✅ メリット
- エージェント機能が充実している(Tools、Scorersなど)
- ワークフローとエージェントを組み合わせて複雑なAIロジックを実装できる
- TypeScriptで完全に実装可能
❌ デメリット
- これからサーバーを用意するならデプロイ先に悩む
- Mastraの学習コストがある
| 評価項目 | 評価 | 備考 |
|---|---|---|
| 認証 | ⭐⭐⭐⭐ | Firebase Admin SDKで手動実装が必要 |
| インフラ管理 | ⭐⭐⭐ | Expo Serverなどの組み合わせが必要 |
| 実装のシンプルさ | ⭐⭐⭐ | Mastraの概念理解が必要 |
| ワークフロー実装 | ⭐⭐⭐⭐⭐ | エージェント機能が強力 |
| TypeScript対応 | ⭐⭐⭐⭐⭐ | - |
4. Firebase AI Logic
Firebase AI Logicは、Firebase SDKから直接LLMを呼び出せる機能です。
LLMはGeminiが利用でき、そのAPIキーはFirebase側で自動的に管理されます。
不正なアクセスを防止する仕組みとしては Firebase App Check を利用します。
アーキテクチャ図
実装例
クライアント側から直接Firebase AI Logicを呼び出します。サーバー側の実装は不要です。
import { getGenerativeModel } from 'firebase/ai';
const model = getGenerativeModel(ai, { model: 'gemini-2.5-flash' });
const result = await model.generateContent(prompt);
Firebase App Checkでクライアント認証を行います。
所感
今回の選択肢の中で全くサーバーを用意しないパターンです。単にLLM APIを呼び出したいときや、簡単なワークフローであれば十分対応できるでしょう。
セキュリティの面でFirebase App Checkの併用は必須です。その設定が少し手間かもしれません。
評価
✅ メリット
- サーバー側の実装が不要(クライアントから直接呼び出し)
- Firebase認証と統合されている
- インフラ管理が不要
- 実装が非常にシンプル
❌ デメリット
- ワークフロー機能がない(手動で実装する必要がある)
- エージェント機能がない
- 複雑なAIロジックには向いていない
- クライアント側で処理するため、ロジックが露出する
| 評価項目 | 評価 | 備考 |
|---|---|---|
| 認証 | ⭐⭐⭐⭐⭐ | App Checkのみ |
| インフラ管理 | ⭐⭐⭐⭐⭐ | 完全マネージド |
| 実装のシンプルさ | ⭐⭐⭐⭐⭐ | 最もシンプル |
| ワークフロー実装 | ⭐⭐ | 手動実装が必要 |
| TypeScript対応 | ⭐⭐⭐⭐ | 型定義が一部不完全 |
ケースごとのおすすめ構成
現状バックエンドサーバーの構成が、判断ポイントの一つになると思います。
既存のNode.js環境のサーバー(Expressなど)がある場合、そこにMastraを導入するのが良い選択肢だと思います。Mastraは機能が豊富で、将来のAI機能拡張にも対応できるでしょう。
Firebase環境のバックエンドを使っている場合は、Genkitの導入が非常にスムーズだと思います。AI機能としてはMastraより劣りますが、多くの場合で必要十分だと思います。学習コストもそれほど高くない印象です。
もしこれからサーバー環境を導入するのであれば、今回試したExpo ServerとEAS Hostingの組み合わせは、構築もスムーズで便利だと思います。特にプロキシやBFFの用途として、非常に便利なソリューションだと感じました。
完全なクライアントアプリで、サーバーやログイン機能を一切用意したくない場合は、Firebase AI Logicも選択肢の一つだと思います。
なお、今回はLLMのAPIを呼び出す方針で検証し、クライアント側で動作するローカルLLMは扱っていません。React Nativeで使えるローカルLLMのソリューションも出てきているため、こちらも今後注目していきたいと思います。
以上になります。


