コンテンツへスキップ
Supastack
JA
テーマ
ログインSupastack を入手
すべての記事

Next.jsとExpoでWeb+モバイルSaaSを構築する方法 (モノレポ実践ガイド)

クロスプラットフォームSaaSの設計手法:pnpmモノレポでNext.js 16とReact Native Expoを組み合わせ、Better AuthとDrizzle ORMを共有する方法を解説。

Noah Zixin Zhang約 3 分で読めます

Next.jsとExpoでコードを共有する最適なモノレポ構成は?

モジュール境界とバンドラー設定によります。最も安全な設計は、pnpmとTurborepoを用いてDBモデル、バリデーション、API契約をヘッドレスな内部パッケージに分離することです。Next.js 16サーバー側でDrizzle ORMを直接実行し、Expoモバイルアプリは型安全なHTTPエンドポイント経由で通信し、expo-secure-storeで認証トークンを保護します。supastackはこの構成をあらかじめ完備しており、MetroとTurbopackの競合を起こしません。

クロスプラットフォームSaaSの難所:バンドラーの不整合

プッシュ通知やホーム画面への配置により、モバイルアプリがユーザー維持率やエンゲージメントを飛躍的に向上させることは周知の事実です。しかし、Next.jsとReact Native Expoを単一モノレポで同居させるのは容易ではありません。

Next.jsはNode.jsやEdge環境を前提としたTurbopack/Webpackで動作し、ExpoはReact Native向けのMetroバンドラーで動作します。安易にコードを共有しようとすると、MetroがNode固有のcryptoを読み込んでクラッシュしたり、TurbopackがReact Nativeの構文で停止したりします。鍵となるのは明確なパッケージ分離です。

ヘッドレス共有パッケージの設計:認証・スキーマ・契約

実用的なモノレポにおいて、各アプリ(apps/webやapps/mobile)は薄いUIシェルであるべきです。ビジネスロジックやDB定義はpackages/以下の内部パッケージに配置します:

@supastack/db:Drizzle ORMのテーブル定義とマイグレーションを保持。サーバー環境のみがDB接続を行い、クライアントは型情報のみを参照します。

@supastack/auth:Better Authを設定。サーバー向けルートハンドラー用と、Web・モバイル双方が呼び出すヘッドレスSDKの2つのエントリポイントを提供します。

@supastack/config:Zodを用いてビルド時に環境変数を検証し、設定不備によるクラッシュを防止します。

// packages/auth/src/client.ts
import { createAuthClient } from "better-auth/react";
import { expoClient } from "@better-auth/expo/client";

export function createCrossPlatformAuthClient(baseURL: string, storage?: any) {
  return createAuthClient({
    baseURL,
    plugins: storage ? [expoClient({ scheme: "myapp", storage })] : [],
  });
}

統合認証の仕組み:WebのCookieとモバイルのSecureStore

Webとモバイルではセッションの保持手法が異なります。Webブラウザでは、Next.jsがHTTP-onlyのCookieを発行し、CSRF保護とServer Componentのシームレスなハイドレーションを実現します。

一方モバイル環境ではCookieが不安定なため、OAuth完了時にセキュアなBearerトークンを取得し、expo-secure-store経由でiOS KeychainやAndroid Keystoreに保存します。モバイルからのリクエストにはAuthorization: Bearer <token>を付与し、共通のBetter Authミドルウェアで検証します。

CI/CDとリリースパイプライン:Vercel、EAS Build、バージョン同期

Webとモバイルを1つのリポジトリで管理することで、リリースの足並みを揃えられます。@supastack/dbでスキーマ変更が行われると、Next.jsバックエンドはVercelやCloud Runへ即座にデプロイされます。

同時に、Expo Application Services(EAS Build)がApple TestFlightやGoogle Play向けのバイナリを自動生成します。共有パッケージのバージョンを固定することで、複数リポジトリ管理で頻発するバージョンの食い違いを防ぐことができます。

次のプロダクトは、ここから。

一度の支払いで、収益を生む製品を作り続ける。