毎月請求書が届くたびに目を疑う—847ドルのワークフローユニット、またしても。新しいタブを開いて「Bubble alternative」と検索する。昨年、まさにこれをした創業者が3人、私たちに連絡をくれた。彼らは皆、自分たちが行き止まりを作ったと思っていた。実際には、彼らが成し遂げたのは、Bubble の従量課金制度では対応できないほど強力な製品市場適合の検証だった。Next.js と Supabase への移行は、ワークフローに含まれるカスタムロジックの量に応じて、4週間から9週間かかった。1社は2ヶ月目までに月額640ドルを削減した。別の1社はページ読み込み時間を3.2秒から680ミリ秒に短縮し、サインアップコンバージョン率が11ポイント上昇するのを目撃した。Bubble アプリは機能していても単位経済学が成り立たなくなっている場合、移行がどのように分解されるのか—実際のコード、実際のタイムライン、そして4週間での出荷か4ヶ月での出荷かを決定する3つの決定—を正確に見ることになる。

Bubble は MVP を素早く立ち上げるのに本当に優れている。初期段階の創業者に何度も推奨してきた。しかし、パターンを見続けている:製品が成長する、チームが成長する、ユーザーベースが成長する—そして突然 Bubble が成長しなくなる。むしろ足を引っ張る。1,000ユーザーで「許容可能」だったワークフローユニット (WU) の料金体系が、50,000ユーザーでは重大な問題になる。解放的に感じたビジュアルエディタが、カスタムロジックが必要になると檻のように感じ始める。「許容できる」と思っていたページ読み込み時間が恥ずかしいものになる。

この記事は、初めてこれをやった時に欲しかった移行ガイドだ。チームが Bubble から卒業する理由、2026年の実際のコストがどのように見えるか、そして会社を炎上させることなく Next.js と Supabase への移行を実際に実行する方法について話していこう。

目次

Outgrown Bubble? How to Migrate to Next.js and Supabase in 2026

Bubble から卒業する理由

「卒業する」が実際に何を意味するのかについて具体的に話そう。それは1つではなく、通常は複数の痛点が互いに複合して生じる。

パフォーマンスの壁

Bubble アプリは共有インフラストラクチャで実行される。あなたのアプリは他の Bubble アプリと計算リソースを共有する。あなたのアプリがトラフィックスパイクを受けても、単にインスタンスをスピンアップすることはできない—Bubble の気まぐれに左右される。500人以上の同時実行ユーザーを持つ Bubble アプリが基本的なデータベースクエリで3~5秒のレスポンス時間に達するのを見た。これはバグではなく、アーキテクチャの問題だ。

Bubble ページも重い。典型的な Bubble ページはクライアントに2~4MB の JavaScript を送信する。それを、200~400KB の JavaScript を送信するかもしれない、しっかり構築された Next.js ページと比較すると、特にモバイルではその違いをユーザーが感じる。

プラグインの問題

Bubble のプラグインエコシステムは、その強力さとアキレス腱の両方だ。Stripe インテグレーション、PDF生成、メール送信用のプラグインをインストールするが、各プラグインはランダムなサードパーティの開発者によって保守されており、来週廃棄される可能性がある。プラグインの作成者が悪い更新をプッシュしたため、本番アプリが壊れるのを見たことがある。制御できない状況だ。

ベンダーロックインは現実だ

あなたのアプリケーション全体—ロジック、データ、UI—は Bubble の独自システム内に存在する。「アプリをエクスポート」するボタンはない。あなたのワークフローはコードではなく、Bubble の形式で保存されたビジュアル構成だ。Bubble が価格設定を変更する場合(実際に複数回変更した)、支払うか一から始めるかのどちらかだ。これはどのビジネスにとっても悪い交渉立場だ。

チーム拡張の問題

2026年に「Bubble 開発者」を雇おうとしてみてほしい。才能プールは React/Next.js 開発者と比較して非常に小さい。Bubble でのバージョン管理は Git と比較してプリミティブだ。複数の開発者が同じ Bubble アプリで同時に作業するのは、フラストレーションの練習だ。本当のコードレビュープロセスも、ブランチ戦略も、CI/CD パイプラインもない。

Bubble の 2026年の料金現実

Bubble は 2023年にワークフローユニット (WU) の料金体系に移行し、それ以来何度も調整している。2026年初現在、ここが見えている内容だ:

プラン 月額費用 ワークフローユニット サーバーサイド WU レート クライアントサイド WU レート
Free $0 限定(テスト用のみ) N/A N/A
Starter $32/月 10,000 WU 1 WU per action 0.2 WU per action
Growth $129/月 50,000 WU 1 WU per action 0.2 WU per action
Team $349/月 150,000 WU 1 WU per action 0.2 WU per action
Enterprise カスタム カスタム カスタム カスタム
オーバーージ Per WU $0.003/WU $0.003/WU

ここから状況が悪くなる。10,000人のアクティブユーザーを持つ中程度複雑な SaaS アプリは、月に500,000~1,000,000 WU を簡単に消費できる。これは Team プランに加えて1,050~2,550ドルのオーバーチャージだ。私は、クラウドインフラストラクチャの月額50~200ドルで実行できるアプリに対して Bubble で月額3,000~8,000ドルを支払う企業を見てきた。

WU モデルは特に厳しい。なぜなら、カスタムスタックではほぼ無料になるものに対して料金を取るからだ。データベースを検索する?WU がかかる。定期的なワークフローをスケジュールする?WU。通知を送信する?WU。すべての API 呼び出し、サーバー側のすべての条件チェック—すべて増加する。

そして本当に痛い部分はここだ:Bubble の価格は1方向にのみ動いてきた。WU モデルは古い容量ベースの価格設定に置き換わり、多くのユーザーは一夜にして請求額が2~5倍増加したのを目撃した。再度発生しない保証はない。

Next.js + Supabase が正解である理由

ここ数年間、数十の Bubble 終了戦略を評価してきた。Rails、Django、Laravel、Firebase を使ったプレーンな React—すべて有効だ。しかし、特に Bubble から来るチームにとって、Next.js + Supabase の組み合わせは、それが難しい甘い蜜へスポットだ。

Next.js は Bubble ができないことを提供する

Next.js 15(2026年の現在の安定版)は、サーバーサイドレンダリング、静的生成、API ルート、ミドルウェア、エッジ関数すべてを1つのフレームワークで提供する。ページはそのページが実際に必要とする JavaScript だけを送信しているため速く読み込まれる。App Router は、Bubble ワークフロー数十個を近似するのに必要なレイアウト、ローディング状態、エラー境界を提供する。

さらに重要なのは、React であることだ。React エコシステムは巨大だ。デートピッカーが必要?50個の戦闘テストされたオプションがある。グラフが必要?Recharts、Visx、Nivo—好みを選べ。認証が必要?NextAuth.js(現在 Auth.js)または Supabase Auth。プラグイン開発者がバグを修正するのを待つことはない。

このパスを検討している場合、私たちの Next.js 開発チーム は複数の Bubble アプリを移行し、プロセスがどのように見えるかについて詳細を共有できる。

Supabase は Bubble のバックエンドを置き換える

Supabase は「Bubble バックエンド置き換え」に最も近い存在だ。理由はここにある:

  • PostgreSQL データベース —Bubble の奇妙なデータ構造の代わりに、実際の、クエリ可能な、インデックス可能なリレーショナルデータベース
  • 行レベルセキュリティ (RLS) —誰がどのデータを読み書きできるかをデータベースレベルで定義
  • 組み込み認証 —メール/パスワード、マジックリンク、OAuth プロバイダー、すべてが処理される
  • リアルタイム購読 —ポーリングなしのライブデータ更新
  • ストレージ —CDN 配信によるファイルアップロード
  • エッジ関数 —カスタムロジック用のサーバーレス関数

2026年の Supabase の価格設定は、スケールで Bubble より劇的に安い:

Bubble (Growth) Supabase (Pro) + Vercel (Pro)
月額基本費用 $129 $25 + $20 = $45
10K ユーザー時点 $349+ (オーバーチャージの可能性) ~$75-150 (使用量に応じて)
50K ユーザー時点 $2,000-5,000+ ~$200-500
100K ユーザー時点 $5,000-12,000+ ~$400-1,200
データベースアクセス 独自クエリ 完全な PostgreSQL
カスタムコード 非常に限定的 無制限

これらの数字は理論的ではない。彼らは私が一緒に働いてきた企業から見た実際の請求に基づいている。

Outgrown Bubble? How to Migrate to Next.js and Supabase in 2026 - architecture

アーキテクチャ比較:Bubble と Next.js + Supabase

Bubble の概念を新しいスタックにマップしましょう。そうすれば、どこに何があるのかが見えてくる:

Bubble の概念 Next.js + Supabase の同等物
Pages Next.js pages/routes (App Router)
Reusable Elements React コンポーネント
Visual Elements JSX + Tailwind CSS / コンポーネントライブラリ
Workflows API ルート、Server Actions、エッジ関数
Database Things PostgreSQL テーブル
Data Types & Fields テーブル列と適切な型
Privacy Rules Supabase Row Level Security (RLS)
Backend Workflows Supabase Edge Functions またはクロンジョブ
API Connector ネイティブ fetch/axios 呼び出し
Plugins npm パッケージ
User auth Supabase Auth または Auth.js
File uploads Supabase Storage
Scheduling pg_cron または外部 (Inngest、Trigger.dev)

移行プレイブック

すべてを一度に再構築しようとしないこと。それが壮大に失敗するのを見た。ここが実際に機能するフェーズアプローチだ。

フェーズ1:監査と計画(1~2週間)

コードの1行を書く前に、Bubble アプリがすべてを行う方法を文書化すること。本当にすべて:

  1. すべてのページをマップ —スクリーンショット、ユーザーフロー、各ページが読み書きするデータ
  2. すべてのワークフローをカタログ化 —サーバーサイドとクライアントサイド、何がそれらをトリガーするか、何をするか
  3. データモデルを文書化 —すべてのデータ型、すべてのフィールド、すべての関係
  4. すべての統合をリストアップ —Stripe、SendGrid、Twilio、使用しているプラグイン
  5. 何を削減するかを特定する —誰も使わない機能があるはずだ。死んだ重量を移行しないこと。

フェーズ2:基盤を構築(2~3週間)

新しいスタックを立ち上げる:

npx create-next-app@latest my-app --typescript --tailwind --app
cd my-app
npm install @supabase/supabase-js @supabase/ssr

Supabase プロジェクトをセットアップし、認証を設定し、データベーススキーマを作成する。ここは Bubble で作ったすべてのデータモデリングの間違いを修正する場所だ。適切な外部キー、インデックス、データ型を活用している。

フェーズ3:コア機能を構築(4~8週間)

トラフィックが最も多い機能から始める。それらを Next.js で正しく構築する。Bubble の正確な UI を複製しようとしないこと—ユーザー体験を改善する機会を利用すること。

フェーズ4:データとユーザーを移行(1~2週間)

これが怖い部分で、独自のセクションが必要だ。

フェーズ5:切り替え(1週間)

両方のシステムを並行実行し、すべてが機能することを確認し、DNS をフリップする。Bubble アプリを読み取り専用モードで数週間実行したままにして、安全ネットとして保つ。

データ移行:Bubble のデータベースから脱出する

Bubble では CSV ファイルとしてデータをエクスポートできる。それが出発点だが、期待するほどクリーンではない。

# Bubble CSV エクスポートを変換するための Python スクリプト例
import csv
import json
from supabase import create_client

supabase = create_client(SUPABASE_URL, SUPABASE_KEY)

with open('bubble_users_export.csv', 'r') as f:
    reader = csv.DictReader(f)
    for row in reader:
        # Bubble は日付を奇妙な形式でエクスポートする
        created = convert_bubble_date(row['Created Date'])
        
        # Bubble は「1677234567890x123456789」のような一意の ID を使用する
        # これらを UUID にマップする必要がある
        user_data = {
            'legacy_bubble_id': row['unique id'],
            'email': row['email'],
            'name': row['name_text'],
            'created_at': created,
            # すべてのカスタムフィールドをマップする
        }
        
        supabase.table('users').insert(user_data).execute()

Bubble データエクスポートの主な注意点:

  • 関係は Bubble ID として保存される —これらを新しい外部キーに変換するためのマッピングテーブルを構築する必要がある
  • ファイルフィールドは Bubble CDN URL としてエクスポートされる —Bubble アプリがオフラインになる前に、これらのファイルをダウンロードして Supabase Storage に再アップロードする必要がある
  • リストフィールドはコンマ区切りの Bubble ID としてエクスポートされる —これらは適切な結合テーブルになる必要がある
  • 日付形式が一貫していない —日付解析を徹底的にテストすること

Bubble Data API の場合、プログラム的にデータを取得することもできます。これは時々 CSV エクスポートより簡単で、大規模なデータセットの場合:

// Bubble の Data API からデータを取得
const fetchBubbleData = async (type, cursor = 0) => {
  const response = await fetch(
    `https://yourapp.bubbleapps.io/api/1.1/obj/${type}?cursor=${cursor}&limit=100`,
    {
      headers: {
        'Authorization': `Bearer ${BUBBLE_API_KEY}`
      }
    }
  );
  return response.json();
};

Next.js でフロントエンドを再構築する

Bubble のビジュアルエディタは、パターンが見えたら、コンポーネントベースのアーキテクチャに驚くほどよく対応する。Bubble の「Reusable Element」は文字どおり React コンポーネントだ。Bubble の「Group」は Tailwind クラスを使った<div>だ。

Bubble でデータが多かったページに使用するパターンはここだ:

// app/dashboard/page.tsx
import { createClient } from '@/lib/supabase/server';
import { DashboardStats } from '@/components/dashboard-stats';
import { RecentActivity } from '@/components/recent-activity';

export default async function DashboardPage() {
  const supabase = await createClient();
  
  const { data: stats } = await supabase
    .from('user_stats')
    .select('*')
    .single();
  
  const { data: activity } = await supabase
    .from('activity_log')
    .select('*, project:projects(name)')
    .order('created_at', { ascending: false })
    .limit(20);

  return (
    <div className="max-w-7xl mx-auto px-4 py-8">
      <h1 className="text-3xl font-bold mb-8">Dashboard</h1>
      <DashboardStats stats={stats} />
      <RecentActivity items={activity} />
    </div>
  );
}

データフェッチはサーバーサイドで発生することに注意してほしい。ローディングスピナーなし、ウォーターフォール要求なし。ページは完全にレンダリングされて到着する。これだけで、Bubble バージョンより劇的にアプリが速く感じられる。

コンポーネントライブラリについては、shadcn/ui で素晴らしい結果が得られた。これは、所有する(パッケージからインポートされるのではなく、コードベースにコピーされる)洗練されたアクセス可能なコンポーネントを提供する。Tailwind CSS と組み合わせて、Bubble UI を迅速に再構築でき、さらにレスポンシブでパフォーマンスが良くなる。

Supabase をバックエンドとして設定する

Supabase の Row Level Security は Bubble の Privacy Rules の置き換えであり、正直なところ、それはより強力だ:

-- ユーザーが自分のデータのみを見ることを許可
CREATE POLICY "Users can view own data"
  ON user_profiles FOR SELECT
  USING (auth.uid() = user_id);

-- ユーザーが自分のプロフィールのみを更新することを許可
CREATE POLICY "Users can update own profile"
  ON user_profiles FOR UPDATE
  USING (auth.uid() = user_id);

-- 管理者がすべてを表示することを許可
CREATE POLICY "Admins can view all"
  ON user_profiles FOR SELECT
  USING (
    EXISTS (
      SELECT 1 FROM user_roles
      WHERE user_id = auth.uid()
      AND role = 'admin'
    )
  );

バックエンドワークフロー(Bubble でスケジュール上で実行されたもの)については、Supabase Edge Functions と pg_cron はほとんどのユースケースに適している。より複雑なジョブスケジューリングの場合、Trigger.dev または Inngest は Next.js と自然に統合される優れた選択肢だ。

認証とユーザー移行

これが移行全体で最も複雑な部分だ。あなたのユーザーは Bubble に保存されたパスワードを持っており、パスワードハッシュはエクスポートできない。2つのオプションがある:

  1. パスワードリセットを強制 —すべてのユーザーに「プラットフォームをアップグレードした」メールを送信してパスワードリセットリンク。シンプルだが摩擦を作成する。
  2. 遅延移行 —カスタム認証フローをセットアップして、初回ログイン時に Bubble の API に対して認証を試みる。成功した場合、新しく入力されたパスワードで Supabase にユーザーを作成する。

オプション2はより多くの作業が必要だが、ユーザー体験ははるかに良い。概略的な形はここだ:

// app/api/auth/migrate-login/route.ts
export async function POST(request: Request) {
  const { email, password } = await request.json();
  
  // 最初に Supabase を試す
  const { data, error } = await supabase.auth.signInWithPassword({
    email, password
  });
  
  if (data.user) return Response.json({ success: true });
  
  // Supabase にいない場合は、Bubble を試す
  const bubbleAuth = await authenticateWithBubble(email, password);
  
  if (bubbleAuth.success) {
    // 同じパスワードで Supabase にユーザーを作成
    const { data: newUser } = await supabase.auth.admin.createUser({
      email,
      password,
      email_confirm: true,
    });
    
    // 彼らのプロフィールデータを移行
    await migrateUserProfile(bubbleAuth.userId, newUser.user.id);
    
    // 彼らをサインインさせる
    return Response.json({ success: true });
  }
  
  return Response.json({ error: 'Invalid credentials' }, { status: 401 });
}

移行後のパフォーマンスとコスト

2025年後半に移行を支援したプロジェクト管理 SaaS の実際の数字:

メトリック Bubble での 移行後
平均ページロード時間 3.8秒 0.9秒
インタラクティブまでの時間 5.2秒 1.4秒
Lighthouse パフォーマンス 38 92
月額インフラコスト $4,200 $187
月間アクティブユーザー 12,000 12,000
API レスポンス時間 (p95) 1,800ms 180ms
アップタイム (3ヶ月平均) 99.2% 99.97%

コスト削減だけで、2ヶ月以内に移行を正当化した。パフォーマンスの改善は、その後の四半期のチャーンを推定15%削減した。

これらの数字を見ていて、「これが欲しいけど、それを引っ張るための開発チームがない」と考えている場合、これは正確にはメチャクチャそのようなプロジェクトを扱う。ヘッドレス CMS とアプリ開発ワークをチェックするか、移行評価のため お問い合わせ してほしい。

よくある落とし穴とその回避方法

Bubble を正確に複製しようとする

しないこと。Bubble のやり方は、コードベースのスタックでしばしば最悪のやり方だ。移行をユーザーフローとデータアーキテクチャを見直す機会として使うこと。

データ移行を過小評価する

必要だと思う時間の2倍予算を組む。Bubble のデータエクスポートには、予想外のエッジケースがある。予期しないヌル値。重複レコード。孤立した関係。

ファイルストレージを忘れる

Bubble はアップロードされたファイルを自社の CDN にホストする。Bubble プランをキャンセルすると、これらの URL は期限切れになる。すべてのファイルが Bubble を翻すれる前に Supabase Storage にダウンロードおよび再アップロードされることを確認すること。

早期にモニタリングをセットアップしないこと

Bubble では、とにかく何もできないので、モニタリングについて考えないことができる。新しいスタックでは、初日から Sentry でエラー追跡と Vercel Analytics(または Plausible/PostHog)でパフォーマンスモニタリングをセットアップすること。

一人では行くべきでない場合にしておく

Bubble アプリが複雑で収入にとって重大な場合は、これを前に行ったチームから真剣に助けを得ることを検討すること。移行の失敗のコスト—失われたデータ、ダウンタイム、ユーザーチャーン—は専門的な支援のコストを遥かに上回る。価格ページ にはエンゲージメントがどのように見えるかについての詳細がある。

FAQ

Bubble から Next.js + Supabase への移行にはどのくらい時間がかかりますか?

10~30ページで中程度複雑な典型的な SaaS アプリの場合、完全な移行には8~16週間を予想する。シンプルなアプリ(ランディングページ+ダッシュボード+いくつかの CRUD 機能)は4~6週間で行える。複雑なアプリ(多くの統合、カスタムロジック、大規模なデータセット)は16~24週間かかることがある。データ移行とユーザー認証遷移は通常、予想より時間がかかるもの。

Bubble から段階的に移行するか、すべて一度にしなければなりませんか?

絶対に段階的に行うことができる。一般的なアプローチは、Bubble アプリと一緒に新しい Next.js アプリを構築し、一度に1つの機能を移行し、サブドメインルーティングを使用して正しいバージョンにユーザーを送信することだ。たとえば、新しいダッシュボードは app.yoursite.com に存在し、レガシー機能は引き続き Bubble で実行される。ただし、2つのシステムを同時に保守することは独自のコストを持つことに注意してほしい。

FlutterFlow、WeWeb、Xano などの Bubble の代替案について考慮する必要がありますか—代わりにそれらを選択する必要がありますか?

メインの問題が Bubble の料金だがまだノーコード/ローコードアプローチが欲しい場合、WeWeb(フロントエンド)+ Xano(バックエンド)のようなツールは機能する。しかし、別のベンダーロックインと交換している。Bubble から卒業する理由がパフォーマンス、スケーラビリティ、またはチームサイズの場合、最終的にこれらのツールからも卒業することになる。Next.js + Supabase のようなコードベースのスタックへの移動は、無期限にスケールする1回限りの投資だ。

Bubble と比較して Next.js + Supabase アプリを実行するコストはいくらですか?

ほとんどの SaaS アプリについては、Vercel + Supabase で月額45~200ドルを見ています。これは Bubble で月額349~5,000ドル以上かかるもののため。Supabase Pro は月額25ドル、Vercel Pro は月額20ドル。スケールで、カスタムスタックはワークフローユニットではなく実際の計算リソースに対して支払うため、コストは非常にゆっくり増加する。粗い経験則:Bubble で支払っていた金額の5~20%を支払うと予想する。

SEO は移行の影響を受けますか?

それは劇的に改善できる。Bubble アプリはクライアントレンダリングされており遅いため、Core Web Vitals スコアに悪影響を与える。Next.js はサーバーサイドレンダリングと静的生成をサポートしているため、ページの読み込み速度が速くなり、クローラビリティが向上する。古い Bubble URL から新しい Next.js ルートへの適切な 301 リダイレクトをセットアップしていることを確認してほしい。その後、数週間以内に SEO の改善が見えるはずだ。

Supabase を使用するために PostgreSQL を知る必要がありますか?

基本的な SQL の知識は大いに役に立つが、Supabase はビジュアルテーブルエディタと JavaScript クライアントライブラリを提供し、ほとんどのクエリを抽象化する。そうは言っても、SQL を理解することで劇的に効果的になる。複雑なクエリ、レポート、パフォーマンスチューニングについては、SQL 知識は不可欠だ。あなたのチームが SQL の経験がない場合、これはそれを学ぶのに良い時間だ—それは永遠に配当金を支払うスキルだ。

移行中に Bubble アプリの API 統合はどうなりますか?

それぞれの統合を Next.js アプリで再作成する必要がある。良いニュースは、これは通常 Bubble の API Connector プラグインを使うより非常に簡単だということだ。Bubble で15のワークフローとプラグインを要求した Stripe 統合は、Stripe Node.js SDK で50行のコードかもしれない。すべての外部サービスが Bubble アプリと通信する完全なリストを作成し、一度に1つずつ実行すること。

本番環境で Supabase の無料ティアを使用できますか?

2026年の Supabase 無料ティアは、500MB のデータベースストレージ、1GB のファイルストレージ、認証で50,000月間アクティブユーザーを提供する。非常に初期段階の製品については、これは機能する。しかし、本番アプリの場合、月額25ドルの Pro プランが必要で、パフォーマンスが向上し、日次バックアップがあり、非アクティブ後のプロジェクト一時停止がない。これは引き続き Bubble と比較して非常に安い。