2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【初心者完全版】0から Next.js 15 + Claude Code で SaaS を2時間で作る最強チュートリアル

2
Posted at

Next.js 15とClaude Codeを使えば、認証・DB・CRUD・デプロイまで揃ったSaaSの雛形が、初心者でも2時間で動く。この記事は完全ノーカットの手順書だ。題材は「シンプルなメモ管理SaaS」。ユーザー登録してログインし、自分のメモをCRUDし、本番URLで動くところまで持っていく。

前提は次の2つだけ。

  • Node.js 20以上(node -vで確認)
  • Claude Codeがインストール済み(claude --versionで確認)

使うスタックはNext.js 15(App Router) + Clerk(認証) + Neon(PostgreSQL) + Drizzle ORM + Vercel(デプロイ)。全て無料枠で足りる。

ステップ1: プロジェクト作成(所要5分)

npx create-next-app@latest memo-saas --typescript --app --tailwind --eslint --src-dir --import-alias "@/*"
cd memo-saas

インタラクティブな問いに対しては全てデフォルト(Yes)で進めて構わない。完了したらnpm run devhttp://localhost:3000が開くことを確認する。

ステップ2: CLAUDE.md を書く(所要5分)

プロジェクトルートにCLAUDE.mdを作る。これはClaude Codeが常時参照する「プロジェクトの憲法」だ。雑に書くと雑な出力が返ってくる。

# memo-saas

## 概要
認証付きのメモ管理SaaS。ユーザーは自分のメモのみ閲覧・編集できる。

## 技術スタック
- Next.js 15 (App Router, Server Actions)
- TypeScript (strict)
- Clerk (認証)
- Neon (Postgres)
- Drizzle ORM
- Tailwind CSS
- Vercelデプロイ

## ルール
- `any`型の使用を禁止する
- DBアクセスは必ず`src/db/`配下のモジュール経由
- 認証チェックは各Server Actionの冒頭で`auth()`を呼ぶ
- UIコンポーネントは`src/components/`、ページは`src/app/`

このファイルがあるだけでClaude Codeの出力精度が体感で3倍変わる。

ステップ3: Clerk で認証(所要20分)

Clerkの無料枠は月間アクティブユーザー10,000人まで。個人開発では事実上無限だ。

Clerkのダッシュボードでアプリケーションを作成し、Publishable KeyとSecret Keyをコピーする。.env.localに貼る。

NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxxxx
CLERK_SECRET_KEY=sk_test_xxxxx

ここからClaude Codeの出番。以下をそのまま投げる。

Next.js 15 App Routerに@clerk/nextjsを導入してほしい。手順は次の通り。1) パッケージインストール、2) src/middleware.tsにclerkMiddlewareを設定、3) src/app/layout.tsx<ClerkProvider>でラップ、4) サインインページとサインアップページを/sign-in/sign-upにキャッチオールルートで作成、5) /dashboardを認証必須ページに設定。.env.localは既に設定済み。

Claude Codeが5ファイル前後を生成したら、npm run dev/sign-upにアクセスし、アカウント作成 → /dashboardリダイレクトまで動くことを確認する。

ステップ4: Neon + Drizzle で DB接続(所要25分)

Neonは無料枠で0.5GB、分岐DB5個まで使える。プロジェクトを作成し、接続文字列(postgres://...)をコピー、.env.localに追記する。

DATABASE_URL=postgres://user:password@ep-xxxx.ap-southeast-1.aws.neon.tech/neondb?sslmode=require

Claude Codeに次を投げる。

Drizzle ORMをセットアップしてほしい。1) drizzle-ormdrizzle-kitpostgresをインストール、2) src/db/schema.tsmemosテーブル(id: uuid主キー、userId: text not null、title: text not null、body: text、createdAt: timestamp default now)を定義、3) src/db/index.tsにDBクライアントを初期化、4) drizzle.config.tsを作成、5) npm run db:pushでスキーマをNeonに反映できるようにpackage.jsonにスクリプトを追加。

生成後、以下を実行する。

npm run db:push

Neonのダッシュボードでmemosテーブルが作成されていれば成功だ。

ステップ5: CRUD ページを作る(所要40分)

ここがメインディッシュ。Claude Codeに次のプロンプトを投げる。具体的に書けば書くほど品質が上がる。

/dashboardページにメモのCRUDを実装してほしい。要件は以下。

  1. 認証必須。auth()userIdを取得し、無ければ/sign-inにリダイレクト
  2. Server Actionsで実装すること(API Routeは使わない)
  3. ファイル構成: src/app/dashboard/page.tsx(一覧と新規作成フォーム)、src/app/dashboard/actions.ts(createMemo, deleteMemo, updateMemo)
  4. Server Actionの冒頭で必ずauth()を呼び、userIdが一致するメモのみ操作可能にする
  5. フォームはuseFormStatusでpending状態を表示
  6. 削除ボタンは<form action={deleteMemo.bind(null, memo.id)}>パターン
  7. Tailwindでシンプルかつ読みやすいUIに(max-w-2xl中央寄せ、カード型)

CLAUDE.mdのルールを守ること。特にany禁止と認証チェック必須。

生成されたコードを読み、Server Action冒頭のauth()呼び出しとeq(memos.userId, userId)の条件が両方入っていることを必ず確認する。片方でも抜けると他人のメモが見える脆弱性になる。

// src/app/dashboard/actions.ts の期待形
"use server";

import { auth } from "@clerk/nextjs/server";
import { db } from "@/db";
import { memos } from "@/db/schema";
import { and, eq } from "drizzle-orm";
import { revalidatePath } from "next/cache";

export async function createMemo(formData: FormData) {
  const { userId } = await auth();
  if (!userId) throw new Error("Unauthorized");

  const title = String(formData.get("title") ?? "").trim();
  if (!title) return;

  await db.insert(memos).values({ userId, title, body: String(formData.get("body") ?? "") });
  revalidatePath("/dashboard");
}

export async function deleteMemo(id: string) {
  const { userId } = await auth();
  if (!userId) throw new Error("Unauthorized");

  await db.delete(memos).where(and(eq(memos.id, id), eq(memos.userId, userId)));
  revalidatePath("/dashboard");
}

ステップ6: Vercel にデプロイ(所要15分)

GitHubにプッシュし、Vercelのダッシュボードで「Import Project」→リポジトリ選択。環境変数としてNEXT_PUBLIC_CLERK_PUBLISHABLE_KEYCLERK_SECRET_KEYDATABASE_URLの3つを設定する。

git init
git add .
git commit -m "initial commit"
git remote add origin https://github.com/yourname/memo-saas.git
git push -u origin main

Vercelは自動でビルド&デプロイし、2分後にhttps://memo-saas-xxx.vercel.appが発行される。この時点でサインアップ→メモ作成→削除が本番で動く。

ClerkのダッシュボードでProduction環境用のPublishable Key/Secret Keyを改めて発行し、Vercelの環境変数に本番値として設定するのを忘れないこと。開発用キーのままだとメール認証で詰まる。

要点まとめ

  • Claude Codeへの指示は「CLAUDE.md + 具体的なファイル構成 + セキュリティ要件」の3点セットで渡すと精度が跳ね上がる
  • 認証チェックとユーザーIDによるフィルタは、Server Actionの先頭で必ず両方入れる
  • 無料枠(Clerk + Neon + Vercel)だけで本番稼働するSaaSが組める
  • 2時間のうち、実はコードを書くのは15分程度で、残り1時間45分は「Claude Codeに適切に指示する」「生成結果を読んで検証する」時間になる

このテンプレートを下敷きに、memosテーブルを自分のドメインに置き換えれば、週末で新しいSaaSを1本ずつ立ち上げられる。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?