個人でSaaSを開発しようとしたとき、最初の大きな壁となるのが技術スタックの選定です。2025年現在、フロントエンド・バックエンド・データベース・認証・デプロイの各レイヤーで多くの選択肢があり、それぞれにトレードオフがあります。この記事では、1人または少人数チームで個人SaaSを開発・運用する観点から、各カテゴリの選択肢を比較し、具体的な判断基準を提示します。
フロントエンド:Next.js vs Remix vs Astro
2025年現在のフロントエンドフレームワークの三強は、Next.js、Remix、Astroです。それぞれ設計思想が大きく異なり、ユースケースによって適切な選択が変わります。
- Next.js 15: フルスタック対応、Server Components・Server Actions、Vercelとの最高の相性、最も大きなエコシステム。学習コストは中程度。
- Remix: Web標準(FormData、fetch、etc)ファースト、優れたエラーバウンダリ、Nested Routing。学習コストは高め。
- Astro: コンテンツサイト最適化、Islands Architecture(部分的にReact/Vue等を使用可能)、最小限のJS配信。ブログやドキュメントサイトに最適。
個人SaaS開発の判断基準としては、ダッシュボード・ユーザー管理・APIを含む本格的なWebアプリにはNext.js、コンテンツ主体のサービスにはAstro、Web標準への強いこだわりがある場合はRemixを選択するのが無難です。エコシステムの大きさと情報量からNext.jsが無難な選択肢ですが、Astroは静的コンテンツ比率が高いサービスでは圧倒的なパフォーマンス優位性があります。
// Next.js 15のServer Actions - 個人SaaSで典型的なパターン
'use server'
import { revalidatePath } from 'next/cache'
import { redirect } from 'next/navigation'
import { auth } from '@/lib/auth'
import { db } from '@/lib/db'
export async function createProject(formData: FormData) {
const session = await auth()
if (!session?.user) redirect('/login')
const name = formData.get('name') as string
const description = formData.get('description') as string
const project = await db.project.create({
data: {
name,
description,
ownerId: session.user.id,
},
})
revalidatePath('/dashboard')
redirect(`/projects/${project.id}`)
}
// Astroのコンテンツコレクション - ブログ型SaaSに最適
// src/content/config.ts
import { z, defineCollection } from 'astro:content'
const blogCollection = defineCollection({
type: 'content',
schema: z.object({
title: z.string(),
publishedAt: z.date(),
tags: z.array(z.string()),
draft: z.boolean().default(false),
}),
})
export const collections = { blog: blogCollection }バックエンド:Hono vs Express vs tRPC
Next.jsのAPI Routesを使う場合はバックエンドフレームワークが不要なケースも多いですが、独立したAPIサーバーが必要な場合の選択肢を比較します。
- Hono: 超軽量・高速(Cloudflare Workers等のEdge環境でも動作)、Web標準準拠、TypeScript Firstの設計。モダンなREST APIに最適。
- Express: 15年以上の実績、最大のエコシステム、豊富なミドルウェア。しかしTypeScript対応が弱く、モダン非同期処理との相性が悪い。
- tRPC: TypeScript型安全なRPC、フロントエンドとバックエンドの型共有が自動化。Next.jsとの相性が抜群だが、型以外のクライアントとは使いにくい。
// Honoを使ったAPI(Cloudflare WorkersやBunで実行可能)
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'zod'
const app = new Hono()
const createUserSchema = z.object({
name: z.string().min(1).max(100),
email: z.string().email(),
})
app.post('/api/users',
zValidator('json', createUserSchema),
async (c) => {
const { name, email } = c.req.valid('json')
// データベース処理
const user = await createUser({ name, email })
return c.json({ success: true, data: user }, 201)
}
)
export default app
// tRPCのルーター定義(Next.jsと完全な型共有)
import { z } from 'zod'
import { createTRPCRouter, protectedProcedure } from '@/lib/trpc'
export const projectRouter = createTRPCRouter({
list: protectedProcedure.query(async ({ ctx }) => {
return ctx.db.project.findMany({
where: { ownerId: ctx.session.user.id },
orderBy: { createdAt: 'desc' },
})
}),
create: protectedProcedure
.input(z.object({ name: z.string().min(1), description: z.string() }))
.mutation(async ({ ctx, input }) => {
return ctx.db.project.create({
data: { ...input, ownerId: ctx.session.user.id },
})
}),
})データベース:Supabase vs PlanetScale vs Neon
個人SaaSにとって、データベースの選択はコストと機能のトレードオフが最も重要です。それぞれのサービスの特徴を整理します。
- Supabase: PostgreSQL + 認証 + ストレージ + リアルタイム。無料プランが充実(500MB DB、認証、1GB ストレージ)。フルスタックBaaSとして最もコスパが良い。
- PlanetScale: MySQL + GitOpsライクなスキーマ変更。スケーラビリティが高い。無料プランが縮小され個人開発には割高になった。
- Neon: サーバーレスPostgreSQL + ブランチ機能。無料プランあり(0.5GB)。コールドスタートがある点に注意。
個人SaaSの初期段階ではSupabaseが最もコスパが良い選択です。認証・ストレージ・データベース・リアルタイムが1つのサービスで完結し、無料プランでも多くの機能が使えます。スケール後にコストを最適化したい場合はNeonやRDSへの移行を検討します。
認証:NextAuth vs Supabase Auth vs Clerk
認証は実装が複雑でバグが起きやすいため、できる限り信頼できるライブラリやサービスに任せることが重要です。
- NextAuth(Auth.js): オープンソース、完全自己ホスト可能、50以上のOAuthプロバイダー対応。Next.jsとの親和性が高いが設定が複雑。
- Supabase Auth: Supabaseとの完全統合、RLSとの連携が強力、メール/SNS/MFA対応。Supabaseを使う場合はこれ一択。
- Clerk: 最も簡単に使える認証サービス、UIコンポーネント付き、MFA・パスキー・オーガニゼーション機能が豊富。月間アクティブユーザー10,000人まで無料(2025年時点)。
// Clerk を使った認証(最もシンプル)
// middleware.ts
import { clerkMiddleware, createRouteMatcher } from '@clerk/nextjs/server'
const isProtectedRoute = createRouteMatcher(['/dashboard(.*)', '/api/(.*)'])
export default clerkMiddleware((auth, req) => {
if (isProtectedRoute(req)) auth().protect()
})
// app/dashboard/page.tsx
import { auth, currentUser } from '@clerk/nextjs/server'
export default async function DashboardPage() {
const { userId } = auth()
const user = await currentUser()
if (!userId || !user) return null
return (
<div>
<h1>こんにちは、{user.firstName}さん</h1>
</div>
)
}
// Auth.js (NextAuth) を使った認証(カスタマイズ性が高い)
// app/api/auth/[...nextauth]/route.ts
import NextAuth from 'next-auth'
import GitHub from 'next-auth/providers/github'
import { PrismaAdapter } from '@auth/prisma-adapter'
import { prisma } from '@/lib/db'
export const { handlers, auth, signIn, signOut } = NextAuth({
adapter: PrismaAdapter(prisma),
providers: [GitHub],
callbacks: {
session: ({ session, user }) => ({
...session,
user: { ...session.user, id: user.id },
}),
},
})デプロイ:Vercel vs Fly.io vs Railway
デプロイ先の選択は、コスト・スケーラビリティ・開発体験のバランスで決まります。個人開発の初期段階と成長後で最適解が変わることも考慮が必要です。
- Vercel: Next.js開発元のホスティング、最高のDX(プレビューデプロイ、自動SSL)、Edge Network、無料プランあり。本番商用利用はProプランが必要(月$20)。
- Fly.io: Dockerベースのデプロイ、グローバル展開が容易、無料枠あり。バックエンドサービスやDBのホスティングに最適。
- Railway: GitHubとの簡単な連携、PostgreSQL/Redisのホスティングも可能、従量課金で月$5から。小規模サービスのオールインワン展開に向く。
// Fly.ioのDocker設定(Honoサーバーのデプロイ例)
// Dockerfile
// FROM oven/bun:1 AS base
// WORKDIR /usr/src/app
//
// FROM base AS install
// COPY package.json bun.lockb ./
// RUN bun install --frozen-lockfile
//
// FROM base AS release
// COPY --from=install /usr/src/app/node_modules node_modules
// COPY . .
// USER bun
// EXPOSE 3000/tcp
// ENTRYPOINT [ "bun", "run", "src/index.ts" ]
// fly.toml
// app = "my-saas-api"
// primary_region = "nrt" // 東京リージョン
//
// [http_service]
// internal_port = 3000
// force_https = true
// auto_stop_machines = true
// auto_start_machines = true
// min_machines_running = 0 // コスト削減:使われていない時は0台に
// next.config.ts - Vercelへのデプロイ最適化
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
// 静的ページの最大限の活用
experimental: {
// PPR (Partial Prerendering) - Next.js 15の実験的機能
ppr: true,
},
images: {
// 外部画像ドメインの許可
remotePatterns: [
{ protocol: 'https', hostname: '**.supabase.co' },
],
},
}
export default nextConfigコスト比較と個人開発での最適解
月間ユーザー数が1,000人未満の初期段階における推定月額コストを比較します。以下はあくまで目安です。
- 最小コスト構成: Next.js(Vercel Hobby無料)+ Supabase(無料)+ Clerk(無料)→ 月$0
- スタンダード構成: Next.js(Vercel Pro $20)+ Supabase(Pro $25)+ Clerk(無料)→ 月$45
- 独立バックエンド構成: Next.js(Vercel)+ Hono API(Fly.io $5)+ Neon($19)+ Clerk → 月$50〜
実際の選定フロー
技術スタックの選定では、以下のフローで判断することをお勧めします。まず作るものの性質を見極め、次にチームのスキルセット、最後にコストとスケーラビリティを考慮します。
- 1SaaSのコア機能を明確にする(リアルタイム機能が必要か、コンテンツ主体か、トランザクションが多いか)
- 2既存の経験を活かせるスタックを優先する(学習コストは開発速度に直結する)
- 3無料プランで始められる構成を選ぶ(PMFを確認するまでコストを最小化)
- 4スケール時の移行コストを考慮する(ロックインリスクを把握しておく)
- 5コミュニティと情報量を確認する(困ったときに情報が見つかるか)
ℹ️ 情報
2025年の個人SaaSにおける最も人気のある構成は「Next.js + Supabase + Clerk + Vercel」です。この構成は学習コスト・開発速度・コストのバランスが良く、多くの個人開発者が選択しています。迷ったらこの構成から始め、ボトルネックが見えてから最適化するアプローチが最も実践的です。