「個人開発のSaaSって、結局どの技術で作るのが正解なの?」
「Next.jsとSupabaseとStripeの組み合わせが本当にいいのか知りたい!」
個人開発のSaaSでは、技術選定に迷っている時間がそのまま公開の遅れになります。
そして日本語の情報は「このスタックが最強です」という結論だけが並び、なぜそれで足りるのかまで書かれていないことが多いんですよね。
先に結論をお伝えすると、1人で有料のSaaSを出すならNext.js・Supabase・Stripeの3点で必要な機能はほぼ埋まります。
この記事では、3つの役割分担と、選び直すときに何が痛むのかまで含めて整理しました。
この記事でわかること
- 個人開発のSaaSで技術選定に使う判断軸
- Next.js・Supabase・Stripeそれぞれの担当範囲と選ぶ基準
- 構成を動かして課金までつなぐ手順
- 選び直すときに発生する乗り換えコストの重さ
この構成でいちばん読みにくいのが、規模が伸びたあとの固定費です。請求がどこから増えるかはSupabaseの料金は無料枠でどこまで?超過課金の落とし穴にまとめてあります。
個人開発のSaaSで技術選定が成否を分ける理由
技術選定は、コードを1行も書かないうちに勝負の半分が決まる工程です。
ここでは、選定でつまずく典型と、個人開発だからこそ効いてくる判断軸を見ていきましょう。
技術選定でつまずかないための考え方
- 選定に時間をかけすぎて作らないまま終わる罠
- 個人開発の技術選定で見るべき判断軸
- AIに書かせる前提だと選び方が変わるという事実
選定に時間をかけすぎて作らないまま終わる罠
個人開発でいちばん多い失敗は、技術を間違えることではありません。
何で作るかを決めきれないまま、作らずに終わることです。
比較記事を読み込み、フレームワークを2つ試し、DBをどれにするか悩む。この工程だけで数週間が溶けます。

ここで意識してほしいのが、個人開発では技術の優劣より、自分が最後まで走り切れるかのほうが結果に効くという点です。
実際、公開までたどり着いた人と途中で止まった人の差は、選んだ技術ではなく決断の速さにありました。
選定で時間を溶かす典型的な行動
- ベンチマークの数値を比べて優劣を決めようとする
- 「将来1万ユーザーになったら」を前提にスケール性能で選ぶ
- 新しく出たばかりのフレームワークを試したくなる
- 自分が書ける言語より、流行っている言語を選ぼうとする
どれも技術的には正しい問いですが、まだ1人のユーザーもいない段階で答えを出す必要はありません。
個人開発の技術選定で見るべき判断軸
では何を基準にすればいいのか。私が使っているのは次の5つです。
| 判断軸 | 見るポイント |
|---|---|
| 自分の習熟度 | 今日から書けるか。学習に1か月かかる技術は選ばない |
| 運用の手離れ | サーバー管理・バックアップ・監視を任せられるか |
| 初期コスト | 売上ゼロの期間を無料枠で走れるか |
| 情報量 | 日本語・英語のドキュメントと実装例が十分にあるか |
| 乗り換えコスト | やめたくなったときに、どれだけ引き剥がしやすいか |
この5つのうち、多くの記事が触れていないのが最後の乗り換えコストです。
選定の話は「入るとき」ばかり語られますが、実際に痛いのは「出るとき」でした。ここは記事の後半で詳しく扱います。
AIに書かせる前提だと選び方が変わる
2026年の個人開発では、コードの大半をAIに書かせる前提で選ぶ意味が出てきました。
理由はシンプルで、学習データに多く含まれている技術ほど、AIの生成精度が上がるからです。
ニッチなフレームワークを選ぶと、生成されたコードが動かず、結局自分でドキュメントを読むことになります。
AI前提で選ぶときの見方
- GitHubのスター数より、実装例の総量が多い技術を選ぶ
- 公式ドキュメントが構造化されていて、AIが参照しやすい形になっている
- 破壊的変更の頻度が低く、生成されるコードが古びにくい
この観点でも、Next.js・Supabase・Stripeの組み合わせは有利な位置にあります。
3つとも実装例が大量に流通していて、AIに「この構成で認証を作って」と頼めば、かなり近いものが出てくるからです。
逆に注意したいのが、破壊的変更が多い技術は、AIが古い書き方を出してくるという点でした。
生成されたコードが動かないとき、原因が自分のミスなのか世代のズレなのか切り分けられず、時間だけが溶けていきます。
だからこそ、AIに任せる範囲が大きいほど「枯れているかどうか」の比重が上がります。新しさより、情報の厚みで選ぶ。この基準が2026年の個人開発ではかなり効きますよ。
個人開発のSaaSにおけるNext.jsの役割と選ぶ基準
まずはフロント側を担当するNext.jsから見ていきます。
ここでは、1人開発と相性がいい理由と、逆にNext.js以外を選ぶべき場面まで押さえておきましょう。
Next.jsをどう位置づけるか
- 1人開発と相性がいい理由
- App Routerとレンダリング方式の使い分け
- Server ActionsとAPI Routeのどちらを使うか
- Next.js以外を選んだほうがいい場面
Next.jsが1人開発と相性がいい理由
Next.jsは、Reactをベースにしたフルスタックのフレームワークです。
1人開発にとって決定的なのは、フロントとバックエンドを同じプロジェクトに置ける点でした。
APIサーバーを別に立てる必要がなく、リポジトリも1つ、デプロイも1回で済みます。
1人で回すときに効いてくる特徴
- 画面とサーバー処理を1つのプロジェクトで管理できる
- ページごとに描画方法を選べるため、SEOが必要な画面だけ静的にできる
- Vercelにそのまま載るので、デプロイの設定でつまずかない
- TypeScriptが標準で、型がそのままドキュメントの代わりになる
2つ目は、SaaSでは意外と重要です。
ランディングページや料金ページは検索から流入させたい一方、ログイン後のダッシュボードは検索不要。この使い分けが1つのプロジェクト内で完結します。
App Routerとレンダリング方式の使い分け
Next.jsには、ファイル配置でルーティングを決めるApp Routerという仕組みがあります。
ここで最初に理解しておきたいのが、サーバーで動くコンポーネントとブラウザで動くコンポーネントが混在するという点です。
この区別が曖昧なままだと、「なぜかDBのキーがブラウザから見えてしまう」といった事故につながります。
| 種類 | できること | 使う場面 |
|---|---|---|
| サーバーコンポーネント(既定) | DB直接参照・秘密鍵の利用 | 一覧表示・詳細ページ |
| クライアントコンポーネント | 状態管理・イベント処理 | フォーム・モーダル・タブ |
迷ったら、まずサーバーコンポーネントで書いてみてください。
ボタンのクリックや入力の管理が必要になった箇所だけ、ファイルの先頭に'use client'を付けてクライアント側に寄せる。この順番だと、秘密情報がブラウザに漏れる事故を構造的に防げます。
Server ActionsとAPI Routeのどちらを使うか
データを書き込むとき、Next.jsには2つの経路があります。
フォームから直接サーバー関数を呼ぶServer Actionsと、URLを持つエンドポイントを作るAPI Routeです。
個人開発では、この使い分けをシンプルなルールに落としておくと悩まずに済みました。
2つの経路の使い分け
- Server Actions:自分の画面から呼ぶ処理(フォーム送信・データ更新・削除)
- API Route:外部から叩かれる処理(StripeのWebhook・外部連携・cron)
境界は「呼び出し元が自分のアプリかどうか」です。
外部サービスがHTTPで叩いてくるものはURLが必要なのでAPI Route、それ以外はServer Actions。この一言で判断できるようになります。
Next.js以外を選んだほうがいい場面
ここまで推してきましたが、Next.jsが向かないケースもあります。
いちばん多いのは、Reactを書いた経験がまったくない場合です。
SaaSを作りながらReactとApp Routerを同時に覚えるのは、正直かなり重いですよね。
別の選択肢を検討したい場面
- PHPやRuby、Pythonの経験が長く、Reactが未経験(Laravel・Railsのほうが速い)
- 画面がほとんどなく、APIだけを提供する(Honoなど軽量なものが向く)
- リアルタイム性が中心で、常時接続を大量にさばく必要がある
1つ目は特に大事なところです。
慣れた言語で1か月で出せるものを、新しい技術で3か月かけて出す理由は、個人開発にはほとんどありません。
個人開発のSaaSでSupabaseに任せられる範囲
次は、サービスの土台になるSupabaseです。
ここを理解すると、自分で書かなくていいコードがかなり減ります。
Supabaseで押さえておく範囲
- Supabaseが1つで賄う役割
- SupabaseとFirebaseの違い
- Row Level Securityでデータを守る仕組み
- 無料枠が足りなくなる境界
Supabaseが1つで賄う役割
Supabaseは、PostgreSQLを中心にしたバックエンドのセットです。
個人開発でありがたいのは、本来なら別々に用意する機能が1つのプロジェクトにまとまっているところでした。
認証基盤を自前で作った経験がある方なら、この省力化の大きさは想像がつくと思います。
Supabaseが担当する4つの役割
- データベース:PostgreSQL(普通のSQLがそのまま書ける)
- 認証:メール・パスワード、マジックリンク、Google/GitHubログイン
- ストレージ:画像やファイルの保管と配信
- リアルタイム:テーブルの変更をブラウザへ即時通知
とくに認証は、自前で作ると数週間かかるうえにセキュリティ上のリスクを抱え込みます。
パスワードのハッシュ化、メール確認、パスワード再設定、セッション管理。ここを丸ごと任せられるだけで、公開までの日数がまるで変わりますよ。
SupabaseとFirebaseの違い
同じ立ち位置のサービスとしてFirebaseがよく比較されます。
最大の違いは、データの持ち方でした。SupabaseはリレーショナルなPostgreSQL、Firebaseはドキュメント型のNoSQLです。
SaaSは「ユーザー」「サブスクリプション」「利用ログ」のように関連するデータを扱うことが多いため、SQLで結合できる側に寄せるほうが後から楽になります。
| 観点 | Supabase | Firebase |
|---|---|---|
| データ構造 | リレーショナル(PostgreSQL) | ドキュメント型(NoSQL) |
| 集計・結合 | SQLでそのまま書ける | 設計時に非正規化が必要 |
| 乗り換えやすさ | 標準的なPostgreSQLへ移せる | 独自APIへの依存が強い |
| リアルタイム | 対応(後付けの印象) | 対応(元々の強み) |
チャットや共同編集のようにリアルタイムが中心の機能なら、Firebaseのほうが素直です。
一方で、課金や集計を持つ普通のSaaSなら、SQLが書けるSupabaseを選んでおくほうが後悔しにくいと感じています。
無料枠の止まり方や乗り換えコストまで含めた比較はSupabaseとFirebaseの違いとは?個人開発での選び方で扱っています。
Row Level Securityでデータを守る仕組み
Supabaseで必ず理解しておきたいのが、Row Level Security(行レベルセキュリティ)です。
この仕組みは、テーブルの行ごとに「誰が読めるか・書けるか」をデータベース側で判定します。
ブラウザから直接データベースを叩ける設計になっているため、この防御がないと他人のデータが丸見えになります。
-- 自分の行だけ読める・書けるようにする例
alter table projects enable row level security;
create policy "自分のプロジェクトだけ参照できる"
on projects for select
using (auth.uid() = user_id);
create policy "自分のプロジェクトだけ更新できる"
on projects for update
using (auth.uid() = user_id);
ここでいちばん多い事故が、テーブルを作ったのにRow Level Securityを有効にし忘れることでした。
テーブルを追加したら必ずポリシーもセットで書く。この習慣を最初に作っておくと、後から全テーブルを点検する羽目にならずに済みます。
Supabaseの無料枠が足りなくなる境界
Supabaseの無料枠は、検証段階なら十分な内容です。
ただし個人開発で効いてくる制約が1つあり、無料プロジェクトは1週間アクセスがないと一時停止されるという仕様があります。
作りかけで放置すると止まるため、公開するなら有料プランへの移行が前提になります。
| 項目 | Free(無料) | Pro(月25ドル) |
|---|---|---|
| データベース容量 | 500MB | 8GB(超過分は従量) |
| ストレージ | 1GB | 100GB |
| 月間アクティブユーザー | 5万 | 10万 |
| 一時停止 | 1週間の非アクティブで停止 | なし |

(出典:Supabase「Pricing」/2026年8月11日時点)
容量やユーザー数は個人開発ならまず届きません。
つまり月25ドルは「性能を買う費用」ではなく、止まらない状態を買う費用と考えるほうが実態に近いです。使い方の詳細はSupabaseの使い方にまとめました。
個人開発のSaaSにStripeで課金を組み込む流れ
SaaSを名乗るには課金が必要です。ここが動いて初めて、趣味の開発から事業に変わります。
Stripeで押さえるべき要素と、個人開発でいちばん壊れやすい部分を順に見ていきましょう。
Stripeで課金を組むときの要点
- Stripe側で用意する3つの要素
- Webhookでサブスクリプションの状態を受け取る
- 契約状態をどこに持つかという設計判断
- 日本で使うときの手数料と実務
Stripe側で用意する3つの要素
Stripeの管理画面でまず作るのは、商品と価格と決済画面の3つです。
ここを先に固めておくと、コード側で書く量が驚くほど減ります。
個人開発では、決済フォームを自作せずStripeがホストする決済ページ(Checkout)へ飛ばすのが基本でした。
最初に用意する3つの要素
- Product(商品):「Proプラン」のようなサービスの単位
- Price(価格):月額1,000円・年額10,000円など、課金の条件
- Checkout Session:ユーザーごとに発行する決済画面へのリンク
カード番号を自分のサーバーで一切受け取らないため、セキュリティ要件のほとんどをStripe側に寄せられます。
解約や支払い方法の変更も、Stripeが用意しているカスタマーポータルへ飛ばすだけで済みます。自作するのは「ポータルへのリンクを発行する処理」だけで、管理画面を作り込む必要はありません。
Webhookでサブスクリプションの状態を受け取る
ここが個人開発でいちばん誤解されやすい部分です。
決済画面から自分のサイトに戻ってきたタイミングで課金完了とみなす実装をよく見かけますが、これは危ういやり方でした。
ユーザーが決済直後にブラウザを閉じたら、戻り先の処理は動かないからです。

正しい経路は、StripeからサーバーへHTTPで通知が届くWebhookです。
Stripeは決済や更新が起きるたびにイベントを送ってくるので、それを受けてデータベースを更新します。
Webhookで最低限受け取るイベント
checkout.session.completed:初回の申込みが完了したcustomer.subscription.updated:プラン変更・更新が起きたcustomer.subscription.deleted:解約が確定したinvoice.payment_failed:カードの決済に失敗した
そして署名の検証は絶対に省略しないでください。検証を飛ばすと、URLを知っている誰でも「課金済み」の通知を偽装できてしまいます。
Webhookを受けるエンドポイントはAPI Routeで作り、生のリクエストボディをそのまま検証に渡す点も忘れやすいところです。
契約状態をどこに持つかという設計判断
Webhookを受け取ったあと、契約状態をどこに保存するか。ここは意外と分かれ道になります。
結論としては、Stripeを正としつつ、判定に使う値だけSupabase側に写しておくのが個人開発では扱いやすい形でした。
毎回StripeのAPIを叩いて確認する実装は、画面表示が遅くなるうえに障害時に全ユーザーが止まります。
create table subscriptions (
user_id uuid primary key references auth.users(id),
stripe_customer_id text not null,
stripe_subscription_id text,
status text not null, -- active / trialing / past_due / canceled
price_id text,
current_period_end timestamptz,
updated_at timestamptz not null default now()
);
機能の出し分けは、このstatusとcurrent_period_endだけを見て判定します。
気をつけたいのがWebhookの取りこぼしです。デプロイ中や障害でイベントを受け損ねると、支払い済みなのに使えないユーザーが生まれます。
整合性を保つための備え
- Stripe管理画面から失敗したイベントを再送できるようにしておく
- 同じイベントが2回届いても結果が変わらない書き方にする
- 日次でStripe側の契約一覧と突き合わせる処理を用意する
- ユーザー自身が「契約状態を再読み込み」できるボタンを置く
最後のボタンは地味ですが、問い合わせ対応の時間をかなり減らしてくれます。
日本で使うときの手数料と実務
価格を決める前に、手数料の構造も把握しておきましょう。
日本国内のカード決済は1件あたり3.6%、サブスクリプション機能を使う場合は取引額の0.7%が上乗せされます。
月額1,000円のプランなら、手元に残るのはおよそ957円という計算です。
| 項目 | 料率 |
|---|---|
| カード決済(国内) | 3.6% |
| サブスクリプション機能 | 取引額の0.7% |
| 通貨換算が必要な場合 | +2% |
海外ユーザーを取りに行くなら、通貨換算の2%も見込んでおいてください。
導入の具体的な手順は個人開発でStripeを導入する方法で扱っています。
個人開発のSaaSで構成を動かすまでの手順
ここまでの3つを、実際に動く形へ組み上げていきます。
順番を守るだけで、手戻りがかなり減りますよ。
構成を動かすまでの流れ
- プロジェクトを作って認証まで通す
- テーブルと行レベルセキュリティを設計する
- ディレクトリ構成を決める
- 環境変数を整理する
- デプロイして本番のWebhookをつなぐ
- 公開前につまずきやすい点を潰しておく
【ステップ1】プロジェクトを作って認証まで通す
最初のゴールは「ログインしたら自分の名前が表示される画面」です。
ここまで通れば、あとは機能を足していくだけになります。
npx create-next-app@latest my-saas --typescript --tailwind --app
cd my-saas
npm install @supabase/supabase-js @supabase/ssr stripe
Supabase側はダッシュボードで新規プロジェクトを作り、URLとAPIキーを控えます。
ここで押さえておきたいのが、Supabaseのクライアントはサーバー用とブラウザ用の2種類を用意するという点でした。
クライアントを分けないと起きること
- サーバー側でログイン状態が読めず、常に未ログイン扱いになる
- ブラウザ側に管理者権限のキーが渡り、全データが露出する
- Cookieの読み書きが噛み合わず、リロードでログアウトする
公式ドキュメントにサーバー用・ブラウザ用の実装例が載っているので、そこから写して2ファイルに分けておきましょう。
【ステップ2】テーブルと行レベルセキュリティを設計する
認証が通ったら、データ設計に入ります。
SaaSで最初に作るテーブルは、だいたい次の3つに落ち着きました。
最初に用意する3つのテーブル
profiles:ユーザーの表示名やアイコンなど、認証情報の外側の属性subscriptions:契約状態(先ほどのStripe同期用)- サービス固有のテーブル:作りたい機能の中心になるデータ
Supabaseの認証ユーザーはauth.usersという専用テーブルで管理されるため、追加の属性はprofilesに分けて持ちます。
そしてテーブルを作った直後に、必ず行レベルセキュリティを有効化してポリシーを書いてください。あとでまとめてやろうとすると、確実に漏れます。
【ステップ3】ディレクトリ構成を決める
構成に正解はありませんが、迷う時間がもったいないので型を1つ持っておくと楽です。
私が使っているのは、役割ごとに分けたシンプルな形でした。
src/
├── app/
│ ├── (marketing)/ … LP・料金ページ(検索流入させる画面)
│ ├── (app)/dashboard/ … ログイン後の画面
│ ├── api/stripe/ … StripeのWebhook受け口
│ └── layout.tsx
├── components/ … 画面部品
├── lib/
│ ├── supabase/ … クライアント(server.ts / client.ts)
│ └── stripe/ … Stripe初期化・価格の定義
└── types/ … 型定義
括弧付きのフォルダ名はURLに影響しないグループ化の記法で、公開画面とログイン後の画面でレイアウトを分けられます。
この分け方にしておくと、認証が必要な画面をディレクトリ単位でまとめて守れるため、判定の書き忘れが起きにくくなります。
【ステップ4】環境変数を整理する
環境変数は、公開してよいものと絶対に隠すものが混ざる場所です。
Next.jsではNEXT_PUBLIC_で始まる変数だけがブラウザに配られるという規則があります。
逆に言えば、この接頭辞を付けた瞬間に中身は公開情報になるということですね。
# ブラウザに渡してよいもの
NEXT_PUBLIC_SUPABASE_URL=
NEXT_PUBLIC_SUPABASE_ANON_KEY=
# サーバーだけで使うもの(絶対に接頭辞を付けない)
SUPABASE_SERVICE_ROLE_KEY=
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
下の3つが漏れると、データベースの全操作と決済の操作が第三者に握られます。
環境変数まわりで気をつける点
.env.localを.gitignoreに入れる(テンプレートから外れていないか確認する)- サービスロールキーはサーバーコンポーネントとAPI Routeでのみ使う
- 本番とテストでStripeのキーを取り違えない(テスト用は
sk_test_で始まる) - 誤ってコミットしたら、消すだけでなく必ずキーを再発行する
最後の項目は特に重要です。履歴に残っている以上、削除コミットだけでは無効化になりません。
【ステップ5】デプロイして本番のWebhookをつなぐ
最後は公開です。VercelにGitHubリポジトリを接続すれば、プッシュのたびに自動でデプロイされます。
ここで見落としがちなのが、Vercelの無料プランは非商用の個人利用に限定されているという点です。
決済を処理する時点で商用扱いになるため、課金を始めるなら月20ドルのProプランが前提になります。
デプロイ後に必ずやること
- Vercelの管理画面に環境変数を登録する(ローカルの
.env.localは反映されない) - Stripe側に本番URLのWebhookエンドポイントを登録し、署名シークレットを差し替える
- Supabaseの認証設定に本番ドメインを追加する(リダイレクト先の許可)
- テストモードで一度、申込みから解約までを通しで試す
2つ目のWebhook登録は、ローカル開発と本番で署名シークレットが別物になります。
ここを差し替え忘れると、本番だけ課金が反映されないという分かりにくい不具合になるので気をつけてください。
公開前につまずきやすい点を潰しておく
ここまでの流れで動くようになったら、公開前にひととおり点検しておきましょう。
この構成でつまずく箇所は、驚くほど決まっています。自分だけのアカウントで動作確認していると、まず気づけない類のものばかりでした。
公開前に確認しておきたい注意点
- 別アカウントでログインし、他人のデータが見えないか実際に確かめる
- ログイン必須の画面にURL直打ちでアクセスし、リダイレクトされるか確認する
- 解約したユーザーが有料機能を使えなくなるかを、テストモードで通しで試す
- カード決済が失敗したときの画面と通知が用意されているか確認する
1つ目は、行レベルセキュリティのポリシーを書き忘れていないかの最終確認になります。
自分のアカウントだけで触っていると、そもそも他人のデータが存在しないので気づけません。テスト用のアカウントを2つ作り、片方のデータがもう片方から見えないことを目で確かめてください。
個人開発のSaaSで技術選定をやり直すときのコスト
最後に、どの記事もあまり書かない話をします。選んだ技術から離れるときのコストです。
ここを知っておくと、選定の判断が一段深くなります。
乗り換えという視点で見た3サービス
- 乗り換えコストで技術を選ぶという考え方
- Supabaseから離れるときに痛む部分
- Vercelから離れるときに痛む部分
- Stripeから離れるときに痛む部分
乗り換えコストで技術を選ぶという考え方
マネージドサービスは、便利さと引き換えにその会社の仕様へ依存します。
ここで見るべきなのは、依存の深さがサービスごとにまったく違うという点でした。
同じ「乗り換えづらさ」でも、数日で終わるものと、事業ごと作り直しになるものが混在しています。
| サービス | 乗り換えの重さ | 理由 |
|---|---|---|
| Vercel | 軽い | Next.jsは他の環境でも動く |
| Supabase | 中くらい | DBは標準的だが認証まわりが独自 |
| Stripe | 重い | カード情報を持たないため契約を引き継げない |
この表を先に知っていると、選定の力の入れどころが変わります。
軽いものは深く悩まず決め、重いものだけ時間をかけて選ぶ。それが個人開発の限られた時間の使い方として合理的です。
判断の目安として、私は「そのサービスが明日値上げしたら、自分は何日で逃げられるか」を考えるようにしています。
数日で逃げられるものは即決していい。逃げるのに数か月かかるものだけ、契約条件や運営会社の体力まで見る。この配分にすると、悩む対象がぐっと絞られます。
乗り換えやすさを保つための小さな工夫
- 各サービスの呼び出しを1つのファイルにまとめ、本体のコードから直接叩かない
- 独自機能を使うときは、代替手段があるかを一度だけ確認しておく
- データのエクスポート手段が用意されているかを契約前に見る
やりすぎると抽象化のコストのほうが高くつくので、1つ目だけでも十分です。
Supabaseから離れるときに痛む部分
データベース本体はPostgreSQLなので、ダンプを取って別のホスティングへ移すこと自体は難しくありません。
痛むのは認証まわりです。ユーザーIDの体系、セッションの持ち方、ソーシャルログインの連携がすべてSupabase固有の作りになっています。
パスワードのハッシュは移行できても、ログイン処理は書き直しになります。
Supabase移行で書き直しになる箇所
- ログイン・サインアップ・パスワード再設定の一連の処理
- 行レベルセキュリティのポリシー(
auth.uid()への依存) - ストレージから配信しているファイルのURL
- リアルタイム機能を使っている画面
とはいえ、これは数週間で終わる範囲の作業です。
データそのものは標準的な形で手元に残るため、致命傷にはなりません。
Vercelから離れるときに痛む部分
3つの中でいちばん軽いのがここです。
Next.jsは自前のサーバーでもコンテナ環境でも動くため、載せ替えの選択肢が広く残っています。
移行で手が止まるのは、Vercel固有の機能を使っていた部分だけでした。
Vercel固有で読み替えが必要な機能
- 画像の自動最適化(別の仕組みに置き換える)
- Cron Jobs(外部のスケジューラへ移す)
- エッジで動かしている処理(実行環境の差を吸収する)
逆に言えば、これらを避けておけば移行はほぼゼロコストになります。
とはいえ最初から縛る必要はありません。使える便利機能は使い、乗り換えの判断が必要になった時点で外す、で十分間に合います。
Stripeから離れるときに痛む部分
ここが本当に重い部分です。
Stripeはカード情報を自社で保管しているため、他の決済代行へ移す場合、既存の契約をそのまま引き継げません。
原則として、全ユーザーにカード情報を登録し直してもらうことになります。
決済代行を乗り換えるときに起きること
- 既存の課金ユーザー全員に再登録を依頼する必要がある
- 再登録しなかった人はそのまま解約になる(離脱率が跳ねる)
- 移行期間中は2つの決済基盤を並行して動かすことになる
- 売上データの集計が乗り換え前後で分断される
つまり決済だけは、最初の選定でほぼ確定させる前提で選ぶべき領域です。
逆にStripeは世界的に採用実績が厚く、対応通貨も決済手段も広いので、ここを選んでおけば乗り換えを検討する場面自体がまず来ません。判断の全体像は個人開発によるAI搭載SaaSの始め方と合わせて確認してみてください。
個人開発のSaaSの技術選定に関するよくある質問
Q:Next.jsとSupabaseは初心者でも扱えますか?
A:Reactの基本を書ける状態なら扱えます。逆にReactが未経験だと、SaaSの開発とReactの学習を同時に進めることになるためかなり重いです。その場合は自分が慣れている言語のフレームワークで作り、次のサービスでこの構成に挑戦するほうが早く公開までたどり着けます。
Q:SupabaseとFirebaseはどちらを選ぶべきですか?
A:課金や集計を持つ普通のSaaSならSupabaseです。SQLで結合できるため、あとから分析を足すときに困りません。チャットや共同編集のようにリアルタイム性が中心の機能なら、Firebaseのほうが素直に書けます。
Q:無料枠だけでSaaSを公開し続けられますか?
A:現実的には難しいです。Supabaseの無料プロジェクトは1週間アクセスがないと一時停止され、Vercelの無料プランは非商用の個人利用に限定されています。課金を始めた時点で、合計で月45ドル前後の固定費を見込んでおきましょう。
Q:技術選定にはどれくらい時間をかけるべきですか?
A:1日で十分です。決済だけは乗り換えが重いので慎重に選び、それ以外は「今日から書ける」を基準に決めてしまってください。選定に1週間かけて得られる精度より、1週間早く公開して得られるフィードバックのほうが価値があります。
まとめ
個人開発のSaaSは、Next.jsが画面とサーバー処理、Supabaseがデータと認証、Stripeが課金という役割分担で組み上がります。
この3つを覚えておけば、作るたびに構成を悩み直す必要はありません。
そして選定の判断軸に、乗り換えコストという視点を1つ足してみてください。
軽いものは即決し、重い決済だけ時間をかける。この配分にするだけで、迷っている時間が実装の時間に変わります。
次に手を動かすとき、あなたが最初に決めるのは「何で作るか」でしょうか。それとも「何を作るか」でしょうか。
個人開発を続けていくと、データの持ち方や分析の設計が伸びしろになる場面が出てきます。その領域を仕事として広げる道は、データサイエンティストに未経験からなるには?おすすめスクール7選にまとめてあります。

