stackbook

← 作るもの

SaaS・Web API

B2Bの自社サービス、公開API

条件DB中心 · PaaS · 1〜2人 · MVP · 制約なし

推奨:TypeScript

推奨

TypeScript

  • 少人数なのでフロントと同じTypeScriptに揃える(§2-10 手順3)

構成行を開くと詳細(乗り換える条件・根拠・費用・習熟度)

フロントNext.js+shadcn/ui+TanStack Query

Next.js

公式サイト ↗

既定:アプリ(SSR・フルスタック)フロントエンド

乗り換える条件

  • TanStack StartVercel依存を避けたい、クライアント主体で型安全なルーティングを重視するとき
  • React Router(フレームワークモード)Remix系の資産があるとき

代替:画面Elixir(BEAM)

既定は Phoenix LiveView(サーバー主導でリアルタイムUI)。フロントをReactで作りたいとき に乗り換える。

代替:静的サイト・コンテンツ中心フロントエンド

既定は Astro。同じリポジトリでアプリ部分も持つとき に乗り換える。

代替:同一リポジトリ内のフロント⇔バック(TS同士)API設計

既定は Hono RPC。Next.jsの中で完結し、別プロセスのAPIを持たないとき に乗り換える。

成長したら → ECS/Cloud Run(コンテナ)§24

きっかけ
費用の増加、AWSに集約したい
最初からの備え
Next.jsのstandalone出力でコンテナ化できる状態を保つ。Vercel固有の機能への依存を最小にする

ケース別の構成§19

  • EC(独自要件が多い)フロント:Next.js+shadcn/ui
  • 自社SaaS(B2B)フロント:Next.js+shadcn/ui+TanStack Query
  • toCサービス(Web+モバイル)Web:Next.js
  • AI/LLMプロダクトフロント:Next.js(ストリーミング表示)
  • 個人開発・MVPTS全部入り:Next.js+Supabase+Vercel

習熟度

shadcn/ui

公式サイト ↗

既定:UIコンポーネントフロントエンド

乗り換える条件

  • Mantineコンポーネントを一式そのまま使いたい管理画面
  • MUIMaterial Design指定のとき

ケース別の構成§19

  • EC(独自要件が多い)フロント:Next.js+shadcn/ui
  • 業務システム・社内ツール(TypeScript構成)UI:shadcn/ui+TanStack Table(編集が重いならAG Grid)
  • 自社SaaS(B2B)フロント:Next.js+shadcn/ui+TanStack Query

TanStack Query

公式サイト ↗

既定:サーバー状態(API取得・キャッシュ)フロントエンド

乗り換える条件

  • SWRVercel系の小規模案件

ケース別の構成§19

バックエンドHono(軽量・どこでも動く・型安全なRPC)

Hono

公式サイト ↗

既定:HTTPフレームワークTypeScript(Node.js)

乗り換える条件

  • NestJS10人以上のチームでDI・モジュール構造を強制したいとき
  • FastifyNode専用で既存プラグイン資産を使いたいとき

ケース別の構成§19

  • 業務システム・社内ツール(TypeScript構成)API:Hono(RPCでフロントと型共有)
  • 自社SaaS(B2B)バックエンド:Go(net/http+sqlc+pgx)。少人数ならHono
  • toCサービス(Web+モバイル)バックエンド:Hono(またはGo)
  • 個人開発・MVPエッジ:Hono+Cloudflare Workers+D1/R2

習熟度

API@hono/zod-openapi(Zodスキーマからルートと仕様を同時に定義)
DBPostgreSQL(テナントIDカラム+Row Level Security)

PostgreSQL

公式サイト ↗

既定:RDBDB本体とホスティング

乗り換える条件

  • MySQL既存システムとの互換が必要なときのみ

採用の根拠§22-2

OSSでライセンス費用がかからない。AWS、GCP、Azureを含む主要クラウドがすべてマネージド版を提供している。拡張機能(pgvector、pg_bigm)でベクトル検索や日本語全文検索までこなせるため、専用DBを増やさずに済む

「MySQLの方が一般的では」→ 機能・標準SQLへの準拠・拡張性で優位。移行ツールも揃っている

ケース別の構成§19

  • 業務システム・社内ツール(Rails構成)DB:PostgreSQL
  • 業務システム・社内ツール(TypeScript構成)DB:PostgreSQL+Drizzle
  • 自社SaaS(B2B)DB:PostgreSQL(テナントIDカラム+Row Level Security)
  • AI/LLMプロダクトDB・ベクトル:PostgreSQL+pgvector
  • 個人開発・MVPGo単体:Go+PostgreSQL+htmx

習熟度

ジョブpg-boss(Postgresベース、§4-3)

pg-boss

公式サイト ↗

既定:ジョブキューTypeScript(Node.js)

乗り換える条件

  • BullMQ(Redis/Valkey)秒間数百件を超える、またはValkeyが既にあるとき(§23-1)
  • Inngest/Trigger.devサーバーレス環境でワークフロー(リトライ・待機・ステップ実行)が必要なとき

ケース別の構成§19

  • 業務システム・社内ツール(TypeScript構成)ジョブ:BullMQ+Valkey(またはpg-boss)
認証Clerk(SSO/SCIMが必要になったらWorkOS)

Clerk

公式サイト ↗

既定:マネージド(toC・スタートアップ)認証・認可

乗り換える条件

費用の注意§25

主な課金の軸
月間アクティブユーザー数
膨らみやすい要因
toCでユーザーが急増
対策
規模が見えたら §24 の移行パスを検討する

成長したら → 他のIdP・自前認証§24

きっかけ
費用の増加、要件がClerkの範囲を超えた
最初からの備え
OIDCの標準仕様で連携する。ユーザー情報の正本は自前のDBに持つ

ケース別の構成§19

  • 自社SaaS(B2B)認証:Clerk(SSO/SCIMが必要になったらWorkOS)
  • toCサービス(Web+モバイル)DB・認証・ストレージ:Supabase(小〜中規模)/ RDS+Clerk+S3(中規模以上)

習熟度

課金Stripe Billing

Stripe

公式サイト ↗

既定:カード決済・サブスク(汎用)決済

採用の根拠§22-2

カード情報を自社システムで扱わずに済み、PCI DSSの対応範囲を最小にできる。国内の決済手段(コンビニ払い等)はKOMOJUで補える

「手数料が高い」→ 自前でカード情報を扱う場合のセキュリティ対策・監査コストと比べて判断する

費用の注意§25

主な課金の軸
決済額に対する手数料率
対策
決済手段ごとの料率を事前に確認する

ケース別の構成§19

  • EC(独自要件が多い)決済:Stripe+KOMOJU(国内決済手段)
  • 自社SaaS(B2B)課金:Stripe Billing

習熟度

監査ログ専用テーブルに追記のみで記録
インフラECS on Fargate+RDS+Terraform

ECS on Fargate

公式サイト ↗

既定:AWSを使うどこで動かすか

乗り換える条件

  • Lambdaリクエストがまばらでコールドスタートを許容できるとき
  • ECS Express Mode構成を最小にしたい小規模案件

App Runnerは新規受付を終了したため選ばない

費用の注意§25

主な課金の軸
vCPU・メモリの稼働時間
膨らみやすい要因
過大なタスクサイズ、最小タスク数の設定しすぎ
対策
実測に合わせて調整する。検証環境はSpotを使う

ケース別の構成§19

  • EC(独自要件が多い)インフラ:ECS on Fargate、Cloudflare(CDN・WAF・Waiting Room)
  • 業務システム・社内ツール(TypeScript構成)デプロイ:Render(AWSならECS on Fargate、オンプレならコンテナでVM)
  • 自社SaaS(B2B)インフラ:ECS on Fargate+RDS+Terraform
  • データ基盤・バッチ実行:RenderのCron Job(AWSならECSのスケジュールタスク)

習熟度

RDS

公式サイト ↗

既定:AWSを使うどこで動かすか

乗り換える条件

  • Lambdaリクエストがまばらでコールドスタートを許容できるとき
  • ECS Express Mode構成を最小にしたい小規模案件

App Runnerは新規受付を終了したため選ばない

ケース別の構成§19

  • EC(独自要件が多い)DB:RDS for PostgreSQL
  • 自社SaaS(B2B)インフラ:ECS on Fargate+RDS+Terraform
  • toCサービス(Web+モバイル)DB・認証・ストレージ:Supabase(小〜中規模)/ RDS+Clerk+S3(中規模以上)

Terraform

公式サイト ↗

既定:IaC本体IaC

乗り換える条件

  • AWS CDKAWS専用でTypeScriptで書きたいとき
  • Pulumi複数クラウドを汎用言語で書きたいとき

採用の根拠§22-2

開発・検証・本番で同じイメージを使えるため、環境差による不具合が起きにくい。クラウド移行時もコードから再構築できる

「学習コストが高い」→ テンプレート化しており、案件ごとの差分は小さい

ケース別の構成§19

習熟度

分析・機能フラグPostHog

PostHog

公式サイト ↗

既定:プロダクト分析・セッションリプレイ・機能フラグプロダクト分析・機能フラグ

乗り換える条件

既定:Webサイトのアクセス解析プロダクト分析・機能フラグ

乗り換える条件

  • Cloudflare Web Analytics静的サイトでCookieなしの最小限の計測だけ欲しいとき
  • Plausibleセルフホストもできる軽量な解析が欲しいとき
  • GA4取引先やマーケティング担当がGA4のレポートを求めるとき

既定:機能フラグ(単独)プロダクト分析・機能フラグ

乗り換える条件

  • Unleashセルフホスト
  • OpenFeatureベンダーを差し替えられるようにしたいとき

ケース別の構成§19

  • 自社SaaS(B2B)分析・機能フラグ:PostHog
  • toCサービス(Web+モバイル)分析:PostHog
  • モバイルアプリ単体分析:PostHog

習熟度

監視Sentry+OpenTelemetry+Grafana Cloud

Sentry

公式サイト ↗

既定:エラー監視監視・可観測性・運用

既定:RUM(実ユーザーの表示速度)監視・可観測性・運用

乗り換える条件

既定:エラー時のユーザー問い合わせプロダクト分析・機能フラグ

採用の根拠§22-2

障害の検知と原因特定の時間を短縮できる。計装をOpenTelemetryにしておけば、監視サービスを後から変更できる

「費用がかかる」→ 無料枠・サンプリングで調整できる。障害の長期化による損失の方が大きい

費用の注意§25

主な課金の軸
エラー数、トレースのスパン数、セッションリプレイ数、ログ量
膨らみやすい要因
同じエラーの大量発生、トレースの全量送信
対策
トレースのサンプリング率を設定する。既知のノイズを除外する

ケース別の構成§19

  • EC(独自要件が多い)監視:Sentry+Grafana Cloud
  • 自社SaaS(B2B)監視:Sentry+OpenTelemetry+Grafana Cloud
  • AI/LLMプロダクト監視:Sentry+OpenTelemetry
  • データ基盤・バッチ監視:Sentry(Cron Monitoringで実行漏れを検知)
  • モバイルアプリ単体監視:Sentry

習熟度

OpenTelemetry

公式サイト ↗

既定:計装Elixir(BEAM)

既定:計装(トレース・メトリクス)監視・可観測性・運用

採用の根拠§22-2

障害の検知と原因特定の時間を短縮できる。計装をOpenTelemetryにしておけば、監視サービスを後から変更できる

「費用がかかる」→ 無料枠・サンプリングで調整できる。障害の長期化による損失の方が大きい

ケース別の構成§19

習熟度

Grafana Cloud

公式サイト ↗

既定:可観測性基盤(コスト重視)監視・可観測性・運用

乗り換える条件

  • セルフホストのGrafanaスタックオンプレ要件

ケース別の構成§19

  • EC(独自要件が多い)監視:Sentry+Grafana Cloud
  • 自社SaaS(B2B)監視:Sentry+OpenTelemetry+Grafana Cloud

§19-6の構成を、選んだ条件に合わせて一部差し替えている

構成図 自社SaaS(B2B)

flowchart TB
  U["利用企業"] --> FE["Next.js"]
  FE --> CL["Clerk/WorkOS"]
  FE -- "OpenAPI" --> API["Go API<br/>ECS Fargate"]
  API --> DB[("PostgreSQL<br/>RLS でテナント分離")]
  API --> RV["River ワーカー"] --> DB
  API --> ST["Stripe Billing"]
  API --> OT["OpenTelemetry"] --> GF["Grafana Cloud"]

最初に決めること:マルチテナントの分離方式、SSO対応の時期、監査ログの範囲。

作り始める

共通の準備

# 言語・ツールのバージョン固定(使う言語だけ)
mise use node@lts pnpm@latest
mise use go@latest
mise use ruby@latest
mise use python@latest uv@latest

# Gitフックと依存更新
pnpm add -D lefthook && pnpm exec lefthook install
# renovate.json を置き、GitHubでRenovateアプリを有効化する

自社SaaS・Goバックエンド(§19-6)

mkdir api && cd api
go mod init example.com/app/api
go install github.com/sqlc-dev/sqlc/cmd/sqlc@latest
go install github.com/pressly/goose/v3/cmd/goose@latest
go install github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@latest
go get github.com/jackc/pgx/v5 github.com/riverqueue/river
sqlc init
goose -dir db/migrations create init sql

次に読む