Supabase
Postgres を中心に置いた「Firebase の OSS 代替」。Auth / Realtime / Storage / Edge Functions / Vector まで揃った Backend-as-a-Service。SaaS でもセルフホストでも動く。
これは何か
Postgres + 周辺サービスを1 つの SaaSとして使えるようにしたもの。 フロントだけでもバックを構成できる「BaaS」だが、中身が完全に Postgres なので いつでも普通の SQL データベースとして持ち出せる。
構成要素
| サービス | 中身 | 役割 |
|---|---|---|
| Database | Postgres 16/17 | データ本体。標準 SQL がそのまま使える |
| Auth | GoTrue(OSS) | メール / OAuth / Phone / Magic Link |
| API | PostgREST + pg-meta | テーブルから自動で REST API を生成 |
| Realtime | Phoenix 製の Realtime サーバ | Postgres 変更を WebSocket で配信 |
| Storage | S3 互換のオブジェクトストレージ | 画像・ファイル + 署名付き URL |
| Edge Functions | Deno on Cloudflare | サーバ側ロジック |
| Vector | pgvector 拡張 | 埋め込み検索 / RAG |
Firebase との違い
| Supabase | Firebase | |
|---|---|---|
| DB | Postgres(リレーショナル) | Firestore(ドキュメント) |
| クエリ | SQL / 結合 / 集計が強い | NoSQL(結合できない) |
| OSS | ○ セルフホスト可 | ×(プロプラ) |
| 移行 | 普通の Postgres dump で完結 | 独自エクスポート |
| RLS | Postgres の行レベル権限が強力 | Security Rules(独自 DSL) |
| 料金 | 容量・転送ベースで安い | 読み込み件数で青天井になりがち |
| Edge | Deno (CF Workers) | Functions (Node) |
得意分野
- SaaS / Web アプリのバックエンド全般
- 認証 + DB + ストレージが一体で必要
- リアルタイム同期(チャット、共同編集)
- RAG / ベクトル検索(pgvector が標準で使える)
- Next.js / Nuxt / Remix / SvelteKit などとの相性◎
- 個人開発 〜 中規模 SaaS
苦手分野 / 注意
- Cold start: Free プランは 1 週間アイドルで一時停止
- 巨大トラフィック: Postgres 単体になるので工夫が要る
- 複雑な RLS はSQL の理解が必須
- Realtime は同時接続数に制限あり
料金感(2026 年初頭)
- Free: 500MB DB / 1GB Storage / 50,000 MAU / 一時停止あり
- Pro: $25/月 から、8GB DB、点で課金されない
- Team / Enterprise: 大規模向け
- セルフホストは完全無料(インフラ代のみ)
このセクションの読み方
- セットアップ — プロジェクト作成と最小サンプル
- Database — テーブル設計と SQL
- Auth — メール / OAuth / セッション
- Realtime — DB 変更通知 / Broadcast / Presence
- Storage — 画像とファイル
- Edge Functions — サーバ側ロジック
- Row Level Security — 認可の心臓部
- 運用と注意点
クイックスタート
npm install @supabase/supabase-js
import { createClient } from "@supabase/supabase-js"
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
)
// 一覧取得
const { data, error } = await supabase
.from("posts")
.select("id, title, created_at")
.order("created_at", { ascending: false })
// 認証
await supabase.auth.signInWithPassword({ email, password })
// リアルタイム
supabase
.channel("posts")
.on("postgres_changes", { event: "*", schema: "public", table: "posts" },
(payload) => console.log(payload))
.subscribe()