個人開発の技術スタックをCloudflareで統一した理由

前回の記事では、作るサービスを選ぶ6つの基準を決めました。 今回は、それらのサービスを何で作るかです。これから作るサービスすべてに共通する技術スタックを決めたので、その中身と選んだ理由をまとめます。 (2026年9月時点の方針です)


全体像

領域 採用するもの
フレームワーク SvelteKit(Svelte 5)
言語 TypeScript(strict)
画面のスタイル Tailwind CSS v4 + 個別のCSS
インフラ Cloudflare Workers
DB Cloudflare D1 + Drizzle ORM
キーバリュー Workers KV(補助用)
ストレージ Cloudflare R2
認証 最初は Cloudflare Access → 必要になったら Better Auth
決済 Stripe
テスト Vitest + Playwright
ソース管理・デプロイ GitHub + GitHub Actions
開発スタイル Claude Code でのバイブコーディング

ひと言でいえば、SvelteKitで作って、Cloudflareに全部乗せる構成です。


選んだ一番の理由:70代まで1人で面倒を見られること

前回決めた基準の中に、「1人で、70代になっても運用し続けられる規模」というものがあります。技術スタックも、この基準を一番に考えて選びました。

1か所にまとまっている

インフラ・DB・ストレージ・キーバリュー・認証の保護まで、すべてCloudflareの中で完結します。 管理画面も請求も1つにまとまるので、「あれはどこの設定だったか」と迷うことがありません。10年後の自分が見ても把握しやすい構成にしておきたい、というのが一番の理由です。

サーバーの管理がいらない

どれもCloudflareが管理するサービスなので、OSの更新やサーバーの監視を自分でする必要がありません。前回の基準にある「マネージドサービスで運用負荷を下げる」を、そのまま形にした構成です。

無料枠が広い

個人の小さなサービスなら、無料枠の範囲に収まる見込みが高い構成です。成功の基準の1つを「サーバー代を賄えること」にしているので、そもそものサーバー代が小さいことは大きな助けになります。

特定のサービスに依存しすぎないか

全部をCloudflareに乗せることに、不安がないわけではありません。 ただ、D1の中身はSQLite、R2はS3と互換性のあるAPIを持っています。いざというときは、データを持って他のサービスへ移ることもできます。依存のリスクより、1か所で管理できる利点のほうが大きいと判断しました。


それぞれの選定理由

SvelteKit + TypeScript

書くコードの量が少なく、AIが生成したコードでも読みやすいのが決め手です。 開発はClaude Codeでのバイブコーディングを基本にしますが、将来保守するのは自分です。AIが書いたコードでも、自分が読んで理解できることを重視しました。

言語は、あえてTypeScriptと明記しています。SvelteKitはJavaScriptでも作れるので、フレームワーク名だけでは言語は決まりません。型チェックを厳しめ(strict)にしておくと、AIが生成したコードの誤りにも気づきやすくなります。

D1 + Drizzle ORM

作るサービスのデータは、「プランとギアの組み合わせ」のように、テーブル同士の関係があるものが中心になりそうです。そのため、メインのDBにはリレーショナルなD1を選びました。

D1の操作にはDrizzle ORMを使います。テーブル定義とマイグレーションをTypeScriptで管理でき、型があるので、ここでもAIが書いたコードの誤りに気づきやすくなります。

Workers KVは補助に

KVは、セッションやキャッシュ、設定値の置き場所として使います。 検索や結合ができないことと、書き込みが全体に反映されるまで時間がかかることがあるため、メインのDBには使いません。

R2

画像などのファイル置き場です。R2は、データを取り出すときの通信料がかからないので、画像を多く表示するページでも費用を気にせずに済みます。

Tailwind CSS v4 + 個別のCSS

画面のスタイルはTailwind CSS v4を基本にします。

家計簿アプリを作ったとき、画面がどうも業務システムっぽく見えるのが気になっていました。原因を考えてみると、Tailwindそのものではなく、見た目があらかじめ決まっている部品集(flowbite-svelte)をそのまま使っていたことでした。Tailwind自体は、見た目の好みを持たない道具です。

そこで今回は、色・フォント・角丸などをサービスごとにTailwind v4の @theme で定義して使います。Tailwindで書きにくい演出などは、Svelteの <style> に個別のCSSを書きます。個人開発なので、見た目にもこだわっていきたいと思っています。

認証は段階的に

最初は Cloudflare Access で、アプリ全体を保護します。コードを書かずに、決まった人だけがアクセスできるようにできます。自分や身近な人だけで使う間は、これで十分です。まだ使ったことがないので、試すのも楽しみにしています。

ベータ公開などで一般の利用者に使ってもらう段階になったら、家計簿アプリでも使ったBetter Authを導入します。

決済はStripeに任せる

有料プランを作るときは、Stripeを使います。カード情報などを自分のサービスで持たずに済むので、「個人情報や決済情報をできるだけ持たない」という基準にも合います。


テストの道具

テストは、VitestとPlaywrightの2つを使い分けます。

  • Vitest:関数単体のテストと、サーバー側の処理とDBを組み合わせた結合テスト。Cloudflare公式のWorkers向けテスト環境と組み合わせると、ローカルのD1を使って確かめられます
  • Playwright:ブラウザで操作したときの動き(E2E)。主要な操作の流れだけに絞ります

家計簿アプリでは、後半にPlaywrightを入れたことで、ユニットテストでは見つからない不具合をいくつも見つけられました。個人開発でも、主要な流れだけならやりすぎにはならないと考えています。 テストをどう書き、どう回していくかは、次回の開発プロセスの記事で書きます。


開発用と本番用で環境を分ける

Cloudflareのアカウントは、開発用と本番用の2つを持っています(本番用は個人事業用に作ったアカウントです)。 そこで、GitHubのブランチと対応させて、デプロイ先を自動で切り替えることにしました。

ブランチ デプロイ先
develop 開発用アカウント
main 本番用アカウント

仕組みは、GitHub Actionsの Environments(環境) という機能を使います。

on:
  push:
    branches: [develop, main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    environment: ${{ github.ref_name == 'main' && 'production' || 'development' }}
    steps:
      # テスト → D1マイグレーション → デプロイ

GitHubに development と production の2つの環境を作り、それぞれにそのアカウント用のAPIトークンを登録します。ワークフローはブランチ名を見て、使う環境を選びます。 トークンがアカウントごとに別なので、開発用のトークンで本番を壊してしまう心配がありません。

Workers BuildsではなくGitHub Actionsにした理由

Cloudflareには、GitHubと連携して自動でデプロイしてくれる Workers Builds という仕組みもあります。設定が簡単で、APIトークンの管理もいらないので、こちらも魅力的でした。

それでもGitHub Actionsを選んだのは、次の理由からです。

  • PRごとにテストを自動で走らせる仕組みは、どちらにしても必要になる。デプロイも同じ場所にまとめれば、管理する仕組みが1つで済む
  • 設定がYAMLとしてリポジトリに残るので、2つ目以降のサービスにもそのまま流用できる
  • Claude Codeが gh コマンドでCIのログを読めるので、「CIが落ちたから直して」と頼める

環境を分けるときの注意点

  • D1やR2のIDはアカウントごとに違うので、wranglerの設定ファイルで環境ごとに書き分ける
  • 開発用アカウントの workers.dev のURLはそのままだと誰でも見られるので、開発環境にもCloudflare Accessをかける
  • Stripeなどの鍵も、開発はテスト用、本番は本番用と分けて登録する

バックアップとログ

  • バックアップ:D1のTime Travel(一定期間内の任意の時点に戻せる機能)に加えて、wrangler d1 export で定期的にエクスポートしておく
  • ログ:まずはWorkersに標準で付いているログ機能から始め、足りなくなったら追加する

おわりに

選んだ道具を並べてみると、ほとんどが家計簿アプリで一度使ったものです。家計簿アプリのシリーズは、結果的にこのスタックの練習になっていました。 新しく試すのは、Cloudflare Accessと、開発・本番の2アカウント構成くらいです。

1つ目のアプリで、認証・決済・DB・デプロイの仕組みを一度作っておけば、2つ目以降はそのまま流用できます。サービスが増えても、覚えることと保守するものが増えにくい。これも、長く1人で続けるための工夫の1つです。

次回は、この道具を使ってどう開発を進めていくか、個人開発の開発プロセスについて書く予定です。

← トップページに戻る