Convex公式ドキュメントを全部まとめた:かたい文章を、かるく読み解く。
どうも、こんにちは。私です。
先日のCursor Meetup Tokyoで、サイバーエージェントのグンタ(@gunta85)さんが登壇されていたのですが、そのスライドで気になる技術が紹介されていました。それがConvexです。
なぜConvexが推されていたのか
グンタさんのスライドではこんな感じで書かれていました:
- 完全なe2e型付け
- リアルタイムDB
- SQLなし!
- スキーマ強制でAI生成が完璧
リアルタイムDBもスゴいのですが、「AIコード生成が完璧」と書かれていたのが印象的ですね:
- TypeScript優先の設計: 完全なe2e型付けで、AIが生成するコードの精度が上がる
- スキーマ強制: データベースの構造が明確なので、AIが間違ったコードを生成しにくい
型とスキーマが明確に定義されていることで、人間の開発者は「何を書けばいいか」が分かりやすく、同時にAIも「どんなコードを生成すべきか」の判断材料が豊富になります。曖昧さが少ないほど、人間もAIも正確なアウトプットを出しやすくなるということでしょうか。しらんけど。
「いまっぽいBaaSなんだろうなー。Supabaseとかと何が違うんだろ?」ぐらいでその日は終わっていたのですが、ずーと頭の片隅に残っていたので🤔 公式ドキュメントを読んでみることにしました。
2025/6/16追記:
Convexとは何なのか
Convexは、TypeScriptネイティブのリアクティブBaaS(Backend as a Service)プラットフォームです。Firebase、Supabaseと同じカテゴリーですが、設計思想やアプローチが大きく異なります。
FirebaseやSupabaseとの違い
多くのBaaSプラットフォームでは、「データベース」「API」「リアルタイム同期」を別々の仕組みとして扱い、開発者がそれらを組み合わせる必要がありました。
Firebaseは「NoSQLドキュメントベース」で直感的な扱いやすさを重視し、Supabaseは「PostgreSQL + REST API」で既存のSQL知識を活用できるアプローチを採用しています。
一方でConvexは「TypeScript中心の統合型アプローチ」という独自の道を選んでいます。データベースへのアクセス、API定義、リアルタイム同期がすべてTypeScriptのQuery(読み取り専用)とMutation(読み書き)という2つの関数で統一され、SQLやAPIエンドポイントの設定が大幅に簡素化されます。
技術選択における位置づけ
Convexは「開発者がビジネスロジックに集中できる」ことを目指した設計思想が特徴的です。データベース設計、API設計、WebSocket設定、トランザクション管理といった「バックエンド開発の複雑な部分」を自動化し、アプリケーションの核となる価値創造に時間を使えるアプローチを取っています。
比較的新しいプラットフォームのため、技術の枯れ具合や、コミュニティや情報量の面では成熟したFirebaseやSupabaseに劣る場合もありますが、現代の開発スタイル、特にTypeScriptを中心とした開発やAI支援開発を重視するチームにとっては、非常に魅力的な選択肢と言えるでしょう。
ざっくりとした公式の目次
公式ドキュメントの構成を簡単にまとめると、こんな感じです:
基本情報
はじめに
コア機能
- Functions(関数)
- Database(データベース)
- Realtime(リアルタイム)
- Authentication(認証)
- Scheduling(スケジューリング)
- File Storage(ファイルストレージ)
- Search(検索)
ガイド
ホームからリンクされていたYoutube
公式ドキュメントのホームには、理解を深めるための動画コンテンツへのリンクもありました:
Why Convex?(なぜConvex?)
- Backends for Product Developers(プロダクト開発者のためのバックエンド)
- Intro to Convex(Convex入門)
- Supercharging your app with a reactive backend(リアクティブバックエンドでアプリを強化)
- Why I use Convex over Supabase as my BaaS(なぜ私はBaaSとしてSupabaseではなくConvexを選んだのか)
Learn Convex(Convexを学ぶ)
- Convex with Next.js Quickstart(Next.jsとConvexのクイックスタート)
- Notion Clone: Next.js 13, React, Convex, Tailwind(Notionクローン: Next.js 13, React, Convex, Tailwind)
- Build a Saas Podcast Platform in Next.js(Next.jsでSaaSポッドキャストプラットフォームを構築)
- Building a Subscription Based SaaS with Stripe(Stripeを使用したサブスクリプションベースのSaaS構築)
その他関連動画から出てきた、良さそうなチュートリアル
- The Complete Convex Crash Course(Convex完全クラッシュコース)
- Fullstack app with Next.js, Convex, ShadCN(Next.js、Convex、ShadCNでフルスタックアプリ)
- Building a Subscription Based SaaS with my Favorite Tech Stack(お気に入りの技術スタックでサブスクリプションベースSaaSを構築)
では公式ドキュメントを読んでみよう
実際にGoogle翻訳で読みつつ、AIに要約してもらいつつ、手直ししつつみたいな感じでこの記事は同時に作成しています。ハレーションや私の誤読があったらすいません。その際はご指摘いただければ幸いです。
ではまず、理解を深めるために、まずは公式チュートリアルを実際にやってみることにしましょう。
【はじめに】
■ チュートリアル「10行でチャットアプリ」
チュートリアルのキャッチコピーが「10 lines of code」でチャットアプリを作るというもの。「ちょい盛ってるでしょ〜」と思いながら始めたのですが、わりと本当でした。
まず、Convexの基本概念を理解しておくと分かりやすいです:
Query(クエリ): データベースからデータの読み取り専用の関数
Mutation(ミューテーション): データベースのデータの読み書き関数
この2つがConvexの核となる仕組みです。実際のコードはこんな感じ:
// メッセージを読み取るQuery
export const listMessages = query({
args: {},
handler: async (ctx) => {
return await ctx.db.query("messages").collect();
},
});
// メッセージを書き込むMutation
export const sendMessage = mutation({
args: { user: v.string(), body: v.string() },
handler: async (ctx, args) => {
await ctx.db.insert("messages", {
user: args.user,
body: args.body,
});
},
});
基本的にこれだけで、リアルタイムチャットが動きます。普通、チャットアプリを作ろうと思ったら、リアルタイム同期の実装やらAPI設計やらめんどくさそ~と思いますが、ConvexならWebSocketの設定すら不要。Queryをフロントエンドから呼び出すと、データベースが更新されるたびに自動でリアルタイム同期されます。Convexの「sync engine」が全部やってくれるようです。
複数のブラウザタブで開いて、片方でメッセージを送ると、もう片方に瞬時に反映される。実際に動かしてみると「え、これマジでリアルタイムに動いてる...」ってなります。AI系のチャットプロダクトを作る時にも相性が良さそうですね。
トランザクション内で非同期処理をスケジュールする「Scheduler」
チュートリアルの第2段階で登場するのがSchedulerという仕組み。
外部APIの呼び出し(Action)を、mutation内からスケジュールできるんです:
// mutation内で外部API呼び出しをスケジュール
await ctx.scheduler.runAfter(0, internal.chat.getWikipediaSummary, {
topic,
});
これがトランザクション内で実行されるので、mutationが失敗したらスケジュールもキャンセルされる。データの整合性が保たれるわけです。
従来だと「データ更新してからキューに投げて...」みたいな処理を自分で書かなきゃいけないところが、Convexだと標準機能として組み込まれています。
スケーリングのためのガイドも充実
第3段階では、アプリをスケールさせるためのベストプラクティスへのリンクが提供されています:
- インデックス:クエリを高速化するための仕組み
- 同時書き込み競合の対処法:大量アクセス時の対策
- Convex Components:よくある課題の解決パッケージ
とくに「Convex Components」は面白くて、よくある課題(カウンター、AIエージェント ワークフロー、レート制限など)の解決策が、npmパッケージのように提供されています。
車輪の再発明をしなくて済むというか、スケーリングのノウハウが部品化されてるんですね。「バックエンド開発の面倒な部分が、ごっそりパッケージされてる」素敵な機能と言えます。
■ Convex Components
具体的な機能に入る前に、Convex Componentsが気になったので先にこちらを掘ってみましょう。
Convex Componentsは、コードとデータをサンドボックス内にパッケージ化し、バックエンドに新機能を安全かつ迅速に追加できる仕組みです。各コンポーネントはNPMより独立したライブラリとしてインストールできます。
🔄 Durable Functions(長期実行・ワークフロー管理)
-
Workflow - 数ヶ月間実行可能な長期ワークフローを、サーバー再起動に耐えながら実行
- 使用例:ECサイトで注文確定→3日後にレビュー依頼→1週間後にクーポン送付、AIによる長時間の学習データ処理
-
Workpool - 並列実行数を制限しながらタスクをキューで管理する非同期処理プール
- 使用例:画像リサイズ処理を同時5件まで、メール送信を同時10件まで、のようなリソース制御
-
Crons - 実行時に動的にcronジョブを作成・管理
- 使用例:ユーザーが設定したリマインダー時刻に通知、定期レポートの自動生成
-
Action Retrier - 外部API呼び出しが失敗した時に自動でリトライ処理
- 使用例:決済API、メール送信API、外部データ取得APIの一時的な障害に対する自動復旧
🗄️ Database(データベース)
-
Sharded Counter - 大量の同時アクセスでも競合しない分散カウンター
- 使用例:記事の「いいね」数、商品の在庫数、サイトの訪問者数など高頻度で更新されるカウンター
-
Migrations - データベーススキーマの変更を安全に実行
- 使用例:新機能リリース時のテーブル構造変更、データ形式の変換、インデックスの追加
-
Aggregate - 大量データの合計・集計を効率的に計算
- 使用例:売上レポート、ユーザー行動分析、リアルタイムダッシュボードの数値計算
-
Geospatial (Beta) - 位置情報の保存と地理的検索
- 使用例:近くの店舗検索、配達エリア判定、位置ベースのマッチングアプリ
-
Presence - ユーザーのリアルタイム在線状態を追跡
- 使用例:チャットアプリの「オンライン」表示、共同編集での「誰が見ているか」表示、ゲームのプレイヤー状態
🔗 Integrations(統合)
-
Cloudflare R2 - Cloudflare R2でファイルを保存・配信
- 使用例:ユーザーアップロード画像、動画ファイル、PDFドキュメントの高速配信
-
Collaborative Text Editor Sync - Google Docsのようなリアルタイム共同編集機能
- 使用例:チーム用ドキュメント作成、共同ブログ執筆、リアルタイム議事録作成
-
Expo Push Notifications - React Nativeアプリにプッシュ通知を送信
- 使用例:新着メッセージ通知、リマインダー、アプリ更新のお知らせ
-
Twilio SMS - TwilioでSMSの送受信
- 使用例:二段階認証、注文確認SMS、緊急アラート通知
-
LaunchDarkly Feature Flags - 機能フラグをバックエンドと同期
- 使用例:新機能の段階的ロールアウト、A/Bテスト、緊急時の機能無効化
-
Polar - Polarによるサブスクリプション課金システムを追加
- 使用例:SaaSの月額課金、プレミアム機能の有料化、使用量ベース課金
-
OSS Stats - GitHubとnpmのオープンソースプロジェクトデータを同期
- 使用例:オープンソースプロジェクトのスター数・ダウンロード数の追跡、開発者ポートフォリオサイト
⚙️ Backend(バックエンド)
-
AI Agent - ツールとメモリを持つAIエージェントを定義
- 使用例:カスタマーサポートボット、コード生成アシスタント、データ分析エージェント
-
Persistent Text Streaming - ChatGPTのようなストリーミングテキストを保存
- 使用例:AIチャット履歴の保存、リアルタイム翻訳結果の記録、長文生成の途中経過保存
-
Rate Limiter - API呼び出し回数を制限してリソースを保護
- 使用例:ユーザーごとのAPI利用制限、スパム防止、外部API呼び出しのコスト制御
-
Action Cache - 重い外部API呼び出し結果をキャッシュ
- 使用例:天気予報API、為替レートAPI、AI画像生成APIの結果を一定時間キャッシュ
まだまだベータ版的な気配もありますが、全般的に今っぽい便利なコンポーネントが兼ね備えられているという印象ですね。
■ クイックスタート(各フロントエンド・言語との連携)
Convexは、React、Next.js、Vue、Svelte、React Nativeなど主要なフロントエンドフレームワークに対応しています。バックエンド側でもPython、Swift、Kotlin、Rustなどの言語から利用可能。各フレームワーク・言語向けのクイックスタートガイドが用意されているので、すぐに始められます。
例えばNext.jsなら、npm create convex
コマンドで簡単にセットアップできて、数分でリアルタイムアプリケーションの土台が整います。どのフレームワークを使っても、TypeScriptの型定義が自動で生成されるので、開発体験はかなり良さそうです。
■ Convexの理解
基本概念とアーキテクチャ
Convexは「リアクティブデータベースプラットフォーム」として設計されています。簡単に言うと、Excelのように「どこかのセルを変更すると、関連する全ての数式が自動で再計算される」ような仕組みを、Webアプリ全体で実現するプラットフォームです。
TypeScriptでクエリを直接記述でき、データベースの変更を自動的にフロントエンドに反映。ドキュメントリレーショナルデータベースで、JSON形式のネストされたオブジェクトを保存できます。Query(読み取り専用)とMutation(読み書き)という2種類の関数でデータを操作し、WebSocket経由で自動的にリアクティブな同期を実現します。
開発ワークフロー
npm i convex
でインストール後、npx convex dev
で開発を開始。このコマンドを実行したままにすることで、TypeScriptの型定義が自動更新され、バックエンドコードも継続的にデプロイされます。ダッシュボード(npx convex dashboard
)では、ログ、ヘルスモニタリング、データブラウザ、関数の統計情報などを確認可能。本番環境へはnpx convex deploy
でデプロイし、個人の開発環境とは分離された環境で運用します。
ベストプラクティス
-
Promise処理: 非同期処理は必ず
await
で待つ(処理が終わる前に次に進まないように) -
データベースクエリの書き方:
- ❌ 悪い例:全データを取得してから
.filter()
で絞り込む(遅い) - ✅ 良い例:最初から
.withIndex()
でインデックスを使って絞り込む(速い)
- ❌ 悪い例:全データを取得してから
-
関数設計のルール:
- 外部から呼ばれる関数は必ず引数チェック(変な値が来てもエラーにならないように)
- 「誰がこの機能を使えるか」の権限チェックを必ず入れる
-
フォルダ構成の工夫:
- ビジネスロジックは
model
フォルダにまとめる(再利用しやすい) -
query
やmutation
は薄くして、実処理はmodel
に書く(テストしやすい)
- ビジネスロジックは
-
速度を保つコツ:
- 同じインデックスを複数作らない(無駄なので)
- データベース操作の連続呼び出しは避ける(まとめて処理する方が速い)
TypeScriptベストプラクティス
-
型の自動生成を活用:
- 引数バリデーターを書くだけで、TypeScriptの型が自動で作られる
- 例:
v.string()
と書けば、自動的にstring
型として認識される
-
スキーマ定義のメリット:
- データベースの構造を定義すると、コード補完が賢くなる
-
Doc<"users">
のような便利な型が使えるようになる(userテーブルの型) -
Id<"users">
でユーザーIDの型も明確に(間違えてpostのIDを渡すミスを防げる)
-
フロントエンドでの型活用:
- Reactコンポーネントでも、バックエンドと同じ型定義を使える
-
FunctionReturnType
を使えば、API関数の戻り値の型も自動で分かる
Zen(設計哲学)
パフォーマンス重視の設計
- 「sync engine」がアプリの心臓部(全てのリアルタイム同期を管理)
- クエリは軽量に保つ(100ms以下、数百レコード以内が理想)
- アクションは必要最小限に使い、段階的に追加する
- キャッシュと一貫性はConvexに任せる(自分で管理しない)
アーキテクチャの考え方
- 複雑な問題も「ただのコード」で解決(特殊な仕組みに頼らない)
- 標準的なTypeScriptの技術でサーバーサイドフレームワークを構築
- アクションは「バックグラウンドジョブ」ではなく「ワークフロー」として考える
開発ワークフローの原則
- ダッシュボードを積極的に活用(デバッグとパフォーマンス分析の要)
【コア機能】
■ Functions(関数)
Functions(関数) | Convex公式ドキュメント
Convexの「Functions」は、従来のバックエンド開発でいうAPI、バックグラウンドジョブ、Webhook、cronジョブなどを統一的に扱える仕組みです。5つの関数タイプがあり、それぞれ明確な役割を持っています。
従来のバックエンドとの対応関係
従来のバックエンド | Convex Functions | 特徴 |
---|---|---|
REST API (GET) | Query | リアルタイム同期、読み取り専用 |
REST API (POST/PUT/DELETE) | Mutation | トランザクション付き書き込み |
バックグラウンドジョブ | Action | 外部API連携、非同期処理 |
Webhook受信 | HTTP Action | 外部サービスからの通知受信 |
内部処理・cronジョブ | Internal Function | セキュアな内部処理 |
WebSocket | 自動処理 | Queryが自動的にリアルタイム化 |
各関数タイプの特徴
Query(クエリ)
- データの読み取り専用(副作用なし)
- 結果が自動的にリアルタイム同期される(WebSocket設定不要!)
- 実行時間制限:1秒以内
- 用途:チャット画面、ダッシュボード、ユーザープロフィール表示など
Mutation(ミューテーション)
- データの読み書きが可能
- ACID トランザクション保証(全て成功or全て失敗)
- 実行時間制限:10秒以内
- 用途:フォーム送信、いいねボタン、コメント投稿、在庫更新など
Action(アクション)
- 外部API呼び出しなど非決定論的な処理が可能
- Node.js環境で実行(ブラウザAPIも使用可)
- 実行時間制限:10分以内
- 用途:OpenAI API、Stripe決済、画像リサイズ、CSVインポートなど
HTTP Action(HTTPアクション)
- 外部サービスからのWebhook受信用
- 標準的なWeb APIを使用(Request/Response)
- URLパスのカスタマイズ可能
- 用途:GitHub Webhook、Slackボット、ファイルアップロードなど
Internal Function(内部関数)
- 外部から直接呼び出せない(セキュア)
- cronジョブやスケジューラーから実行
- 管理者向けの危険な操作に最適
- 用途:権限昇格、課金プラン変更、データクリーンアップなど
Convexならではの特徴
リアクティブシステム
- Queryの結果が変わると、自動的にクライアントに通知
- useState + useEffectのような感覚でバックエンドを書ける
- WebSocketの管理やポーリングの実装が不要
トランザクションとスケジューリングの統合
- Mutation内でActionをスケジュール可能
- エラーが起きたら、スケジュールも自動的にキャンセル
- データの整合性が保たれる
型安全なバリデーション
- 引数バリデーターから自動的にTypeScriptの型が生成
- フロントエンドとバックエンドで型を共有
- 開発時のエラーを大幅に削減
構造化されたエラーハンドリング
- ConvexErrorで詳細なエラー情報を提供
- クライアント側で適切なエラー処理が可能
- ユーザーフレンドリーなエラーメッセージを実現
実践的な使い分けガイド
- リアルタイム更新が必要な画面 → Query
- データの作成・更新・削除 → Mutation
- メール送信、AI API呼び出し → Action
- Stripe Webhook、GitHub Webhook → HTTP Action
- 定期的なデータクリーンアップ → Internal Function
- ユーザーに見せたくない管理処理 → Internal Function
■ Database(データベース)
Database(データベース) | Convex公式ドキュメント
Convexのデータベースは「TypeScriptネイティブ」を掲げる、従来のBaaSとは異なるアプローチを採用しています。SQLクエリの代わりにTypeScriptでデータアクセスを行い、リアルタイム同期が標準装備され、型安全性が自動で保証される設計になっています。
従来のBaaSとの設計思想の違い
各BaaSがそれぞれ異なるアプローチを取っていることがよく分かります。FirebaseはNoSQLドキュメントベースで扱いやすさを重視し、SupabaseはPostgreSQLベースで既存のSQL知識を活用できます。
そしてConvexは「ドキュメントリレーショナル」という独自のアプローチを採用し、JSONライクなネストしたデータを扱いながら、リレーショナルな関係性も表現できる点が特徴的です。
特に注目すべきは、「リアクティブシステム」が設計の中核に組み込まれていることです。リアクティブとは「反応する」という意味で、データが変更されると自動的に関連するすべての画面やコンポーネントが即座に更新される仕組みのことです。
従来のFirebaseやSupabaseでは「データを読む」「リアルタイム同期を設定する」を分けて考える必要がありましたが、Convexでは全てのQueryが自動的にこの「反応する仕組み」を持ちます。これはExcelで「どこかのセルを変更すると、関連する全ての数式が自動で再計算される」ような体験を、Webアプリ全体で実現するアプローチです。つまり、開発者がリアルタイム同期を意識することなく、自然に最新データが画面に反映される仕組みが標準で備わっているということです。
主要BaaSサービスの比較
項目 | Firebase | Supabase | Convex |
---|---|---|---|
データベース | NoSQL | PostgreSQL | ドキュメントリレーショナル |
クエリ言語 | Firebase SDK | SQL | TypeScript |
リアルタイム | 別途設定 | WebSocket設定 | 自動装備 |
型安全性 | 手動実装 | 手動実装 | 自動生成 |
学習コスト | 中程度 | SQL知識必要 | TypeScript知識必要 |
コミュニティ | 非常に豊富 | 豊富 | 成長中 |
TypeScriptファーストによる開発体験
Convexの最大の特徴は、データベースへのアクセスがすべてTypeScriptで完結することです。SQLやクエリ言語を覚える必要がありません。メソッドチェーンによる直感的な記述で、IDEの自動補完やコンパイル時エラーチェックの恩恵を完全に受けられます。
// 従来のSQL: SELECT * FROM messages WHERE channel = 'general' ORDER BY created_at
// Convexの書き方
const messages = await ctx.db
.query("messages")
.withIndex("by_channel", (q) => q.eq("channel", "general"))
.collect();
さらに重要なのは、型定義が自動生成されることです。スキーマを定義すると、フロントエンドからバックエンドまで一貫した型安全性が保証されます。これにより、特にAI開発ツールがより正確なコードを生成できるようになります。TypeScriptの既存訓練データを効果的に活用でき、構造的制約によって適切なコード生成範囲を提供するためです。
スキーマレスから始まる柔軟な開発フロー
Convexは型安全性を重視した設計でありながら、「スキーマレス」で開発をスタートできる柔軟性を持っています。プロトタイプ段階では型定義なしでスピード重視の開発を行い、アプリケーションが成熟してきたら段階的にスキーマを定義して型安全性を向上させる、という開発スタイルが可能です。
これは特にAI時代の開発において重要な特徴で、「まず動くものを作って、段階的に堅牢にしていく」という現代的な開発フローに適しています。スキーマを後から追加する際も、既存データとの互換性を保ちながら段階的に制約を強化できます。
自動トランザクション管理による信頼性
従来のデータベースでは、複数の操作をまとめて実行したい場合、明示的にトランザクションを開始・コミット・ロールバックする必要がありました。Convexでは、Mutation関数内で行うすべての操作が自動的に1つのトランザクションとして扱われます。
これは単なる利便性の向上ではなく、データの整合性を保つ重要な機能です。送金処理のような複数のデータ更新を伴う処理でも、途中でエラーが発生すれば全ての操作が自動的にロールバックされ、データの不整合が発生することがありません。
OCC(楽観的並行性制御)による高い並行性
従来のデータベースが採用するペシミスティックロック(データを読む前にロックを取得)と異なり、ConvexはOCC(Optimistic Concurrency Control)を採用しています。これは「読み取り時はロックしない、書き込み時に競合をチェックして、必要なら自動的にリトライ」という仕組みです。
開発者は競合制御を意識する必要がほとんどなく、システムが自動的に最適化された並行処理を実現します。デッドロックの心配もなく、高負荷時でも安定した動作を期待できます。
インデックス設計による予測可能なパフォーマンス
Convexは「明示的なインデックス」という考え方を採用しています。効率的にデータを検索したい場合、事前にインデックスを定義する必要があります。これは一見手間に思えますが、実はメリットもあります。
パフォーマンスが予測可能になることで、「知らないうちに遅いクエリが実行されていた」という事態を防げます。また、どのクエリが高速で、どのクエリに最適化が必要かが明確になるため、長期的なメンテナンス性が向上します。
リアルタイム同期の自動化
最も印象的な機能の一つが、WebSocketやポーリングの設定なしにリアルタイムアプリケーションを構築できることです。Queryでデータを取得すると、そのデータが変更されるたびに自動的にクライアントに最新データが配信されます。
従来だと「データの読み取り」「リアルタイム同期の設定」「状態管理」を個別に実装する必要がありましたが、Convexではこれらが統合されています。チャットアプリケーションのような複雑なリアルタイム機能も、驚くほど少ないコードで実現できます。
技術選択時の考慮ポイント
Convexのデータベースは「開発者がビジネスロジックに集中できる」ことを目指した設計思想が特徴的です。SQLの学習、WebSocketの設定、トランザクション管理、型定義の作成といった「データベース開発の周辺作業」を自動化することで、アプリケーションの核となる価値創造に時間を使えるアプローチを取っています。
一方で、この自動化にはトレードオフも存在します。複雑なSQLクエリ(JOIN文や高度な集計関数など)が必要な場合は、JavaScriptで実装する必要があります。また、インデックスの明示的な定義が必要なため、従来のORMに慣れた開発者にとっては最初は学習コストを感じるかもしれません。
特にAI時代の開発において、TypeScriptネイティブ設計とリアクティブシステムの組み合わせは注目に値します。AIツールがより正確で保守しやすいコードを生成できる環境を提供し、これは開発効率の向上だけでなく、アプリケーション開発のアプローチ自体に影響を与える可能性があります。
ただし、Convexは比較的新しいプラットフォームのため、コミュニティや情報量の面ではFirebaseやSupabaseに劣る場合があります。チーム開発や長期的なプロジェクトでは、技術の成熟度やエコシステムの豊富さも重要な選択要因になるでしょう。
■ Authentication(認証)
Authentication(認証) | Convex公式ドキュメント
Convexの認証システムは、主要な認証プロバイダー(Clerk、Auth0等)との連携を中心として設計されています。OpenID Connect(JWT)をベースとし、バックエンド関数での認証処理がTypeScriptで統一して記述できる点が特徴的です。
また、ベータ版ではありますが、Convex Auth として独自の認証ライブラリも提供しており、将来的には認証からバックエンドまでを統合したアプローチを目指している方向性が見られます。
提供される認証オプション
Convexは複数の認証プロバイダーとの統合をサポートしており、プロジェクトの要件に応じて選択できます。
Convex Auth(ベータ版)
- Convex純正の認証ライブラリ
- 外部サービスへの依存を最小化
- 対応認証方式:マジックリンク・OTP、OAuth(GitHub、Google、Apple)、パスワード認証
- React WebとReact Nativeをサポート
- UIコンポーネントは提供されず(自作必要)
- 現在ベータ版で機能に制限
Clerk統合
- Next.jsとReact Nativeに推奨
- 豊富な認証方式(パスワード、ソーシャルログイン、多要素認証)
- すぐに使える認証UIコンポーネント
- 開発から本番まで一貫したユーザー管理機能
- JWTテンプレートの設定が必要
Auth0統合
- エンタープライズレベルの認証要件に対応
- SSO、高度なMFA、詳細なアクセス制御
- 大規模組織での採用実績が豊富
- 設定の複雑さあり
カスタムOpenID Connect
- 独自の認証システムとの統合が可能
- 柔軟なカスタマイズ対応
Convex Authが目指す統合された開発体験
従来の認証システムでは、認証プロバイダーとバックエンドAPIが分離しており、認証情報を別々に管理する必要がありました。
// 従来のアプローチ
const user = await firebase.auth().currentUser;
const token = await user.getIdToken();
const response = await fetch('/api/data', {
headers: { Authorization: `Bearer ${token}` }
});
// 別々のサービス・APIを管理
Convexでは、認証からデータアクセスまで一貫した書き方で実装できます。
// Convexのアプローチ
export const getUserData = query({
handler: async (ctx) => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) return null;
// APIを介さずに直接データアクセス
return await ctx.db.query("userData").collect();
}
});
技術選択時の考慮ポイント
Convex Authの主なメリットは、統一された開発体験です。認証プロバイダーとバックエンドロジックを別々に管理する必要がなく、関数レベルでの認証制御がctx.auth.getUserIdentity()
という直感的なAPIで実現できる点は、開発効率の向上につながります。
現在はClerkやAuth0といった外部プロバイダーとの連携が中心となるため、これらのサービスへの依存は従来と同様に発生します。Convex Authはベータ版のため、本格的な統合を期待する場合は将来のアップデートを待つ必要があります。
注意点として、Convexプラットフォームへのベンダーロックインのリスクがあります。 認証ロジックがConvex固有のAPIで記述されるため、他のプラットフォームへの移行は困難になる可能性があります。長期的なプロジェクトでは、この点を慎重に検討する必要があります。
TypeScriptを中心とした開発チームや、フロントエンド・バックエンドの境界を意識せずに開発したい場合には適しているでしょう。一方で、複雑なエンタープライズ認証要件(SAML、LDAP統合等)がある場合は、成熟したAuth0などとの直接連携の方が適している場合も多いと思います。
■ Scheduling(スケジューリング)
時間ベースのタスク実行は、多くのWebアプリケーションで必要となる重要な機能です。従来のアプローチでは、cronサーバーの管理やタスクキューの構築など、インフラ面での課題が多く存在していました。Convexは、これらの課題に対してプラットフォーム統合型のアプローチを提供しています。
スケジューリングとは何か
Webアプリケーションでは、「特定の時間に自動的に処理を実行する」機能が頻繁に必要になります。例えば:
- ユーザー登録後に歓迎メールを送る
- 毎日深夜にデータのバックアップを取る
- 未読通知を1時間後にリマインダーとして送信する
- 月末に売上レポートを自動生成する
これらの「時間ベースの自動処理」を実現する仕組みがスケジューリングです。
従来のアプローチとその課題
これまでのWebアプリケーション開発では、時間ベースの処理を実装する際に以下のような課題がありました:
分離されたアーキテクチャ
- cronジョブはOSレベルで設定・管理
- アプリケーションとは別のインフラ管理が必要
- タスクキューサービス(Redis、RabbitMQ)の追加運用
開発体験の複雑さ
- バックエンドコードとcron設定の分離
- ローカル開発環境での再現困難
- エラーハンドリングとリトライロジックの自作
運用面での負担
- 複数のサービス間での実行状態の追跡困難
- 障害時の原因特定とデバッグの複雑さ
- スケーリングとモニタリングの個別対応
Convexのスケジューリングアーキテクチャ
Convexは、これらの課題に対して「データベース統合型スケジューリング」という設計思想でアプローチしています。
統合された開発環境
すべてのスケジューリングロジックがTypeScriptで統一され、アプリケーションコードと同じ環境で管理されます。従来のアプローチでは、cronで外部スクリプトを実行し、APIエンドポイント経由でデータ処理を行い、エラーハンドリングも自作する必要がありました。Convexでは、これらすべてが同じトランザクション内で一貫して処理されます。
耐久性のあるタスク管理
スケジュールされたタスクは、Convexのデータベースに永続化されるため、システム再起動や一時的な障害が発生しても実行が保証されます。これにより、外部のタスクキューサービスを導入する必要がありません。
2つのスケジューリングメカニズム
スケジュール済み関数(Scheduled Functions)
一回限りの遅延実行に特化した仕組みです。「30分後に歓迎メールを送る」「24時間後にリマインダーを送信する」といった、特定の時点での一度だけの処理を簡単に設定できます。ミリ秒単位の精度で将来の実行をスケジューリングでき、データベース操作と同じトランザクション内で処理されるため、確実な実行が保証されます。
Cronジョブ
定期実行のための仕組みです。「毎日午前2時にデータ同期を実行」「15分おきにシステムの健康状態をチェック」といった、継続的な定期処理を設定できます。従来のUnix cronと比べて、TypeScriptで直感的に設定でき、アプリケーションと同じ環境で管理されるため、デバッグや監視が容易になります。
技術選択時の考慮ポイント
メリット
- インフラ運用が不要で開発に集中可能
- トランザクション一貫性による信頼性の高いタスク実行
- ダッシュボードでの統合監視とデバッグ体験
制約事項
- 最大1000個のスケジュール済み関数まで
- 引数サイズは8MB以内
- 実行履歴は7日間のみ保持
■ File Storage(ファイルストレージ)
File Storage(ファイルストレージ) | Convex公式ドキュメント
Webアプリケーションでは、ユーザーがアップロードした画像、PDFドキュメント、動画ファイルなどを安全に保存・配信する機能が必要になります。従来のアプローチでは、AWS S3やGoogle Cloud Storageといった外部サービスの設定や管理が複雑でしたが、Convexは統合されたファイルストレージソリューションを提供しています。
ファイルストレージとは何か
多くのWebアプリケーションでは、以下のようなファイル処理が必要になります:
- ユーザーのプロフィール画像をアップロード・表示する
- PDFや画像ファイルを安全に保存・共有する
- ユーザーがアップロードしたファイルへのアクセス権限を制御する
これらの「ファイルの保存・配信・アクセス制御」を実現する仕組みがファイルストレージです。
従来のアプローチとその課題
これまでのWebアプリケーション開発では、ファイル処理を実装する際に以下のような課題がありました:
分離されたアーキテクチャ
- ファイルストレージ(S3等)とアプリケーションが別々のサービス
- アクセス制御のために複雑な署名付きURLの生成が必要
- CDN設定やキャッシュ戦略の個別管理
開発体験の複雑さ
- ファイルアップロード用の専用エンドポイント作成
- ダウンロード時の権限チェック実装
- エラーハンドリングとリトライロジックの自作
運用面での負担
- 複数のサービス間でのコスト管理
- セキュリティ設定の一貫性確保
- ファイルとデータベースの関連性管理
Convexのファイルストレージアーキテクチャ
Convexは、これらの課題に対して「データベース統合型ファイルストレージ」という設計思想でアプローチしています。
統合された開発環境
ファイルストレージがデータベースと同じConvex環境内で管理されるため、複雑な外部サービス設定が不要になります。ファイルは専用のシステムテーブル「_storage」に保存され、通常のデータベースレコードと同様に扱えます。
シンプルなアクセス制御
従来のアプローチでは署名付きURLの生成や複雑なIAM設定が必要でしたが、Convexではクエリやミューテーション内で直感的にアクセス制御を実装できます。
2つのファイル処理方式
アップロードURL方式
大容量ファイルや一般的なアップロード処理に適した方式です。「アップロードURL生成→ファイル送信→ストレージID保存」の3段階で処理され、ファイルサイズの制限がありません。ユーザーのプロフィール画像や大きなドキュメントファイルのアップロードに適しています。
HTTPアクション方式
より細かい制御が必要な場合に使用する方式です。20MBの制限がありますが、アップロード時のファイル検証やフィルタリング、カスタムヘッダーの設定など、サーバーサイドでの詳細な制御が可能です。
技術選択時の考慮ポイント
Convexはファイルの保存・配信に特化しており、現状、画像変換(リサイズ、フォーマット変換、品質調整)など便利機能は提供されていない印象です。画像の動的変換が必要な場合は、HTTPアクション内でSharpなどのライブラリを使用した処理や、外部サービスとの連携が必要になります。
■ Search(検索)
現代のWebアプリケーションでは、大量のデータから関連する情報を素早く見つける「検索機能」が不可欠です。ユーザーが「チャットの過去メッセージを探す」「商品カタログから目的の商品を見つける」といった場面で、効果的な検索体験が求められます。Convexは、これらのニーズに対して統合された検索ソリューションを提供しています。
Convexの検索アーキテクチャ
Convexは、データベース統合の強みを生かした検索機能が提供されています。
統合された開発環境
検索機能がデータベースと同じConvex環境内で管理されるため、データの同期問題や複雑な設定が不要になります。検索インデックスはスキーマ定義時に作成され、データの変更に自動的に追従します。
リアクティブな検索体験
従来の検索システムでは、データ更新後にインデックス再構築の遅延がありましたが、Convexでは即座に検索結果に反映されます。チャットアプリで新しいメッセージがすぐに検索対象になるような体験が実現できます。
2つの検索アプローチ
テキスト検索(フルテキスト検索)
キーワードマッチングに基づく従来型の検索です。「商品名に『iPhone』を含む」「メッセージに『会議』というワードがある」といった文字列の一致や部分一致で検索します。BM25スコアリングにより関連度順に結果を並べ、タイプアヘッド(入力中の候補表示)機能にも対応しています。
ベクトル検索(セマンティック検索)
意味的類似性に基づく新しい検索アプローチです。「スマートフォン」と検索して「iPhone」「Android」が見つかったり、「料理レシピ」で「パスタの作り方」が検索できるような、言葉の意味を理解した検索が可能です。AIアプリケーションでのRAG(Retrieval Augmented Generation)実装に特に有効です。
【ガイド】
■ AIコード生成
ConvexはAIコーディングを積極的にサポートしています。TypeScript中心の設計や型安全性により、AIが生成するコードの品質を向上させる工夫が随所に見られます。
TypeScript & Convexと、AIコード生成との相性の良さ
ConvexのTypeScriptネイティブ設計は、AIコード生成との相性が良いと言えるでしょう。多くのAIは膨大なTypeScriptコードでの訓練データも多く、Convexコードを生成の精度も高いことが想定されます。
また、ConvexのQuery(読み取り専用)とMutation(読み書き)という明確な関数分類や、型安全性によって、AIが生成するコードの品質向上に寄与している面もあります。自動的なリアクティビティやトランザクション保証といった組み込み機能により、AIが生成したコードでも安定して動作しやすくなっています。
MCPが変える開発体験
Convex MCP(Model Context Protocol)Serverは、AI開発ツールとConvexプロジェクトを直接接続する仕組みです。従来はAIに正確なコードを生成してもらうため、プロジェクトの情報をmarkdownファイルに整理したり、詳細な説明を毎回書いたりする必要がありました。
MCPサーバーを立ち上げると(npx convex@latest mcp start
)、AIツールは以下のような操作が可能になります:
- テーブル情報の確認: どんなテーブルがあるか、スキーマはどうなっているか
- データの参照: テーブル内のデータをページネーション形式で確認
- 関数の実行: 既存のConvex関数をパラメータ付きで実行
- 環境変数の管理: 環境変数の一覧取得、設定、削除
- ワンオフクエリの作成: AIが一時的なクエリコードを書いて実行(読み取り専用なので安全)
ただし、現在はベータ版で、主にCursor(macOS)でテストされており、引数は文字列のみ対応といった制限もあります。Cursor、GitHub Copilot、Windsurfといった主要なAI開発ツールが対応しており、それぞれに最適化された設定ファイルも提供されています。
開発ワークフローの革新
従来のバックエンド開発では「データベース設計→API設計→認証設定→リアルタイム同期設定→テスト→デプロイ」という複雑なプロセスが必要でした。Convexでは、これらの複雑さが大幅に削減され、AIがビジネスロジックに集中できる環境が整っています。
小規模で焦点を絞った変更を重ねながら開発し、頻繁にコミットすることで、AIとの協働がより効果的になります。リアルタイムでのスキーマ変更反映により、「スキーマを変更→再起動→型定義更新→フロントエンド修正」といった手順が不要になり、即座のフィードバックループが実現できるんです。
また、MCPという新しい仕組みにより、AIツールがプロジェクトの文脈を理解し、より適切な提案を行えるようになったことで、AI支援開発の精度と効率は格段に向上します。これは単なる機能追加ではなく、開発体験そのものの革新と言えるでしょう。
■ AIエージェント
ConvexのAIエージェント機能は、単発のAI API呼び出しではなく、状態を保持しながら継続的に動作するAI実体を作成できる機能です。会話履歴やタスクの進行状況を保持し、複数の処理ステップにわたって動作します。
AIエージェントの基本的な仕組み
ConvexのAIエージェントは以下のコンポーネントで構成されています:
- Agent: メッセージ履歴とワークフローを管理する基本単位
- Workflow: 長時間実行される処理を管理(Convex Componentsの機能を活用)
- Tools: エージェントが利用できる外部機能(関数呼び出し、API連携など)
- Chat: OpenAIなどのLLMとの連携
- TextEmbedding: ベクトル検索による情報検索
従来の一回限りのAPI呼び出しと異なり、エージェントは長期間にわたって状態を維持し、サーバー再起動後も処理を継続できます。会話履歴や処理の文脈がConvexのデータベースに自動保存されるため、継続的な対話や複雑なタスク処理が可能になります。
活用例と実装方法
実際の活用例としては、カスタマーサポートでの問い合わせ対応、データ分析の自動化、チャットボット、複数ステップの業務処理自動化などが考えられます。
開発者はエージェントに指示(instructions)、利用可能なツール、チャット機能を設定することで、複雑なAI駆動のワークフローを構築できます。既存のConvexインフラと統合されているため、追加のインフラ管理は不要で、Convexの他の機能(データベース、スケジューリングなど)と組み合わせて使用できます。
■ テスト
Convexは、自動テストと手動テストの両方をサポートしたテストシステムを提供しています。従来のBaaSとは異なり、フロントエンドとバックエンドを分離せずに統合的にテストできる仕組みが特徴です。
2つのテスト手法の使い分け
convex-testライブラリ(モックテスト)
Convexの関数を手軽にテストできるライブラリです。実際のConvexサーバーに接続せず、ローカルで動作するモック(模擬)環境を作成します。Vitestというテストフレームワークと組み合わせて使用し、Query関数やMutation関数が期待通りに動作するかを確認できます。
test("sending messages", async () => {
const t = convexTest(schema);
await t.mutation(api.messages.send, { body: "Hi!", author: "Sarah" });
const messages = await t.query(api.messages.list);
expect(messages).toMatchObject([{ body: "Hi!", author: "Sarah" }]);
});
認証状態のシミュレーションやfetchコールのモックも可能ですが、実際のバックエンド制約は再現されません。
ローカルバックエンドテスト
オープンソース版のConvexバックエンドを使用した、本番環境により近いテストです。実際のバックエンド制約が適用され、データサイズやクエリ制限も本番と同様に動作します。大量のテストデータを使った検証や、クライアント・バックエンドの統合テストに適しています。
ただし、時間制御やランダム性の管理、環境変数のモックなどはできないため、用途に応じて使い分ける必要があります。
従来のBaaSテストとの違い
多くのBaaSプラットフォームでは、フロントエンドとバックエンドのテストを別々に行い、API呼び出しをモックする必要がありました。Convexでは、Query関数の自動リアクティブ性やMutation関数のトランザクション性も含めて、統合的にテストできます。
これにより、「データが変更されたときに画面が自動更新されるか」「複数の操作が一貫して実行されるか」といった、実際のユーザー体験により近い検証が可能になります。
■ 本番環境
Convexの本番環境運用は、従来のBaaSと比べて「デプロイメントの安全性」に重点を置いた設計になっています。後方互換性を重視し、既存のクライアントアプリを壊さずにバックエンドを更新できる仕組みが特徴です。
主要ホスティングサービスとの統合
Convexは主要なホスティングプラットフォームとの連携に対応しており、モダンな開発ワークフローにスムーズに組み込めます:
- Vercel: Gitリポジトリ連携で自動デプロイ、ビルドコマンド設定で同期デプロイ
- Netlify: 同様の設定で継続的デプロイメント、プレビューデプロイメント対応
- GitHub Pages: 静的ホスティング向けのカスタム設定
- カスタムホスティング: 独自インフラとの柔軟な統合
プレビューデプロイメント機能(Proプラン)では、ブランチごとに独立したConvexバックエンドが作成され、本番環境に影響を与えずに変更をテストできます。
監視・ログ・デバッグ
Convexは本番環境での運用を支援する包括的な監視機能を提供しています:
ログとモニタリング
- ダッシュボード: 関数実行状況、パフォーマンス統計、エラー追跡をリアルタイム表示
- ログストリーム: Axiom、Datadog、カスタムWebhookへの外部ログ送信(Proプラン)
- 例外報告: SentryやDatadog Error Trackingとの自動連携(Proプラン)
デバッグ支援
- 関数実行ログの詳細表示(実行時間、引数、戻り値)
- エラー発生時の自動メタデータ付与(関数名、ユーザーID、リクエスト情報)
- プレビューデプロイメントでの安全なテスト環境
データ統合
- ストリーミングエクスポート: Fivetran、Airbyteとの連携で分析・機械学習用途(Proプラン)
- データインポート: 既存システムからの移行支援(全プラン対応)
プランと制限事項
Starterプラン(小規模チーム向け)
- 開発者1-6名、プロジェクト20個
- 月間100万回の関数呼び出し
- ストレージ0.5GiB、帯域幅1GiB/月
Professionalプラン(成長企業向け)
- 開発者1-20名、プロジェクト100個
- 月間2500万回の関数呼び出し
- ストレージ50GiB、帯域幅50GiB/月
- 監視・ログ機能、プレビューデプロイメント対応
技術的制限
- ドキュメントサイズ最大1MiB、最大1024フィールド
- テーブルあたり最大32インデックス
- 関数実行時間:Query/Mutation 1秒、Action 10分
おまけ:日本語音声で学習
まだ英語のコンテンツが多いConvexですが、NotebookLMで音声化したものを作ってみました:
(音声のみ)
参照元の動画:
- What is Convex & Why Should Developers Care?(Convexとは何か&なぜ開発者が注目すべきか)
- Why I use Convex over Supabase as my BaaS(なぜ私はBaaSとしてSupabaseではなくConvexを選んだのか)
- Convex Chef: 最速かつ無料でハイエンドのフルスタックアプリケーションを作成
移動中にでも聞いてみてください。私も何度か聞いてますが、結構分かりやすくまとまってる印象です。
まとめ
公式ドキュメントを一通り読んでみて、ConvexがBaaS業界に持ち込もうとしているアプローチがなんとなく見えてきました。
既存のFirebaseやSupabaseが「データベース + API + α」という構成なのに対して、Convexは「TypeScript統合型プラットフォーム」として差別化を図っている印象ですね。特にリアクティブシステムが標準装備されているのは、チャットアプリやリアルタイムツールを作る際には大きなアドバンテージになりそうです。
MCPサポートなど、AI開発時代を意識した機能も良い取り組みだと思います。他のツールもどんどん似た状態に整えていくと思いますけれどね。
BaaS選択肢が増えるのは開発者にとって良いことですし、TypeScript中心のエコシステムが充実していけば、モダンな開発スタイルにフィットする場面も多いはず。
この記事でConvexに興味を持った方、ぜひ一緒に試してみましょう!
最後まで読んでいただき、ありがとうございました🙇♂️
Discussion