自托管认证:邮箱密码登录与 Google、GitHub OAuth,OAuth 交换、PBKDF2 密码哈希和 JWT 会话签名均在应用内完成
saas-startup — Next.js SaaS模板
作者 mailkite
基于 Next.js App Router 的 SaaS 启动模板,内置自托管认证、Stripe 订阅与团队管理,使用 PostgreSQL 与 Drizzle ORM。
看看你的网站会是什么样
浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。
全部页面与视图 2
截图用于了解视觉与布局,交互效果请以实际项目为准。
值得关注的模板亮点
从已有项目资料中,快速了解它的特点。
Stripe 集成:包含 Checkout、Customer Portal、Webhook 与订阅生命周期处理
团队管理:支持邀请成员、管理权限与共享工作区
数据层使用 PostgreSQL 与 Drizzle ORM,提供类型化 schema、迁移和种子脚本
界面为深色优先,包含动态背景、渐变卡片、明暗切换和主题色选择器
品牌图标由单一脚本生成,可统一替换字形与强调色
模板详细介绍
该模板面向需要快速搭建 SaaS 产品的开发者,提供从登录注册到订阅计费、团队协作的完整基础骨架。认证部分完全运行在应用自身的 Next.js 服务端:OAuth 授权码交换、密码哈希(PBKDF2,基于 WebCrypto)和 JWT 会话签名(jose)都在本地完成,不依赖外部认证服务。唯一的外部依赖是 MailKite 邮件发送,且为可选,未配置 API Key 时应用会跳过欢迎邮件而不会报错。
支付方面集成 Stripe Checkout、Customer Portal 与 Webhook,覆盖订阅生命周期;团队功能支持邀请成员、管理权限与共享工作区。数据层使用 PostgreSQL 配合 Drizzle ORM,包含类型化 schema、迁移与种子脚本。界面为深色优先,带动态背景、渐变卡片、明暗切换与主题色选择器。
项目结构集中在 apps/web 目录,包含 (dashboard)、(login)、auth 回调和 api 路由,以及 lib/auth、lib/mailkite-auth、lib/db 等模块。品牌图标由脚本统一生成,可修改字形与强调色后重新运行。模板采用 MIT 许可,可免费使用、修改、商用和分发,但演示图片、字体、图标等第三方素材需单独核对许可,域名、托管、数据库、支付等外部服务可能另外收费。
适合你的项目吗?
适用场景
- 从零搭建需要登录注册、订阅计费和团队协作的 SaaS 产品
- 为现有 Next.js 项目补充自托管认证与 Stripe 订阅流程
- 需要深色优先界面与可切换主题色的管理后台或产品仪表盘
- 希望使用 PostgreSQL 与 Drizzle ORM 管理类型化数据模型和迁移
适合人群
- 熟悉 Next.js App Router 与 React 的前后端开发者
- 需要快速验证 SaaS 产品形态的独立开发者或小团队
- 接受自行配置 PostgreSQL、Stripe 等外部服务的项目
上手与定制指南
结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。
- 1
克隆仓库后执行 pnpm install,并复制 .env.example 为 .env 填写必要变量
- 2
必填环境变量包括 AUTH_SECRET、POSTGRES_URL、STRIPE_SECRET_KEY 和 STRIPE_WEBHOOK_SECRET
- 3
在 apps/web 目录运行 npx drizzle-kit migrate 完成数据库迁移,再执行 pnpm run dev 启动
- 4
Google 与 GitHub OAuth 需分别注册回调地址 <BASE_URL>/auth/google/callback 与 <BASE_URL>/auth/github/callback
- 5
MAILKITE_API_KEY 为可选,未配置时应用跳过欢迎邮件;AUTH_SECRET 轮换会使所有会话失效
授权与来源资料
使用条件与限制
免费使用 · 保留许可声明本次收录的是公开仓库中采用 MIT 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。
使用时需要遵守
- 允许免费使用、修改、商用和分发该版本代码。
- 分发代码副本或实质性部分时,保留原作者版权声明和完整 MIT 许可声明。
- 代码按现状提供;担保与责任限制以原许可证及适用法律为准。
额外费用与待核对事项
- 邮件发送依赖外部服务 MailKite,需注册并获取 API Key;未配置 MAILKITE_API_KEY 时应用会跳过欢迎邮件而非报错。
- 支付功能依赖外部服务 Stripe,必须提供 STRIPE_SECRET_KEY 与 STRIPE_WEBHOOK_SECRET,并需自行注册 Stripe 账户。
- 必须自行提供 PostgreSQL 数据库连接(如 Neon、Supabase 或自建),数据库托管可能产生额外费用。
- 使用 Google 或 GitHub OAuth 需在对应平台注册应用并配置回调地址,涉及第三方账户与凭据。
- 必须设置 AUTH_SECRET 作为 JWT 签名密钥;轮换该密钥会使所有现有会话失效。
- 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 MIT 许可判断。
- 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
查看原文依据
Permission is hereby granted, free of charge
许可证原文
The only outbound dependency is [MailKite](https://mailkite.dev) for sending email — and that's optional; without an API key the app simply skips the welcome mail.
README 原文
| `STRIPE_SECRET_KEY` | Yes | Stripe secret key (`sk_test_...`) |
README 原文
| `POSTGRES_URL` | Yes | PostgreSQL connection ([Neon](https://neon.tech), Supabase, or any Postgres) |
README 原文
Register these callback URLs with each provider:
README 原文
https://github.com/mailkite/saas-startup/blob/main/LICENSEhttps://github.com/mailkite/saas-startup/blob/main/README.md| `AUTH_SECRET` | Yes | JWT signing key — `openssl rand -base64 32`. Rotating it invalidates every session |
README 原文
DeepSeek 根据仓库许可证和 README 整理 ·2026-10-01。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。
项目核对记录与介绍依据
模板资料
- 来源平台
- GitHub
- 资料与维护参考分
- 资料较完整 · 77 / 100
- 技术栈
- Next.js · React
- 网站类型
- SaaS · 企业官网 · 启动器
这个分数如何计算
本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。
这个项目需要核对什么
- 记录的仓库更新时间
- 2026-09-16
- 截图检查日期
- 2026-10-01
已收录演示链接。请用你的内容与屏幕尺寸检查;有演示不代表表单、认证或支付已经可用。
目录记录的主要技术栈是 Next.js。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。
查看具体选型方法 →介绍的制作与核对状态
介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。
已完成服务器许可规则与 AI 来源核对;未经过人工编辑审核。
查看当时使用的来源资料
SHA-256: cd5486ee04ea85398ce80a3359123df284c9871e134d7d3786a75dbcc2b367e7
2026-10-01T01:16:56.922Z
来源文件 / 仓库<p align="center">
<img src="apps/web/public/brand/logo.svg" alt="SaaS Starter" width="264" />
</p>
# Next.js SaaS Starter
The **Next.js SaaS Starter** is a production-ready template to launch your SaaS. It wires together **authentication** (self-contained, JWT sessions), **payments** (Stripe subscriptions and customer portal), **team management**, and a polished dark-first dashboard — so you can skip the boilerplate and ship your product.
**Auth runs entirely in your app.** There is no external auth service to sign up for: the OAuth code exchange, password hashing and session signing all happen in your own Next.js server, against your own database. The only outbound dependency is [MailKite](https://mailkite.dev) for sending email — and that's optional; without an API key the app simply skips the welcome mail.
- **Auth** — Email/password + Google and GitHub OAuth, self-contained. PBKDF2 hashing via WebCrypto (no native module), JWT sessions via `jose`
- **Payments** — Stripe Checkout, Customer Portal, webhooks, and subscription lifecycle
- **Team** — Invite members, manage permissions, shared workspace
- **UI** — Dark-first, animated backgrounds, gradient cards, light/dark toggle, color theme picker
- **DB** — PostgreSQL with Drizzle ORM (type-safe schema, migrations, seed scripts)
<br>
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fmailkite%2Fsaas-startup&root-directory=apps%2Fweb&env=AUTH_SECRET,STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET&envDescription=Required%20environment%20variables&project-name=my-saas&repository-name=my-saas)
**[Live demo →](https://saas-startup.mailkite.dev)**
## Stack
| Layer | Technology |
|-------|-----------|
| Framework | [Next.js 15](https://nextjs.org) (App Router) |
| Auth | Self-contained — JWT sessions ([jose](https://github.com/panva/jose)), OAuth, PBKDF2 passwords |
| Email | [MailKite](https://mailkite.dev) — transactional send (optional) |
| Payments | [Stripe](https://stripe.com) — checkout, portal, webhooks |
| Database | [PostgreSQL](https://www.postgresql.org) + [Drizzle ORM](https://orm.drizzle.team) |
| UI | [Tailwind CSS v4](https://tailwindcss.com), [shadcn/ui](https://ui.shadcn.com) |
| Platform | [Vercel](https://vercel.com) (deploys anywhere) |
## Quick Start
```bash
git clone https://github.com/mailkite/saas-startup
cd saas-startup
pnpm install
cp .env.example .env # then fill in AUTH_SECRET, POSTGRES_URL, STRIPE_SECRET_KEY
cd apps/web
npx drizzle-kit migrate
pnpm run dev # http://localhost:3000
```
## Deploy
[](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fmailkite%2Fsaas-startup&root-directory=apps%2Fweb&env=AUTH_SECRET,STRIPE_SECRET_KEY,STRIPE_WEBHOOK_SECRET&envDescription=Required%20environment%20variables&project-name=my-saas&repository-name=my-saas)
## Env vars
| Variable | Required | Purpose |
|----------|----------|---------|
| `AUTH_SECRET` | Yes | JWT signing key — `openssl rand -base64 32`. Rotating it invalidates every session |
| `POSTGRES_URL` | Yes | PostgreSQL connection ([Neon](https://neon.tech), Supabase, or any Postgres) |
| `BASE_URL` | Prod | Public origin, e.g. `https://example.com`. OAuth `redirect_uri` is built from it; on Vercel it falls back to `VERCEL_PROJECT_PRODUCTION_URL` |
| `STRIPE_SECRET_KEY` | Yes | Stripe secret key (`sk_test_...`) |
| `STRIPE_WEBHOOK_SECRET` | Yes | Stripe webhook secret (`whsec_...`) |
| `MAILKITE_API_KEY` | No | Sends the welcome email. Omit and email is skipped, not failed |
| `NEXT_PUBLIC_GOOGLE_CLIENT_ID` | No | Google OAuth — enables the button (build-time inlined) |
| `GOOGLE_CLIENT_SECRET` | No | Google OAuth — required for the code exchange |
| `NEXT_PUBLIC_GITHUB_CLIENT_ID` | No | GitHub OAuth — enables the button (build-time inlined) |
| `GITHUB_CLIENT_SECRET` | No | GitHub OAuth — required for the code exchange |
Register these callback URLs with each provider:
| Provider | Callback URL |
|----------|--------------|
| Google | `<BASE_URL>/auth/google/callback` |
| GitHub | `<BASE_URL>/auth/github/callback` |
## Project Structure
```
apps/web/
├── app/
│ ├── (dashboard)/ # Landing, pricing, dashboard pages
│ ├── (login)/ # Sign in, sign up
│ ├── auth/ # OAuth callbacks — code exchange happens here
│ └── api/ # API routes (stripe, user, team)
├── components/ # React components
├── lib/
│ ├── auth/
│ │ ├── oauth/ # GitHub + Google exchange, identity, account upsert
│ │ ├── password.ts # PBKDF2 hash/verify (WebCrypto)
│ │ └── local.ts # Email/password sign-in + sign-up
│ ├── mailkite-auth/ # Sessions, config, middleware, MailKite email
│ └── db/ # Drizzle schema + migrations
├── middleware.ts # Route protection
└── vercel.json # Vercel deploy config
```
## Brand assets
Every icon is generated from one path definition in `apps/web/scripts/generate-icons.mjs`. Change the glyph or the accent colours there and re-run:
```bash
cd apps/web
pnpm run brand:icons
```
| File | Purpose |
|------|---------|
| `app/icon.svg` | Primary favicon — modern browsers prefer this |
| `app/favicon.ico` | Legacy favicon (16/32/48) |
| `app/apple-icon.png` | iOS home screen (180px, full bleed — iOS applies its own mask) |
| `app/opengraph-image.png` | Social preview (1200×630) |
| `app/twitter-image.png` | Twitter/X summary card |
| `public/brand/icon.svg` | The mark, standalone |
| `public/brand/icon-mono.svg` | Single-colour mark; inherits `currentColor` |
| `public/brand/logo.svg` | Mark + wordmark; adapts to light/dark automatically |
| `public/brand/logo-mono.svg` | Single-colour lockup |
| `public/brand/icon-{192,512}.png` | PWA manifest icons |
| `public/brand/icon-maskable-512.png` | Android maskable (glyph inside the 80% safe zone) |
| `public/brand/mask-icon.svg` | Safari pinned tab |
The in-app `<Logo />` component draws its tile with a CSS gradient rather than a baked SVG one, so the mark follows whichever accent the theme picker is set to. The static files above bake the default Ocean palette.
## License
[MIT](https://opensource.org/licenses/MIT) — use for anything. Attribution appreciated.
Designed by [MailKite](https://mailkite.dev).
看看同类模板
对比同技术栈与用途的模板,找到更适合的视觉与内容结构。

ai-website-cloner-template
Clone any website with one command using AI coding agents
Next.js · 启动器

Next.js SaaS Starter
Next.js SaaS Starter 是 Next.js 官方维护的 SaaS 起点模板,定位介于学习资源和可直接部署的脚手架之间。
Next.js · SaaS

Next.js Commerce
Next.js Commerce 是 Vercel 团队维护的电商启动模板,基于 Next.js App Router 构建,采用服务端渲染、React Server Components、Server Actions …
Next.js · 电商

Next-js-Boilerplate
Next-js-Boilerplate 是一个面向 Next.js 16、Tailwind CSS 4 和 TypeScript 的启动器,核心定位是开发者体验优先。
Next.js · 启动器

tailwind-nextjs-starter-blog
tailwind-nextjs-starter-blog 是一个面向个人技术博客的 Next.js 与 Tailwind CSS 启动模板,其 v2 版本基于 App Router 与 React Server Comp…
Next.js · 博客

next-forge
Production-grade Turborepo template for Next.js apps.
Next.js · 启动器
