Next.jsReactSaaS启动器

saas-genai-starter — Next.js SaaS模板

作者 delmalih

面向多租户 GenAI 产品的开源 SaaS 启动器,基于 Next.js 与 FastAPI,内置 BYO-key 模型接入、带引用的 RAG、用量计费与评估工具。

看看你的网站会是什么样

浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。

2 个预览视图
桌面端首页1 / 2
桌面端截图首屏预览

由服务器浏览器实际访问页面后截取。

全部页面与视图 2

截图用于了解视觉与布局,交互效果请以实际项目为准。

采集于 2026-10-03查看来源

值得关注的模板亮点

从已有项目资料中,快速了解它的特点。

01

多租户隔离在数据访问层实现,每个查询通过 TenantScopedRepository 自动注入租户过滤条件

02

支持 BYO-key 模式,可为每个组织配置 Anthropic、OpenAI、Gemini、Mistral、xAI、DeepSeek、Groq 或 OpenRouter 等聊天提供商

03

RAG 管道包含异步文档解析、分块、嵌入和 pgvector HNSW 检索,回答附带页面级引用

04

每次 LLM 调用记录 token、成本、延迟和状态,支持按功能与模型查看每日花费

05

内置评估工具,使用真实管道和 LLM 评判对忠实度与引用正确性打分

06

提供 Terraform 部署配置,可在多个服务的免费额度内运行,并包含 CI/CD 流程

模板详细介绍

这是一个面向多租户 GenAI 产品的开源 SaaS 启动器,仓库采用 MIT 许可,代码可免费使用、修改和分发。项目由 Next.js 前端与 FastAPI 后端组成,配合 PostgreSQL + pgvector、Redis 和 Terraform 部署脚本,提供从认证、租户隔离到 RAG 对话与用量追踪的完整基础结构。

在能力层面,它实现了数据层强制的多租户隔离、基于 Better Auth 的认证与团队邀请、支持 8 家聊天提供商和 5 家嵌入提供商的 BYO-key 密钥管理(Fernet 加密、只写接口)、按组织统计的 LLM 调用成本、带页面级引用的异步 RAG 管道、OpenTelemetry 可观测性以及基于 LLM 评判的评估工具。计费模块通过 Stripe 实现但默认关闭,需要显式启用。

使用限制方面,仓库代码本身免费,但演示图片、字体、图标等第三方素材需单独核对许可;域名、托管、数据库、支付和 AI 服务可能产生费用。README 中提到的 $0/月部署依赖各服务的免费额度,并非代码自带保证。项目状态为 v1 已上线,但评估基线等数据来自特定模型与配置,不构成通用性能承诺。

Next.jsSaaS启动器

适合你的项目吗?

适用场景

  • 需要快速搭建多租户 GenAI SaaS 产品原型的团队
  • 希望让每个客户自带模型 API 密钥并独立计费的产品
  • 构建基于文档的问答或知识库对话应用
  • 需要评估 RAG 回答质量与引用准确性的开发流程
  • 在免费额度内验证 GenAI 产品全栈架构的个人或小团队

适合人群

  • 熟悉 Next.js 与 FastAPI 的全栈开发者
  • 需要多租户与用量追踪的 GenAI 产品团队
  • 希望以 MIT 许可代码为基础进行二次开发的开发者
  • 关注 RAG 引用与评估工具链的技术团队

上手与定制指南

结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。

  1. 1

    需要 Node 22 及以上、pnpm、uv 以及 Docker 运行环境

  2. 2

    执行 make setup、make migrate、make dev 启动本地开发环境,另开终端运行 make worker 处理文档摄取

  3. 3

    在 Settings → AI Provider 中粘贴自己的提供商密钥,或在 apps/api/.env 中设置服务端全局密钥作为回退

  4. 4

    RAG 功能需要额外的嵌入模型密钥,例如 Voyage AI 或 OpenAI/Gemini/Mistral 的密钥

  5. 5

    计费功能默认关闭,启用前需配置 Stripe 相关环境变量

查看仓库使用说明

授权与来源资料

使用条件与限制

免费使用 · 保留许可声明

本次收录的是公开仓库中采用 MIT 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。

使用时需要遵守

  • 允许免费使用、修改、商用和分发该版本代码。
  • 分发代码副本或实质性部分时,保留原作者版权声明和完整 MIT 许可声明。
  • 代码按现状提供;担保与责任限制以原许可证及适用法律为准。

额外费用与待核对事项

  • 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 MIT 许可判断。
  • 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
  • 使用 RAG 功能需要额外的嵌入模型密钥:搭配 Anthropic 时需 Voyage AI 密钥(有免费额度),或使用 OpenAI/Gemini/Mistral 密钥同时覆盖聊天与嵌入。
  • 必须自行提供并配置 AI 提供商 API 密钥:可在设置中按组织粘贴,或在 apps/api/.env 中设置服务端全局密钥作为回退。
  • 计费功能默认关闭,需通过 BILLING_ENABLED 标志显式启用;启用后需使用 Stripe 订阅服务并配置 Stripe 账户。
  • $0/月部署依赖各外部服务的免费额度(Cloud Run、Neon、Upstash、GCS、Vercel 等),超出免费额度可能产生费用,并非代码自带保证。
  • 运行需要 Node 22 及以上、pnpm、uv 以及 Docker 运行环境。
查看原文依据

Permission is hereby granted, free of charge

许可证原文

For RAG you also need an embeddings key: **Voyage AI** (free tier) with Anthropic, or your OpenAI/Gemini/Mistral key covers both.

README 原文

paste your provider key in *Settings → AI Provider* (per-organization, encrypted at rest), or - set server-wide keys in `apps/api/.env` (`ANTHROPIC_API_KEY`, `VOYAGE_API_KEY`, …) as the fallback for every org.

README 原文

**Billing, opt-in** — Stripe subscriptions (Checkout + customer portal + signature-verified webhooks) behind a `BILLING_ENABLED` flag, with plan-based rate limits (free/pro) and upgrade prompts when quotas are hit. Off by default: no Stripe code runs and no Stripe account is needed.

README 原文

The [Terraform in `infra/`](infra/terraform) deploys the whole stack inside free tiers, with CI/CD included:

README 原文

**Prerequisites**: Node ≥ 22, pnpm (`corepack enable pnpm`), [uv](https://docs.astral.sh/uv/), and a Docker runtime (Docker Desktop or `brew install colima docker-compose && colima start`).

README 原文
https://github.com/delmalih/saas-genai-starter/blob/main/LICENSEhttps://github.com/delmalih/saas-genai-starter/blob/main/README.md

DeepSeek 根据仓库许可证和 README 整理 ·2026-10-05。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。

项目核对记录与介绍依据

模板资料

来源平台
GitHub
资料与维护参考分
资料较完整 · 88 / 100
技术栈
Next.js · React
网站类型
SaaS · 启动器
这个分数如何计算

本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。

这个项目需要核对什么

记录的仓库更新时间
2026-06-25
截图检查日期
2026-10-05

已收录演示链接。请用你的内容与屏幕尺寸检查;有演示不代表表单、认证或支付已经可用。

目录记录的主要技术栈是 Next.js。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。

查看具体选型方法 →

介绍的制作与核对状态

介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。

审核声明: [email protected] · 2026-10-05

查看当时使用的来源资料

SHA-256: 8a7a639f77a5044f18e0de2d839e954ad49a8524d2acb9197c84e9ed0716faf5

2026-10-05T03:25:28.434Z

来源文件 / 仓库
# saas-genai-starter

[![CI](https://github.com/delmalih/saas-genai-starter/actions/workflows/ci.yml/badge.svg)](https://github.com/delmalih/saas-genai-starter/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
[![Live demo](https://img.shields.io/badge/demo-live-brightgreen)](https://saas-genai-starter-web.vercel.app)

**A production-grade, open-source starter for multi-tenant GenAI SaaS** — the
parts demo-grade starters ignore: multi-tenancy enforced at the data layer,
LLM cost tracking per organization, provider resilience, bring-your-own-key
support for 8 chat providers, observability, async ingestion, an eval harness
that caught real bugs before launch, and a $0/month deployment.

Built with **Next.js 15 · FastAPI · PostgreSQL + pgvector · Terraform**.

## ✨ Try it now

**[saas-genai-starter-web.vercel.app](https://saas-genai-starter-web.vercel.app)**
— sign up, paste your own API key (Anthropic, OpenAI, Gemini, Mistral, xAI,
DeepSeek, Groq or OpenRouter) in *Settings → AI Provider*, upload a PDF and
chat with it. Streamed answers, page-level citations, live cost tracking.

The demo runs the exact code in this repo on infrastructure that costs its
maintainer **0€/month** (details [below](#the-0month-deployment)). Your keys
are Fernet-encrypted at rest and write-only through the API.

## What's inside

- **Multi-tenancy you can't bypass** — every query goes through a
  tenant-scoped repository that injects the filter at construction;
  forgetting it is structurally impossible. Cross-tenant isolation has
  dedicated tests.
- **Auth done right** — [Better Auth](https://better-auth.com) in Next.js
  (email/password + Google/GitHub SSO, env-gated), FastAPI validates its
  JWTs via JWKS. Roles (owner/admin/member), team invitations with
  single-use hashed tokens.
- **Bring-your-own-key, multi-provider** — each organization picks its
  provider (Anthropic, OpenAI, Google Gemini, Mistral, xAI, DeepSeek, Groq
  or OpenRouter for chat; Voyage, OpenAI, Gemini, Mistral or Cohere for
  embeddings), its model, and pastes its own API keys — encrypted at rest
  (Fernet), write-only through the API, never logged. Server-wide env keys
  remain as the self-host fallback, and OpenAI-compatible providers are a
  [catalog entry away](docs/extending-llm-providers.md).
- **LLM costs under control** — every call (chat, RAG, ingestion,
  extraction) writes a usage row: tokens (including cache reads), cost in
  USD from a versioned pricing table, latency, status. Usage survives
  client disconnects and mid-stream failures. A dashboard shows daily
  spend per feature and model.
- **Resilience as a layer, not an afterthought** — provider-agnostic
  retries with jitter, `retry-after` honored, circuit breaker with
  half-open probes (429s don't trip it — throttling isn't an outage).
- **RAG pipeline** — async ingestion (parse → chunk with page numbers →
  embed → pgvector HNSW), agentic chat with a search tool, citations
  persisted with messages, per-tenant rate limiting (Redis, fail-open),
  structured-output metadata extraction.
- **Observability** — OpenTelemetry traces (FastAPI/SQLAlchemy/httpx +
  `llm.call` spans carrying model, tokens and cost), structured logs with
  request and tenant ids.
- **Evals from day one** — `make evals` runs the real pipeline against a
  fixture corpus and scores it with an LLM judge. Current baseline:
  **0.96 overall** (faithfulness 0.99, citations 0.93) on
  `claude-sonnet-4-6`. The first run scored 0.57 and exposed two real
  bugs — see [Why these choices](#why-these-choices).
- **Billing, opt-in** — Stripe subscriptions (Checkout + customer portal +
  signature-verified webhooks) behind a `BILLING_ENABLED` flag, with
  plan-based rate limits (free/pro) and upgrade prompts when quotas are
  hit. Off by default: no Stripe code runs and no Stripe account is
  needed.
- **Agent-bootstrappable** — point Claude Code (or any coding agent) at
  [`BOOTSTRAP.md`](BOOTSTRAP.md) with five parameters and it turns the
  starter into *your* named, branded product with green tests
  (`make bootstrap` for humans).

## Architecture

```mermaid
flowchart LR
    subgraph web["apps/web — Next.js 15 (Vercel)"]
        UI[App UI] --> BA[Better Auth<br/>sessions + EdDSA JWT]
    end
    subgraph api["apps/api — FastAPI (Cloud Run, scale-to-zero)"]
        MW[JWT via JWKS<br/>+ X-Org-Id tenant scope] --> DOM[Domains<br/>chat · documents · usage<br/>billing · admin]
        DOM --> LLM[LLM layer<br/>catalog · resilience · pricing]
        DOM --> RL[Rate limiter<br/>per-tenant, plan-aware]
        JOBS["/internal/jobs<br/>parse → chunk → embed"]
    end
    UI -->|"typed client (OpenAPI)"| MW
    BA -.->|JWKS| MW
    LLM --> CHAT["Chat: Anthropic · OpenAI · Gemini<br/>Mistral · xAI · DeepSeek · Groq · OpenRouter"]
    LLM --> EMB["Embeddings: Voyage · OpenAI<br/>Gemini · Mistral · Cohere"]
    DOM --> PG[("Postgres + pgvector<br/>(Neon)")]
    JOBS --> PG
    RL --> RD[("Redis<br/>(Upstash)")]
    DOM --> GCS[("Blob storage<br/>local disk / GCS")]
    DOM -->|enqueue| CT["Cloud Tasks (prod)<br/>ARQ on Redis (local)"]
    CT -->|"OIDC-signed push"| JOBS
```

Background jobs need no always-on worker in production: the API enqueues a
Cloud Tasks task, which pushes an OIDC-signed HTTP request back to the same
scale-to-zero service. Locally the same job code runs on an ARQ worker —
the queue is an interface, the swap is configuration.

## The $0/month deployment

The [Terraform in `infra/`](infra/terraform) deploys the whole stack inside
free tiers, with CI/CD included:

| Piece | Service | Why it's free |
|---|---|---|
| API | Cloud Run | scale-to-zero, CPU billed only while serving |
| Jobs | Cloud Tasks | push queue — no idle worker to pay for |
| Database | Neon Postgres | serverless free tier, pgvector included |
| Rate limiting | Upstash Redis | free tier, per-request pricing model |
| Documents | GCS | always-free tier (US regions) |
| Web | Vercel Hobby | static + serverless |
| LLM usage | — | every org brings its own keys |
| CD | GitHub Actions | keyless deploys via Workload Identity Federation |

`git push` on `main` builds the image, runs Alembic against Neon (connection
string fetched from Secret Manager, masked in logs), deploys the new
revision and smoke-checks `/health` — no JSON service-account keys anywhere.

## Quickstart

**Prerequisites**: Node ≥ 22, pnpm (`corepack enable pnpm`),
[uv](https://docs.astral.sh/uv/), and a Docker runtime (Docker Desktop or
`brew install colima docker-compose && colima start`).

```bash
git clone https://github.com/delmalih/saas-genai-starter && cd saas-genai-starter
make setup    # deps + .env files
make migrate  # database schema
make dev      # postgres+redis (docker), API on :8000, web on :3000
make worker   # in a second terminal — document ingestion
```

Sign up on http://localhost:3000, then either:
- paste your provider key in *Settings → AI Provider* (per-organization,
  encrypted at rest), or
- set server-wide keys in `apps/api/.env` (`ANTHROPIC_API_KEY`,
  `VOYAGE_API_KEY`, …) as the fallback for every org.

For RAG you also need an embeddings key: **Voyage AI** (free tier) with
Anthropic, or your OpenAI/Gemini/Mistral key covers both.

**Making it yours**: [`BOOTSTRAP.md`](BOOTSTRAP.md) — written for coding
agents — renames, rebrands and re-domains the starter from five parameters.

## Evals

```bash
make evals                      # full run, ~7 min (paced for Voyage free tier)
make evals ARGS="--min-score 0.8"
```

The harness ingests a fixture corpus with **real embeddings** into a
dedicated database, runs the **real agent loop**, and grades every answer
with an LLM judge on faithfulness and citation correctness — including
negative cases where the right answer is "that's not in the documents".
Per-commit results land in [`evals/results/`](evals/results/).

| Metric | Baseline (claude-sonnet-4-6) |
|---|---|
| Overall | **0.963** |
| Faithfulness | 0.993 |
| Citation correctness | 0.933 |

## Why these choices

The decisions that make this starter production-grade rather than demo-grade
— several were validated the hard way:

- **Tenant isolation lives in the repository layer, not in code review.**
  `TenantScopedRepository` takes the tenant at construction and injects the
  filter into every query; `add()` overwrites forged tenant ids. You can't
  forget a `WHERE tenant_id = ...` because you never write one.
- **`lazy="raise"` on every relationship.** Async SQLAlchemy turns implicit
  lazy loads into `MissingGreenlet` errors that depend on garbage-collection
  timing. A flaky test traced back to exactly that — now any unloaded
  relationship access fails loudly and deterministically, and eager loading
  is explicit.
- **The eval harness paid for itself on day one.** First run: 0.57. It
  exposed that tool results sent the model a 400-char UI snippet instead of
  full chunk content (the agent cited the right document while claiming the
  information wasn't there), and that the agent answered general-knowledge
  questions from memory without searching. Both fixed; baseline 0.96. No
  unit test could have caught either.
- **Usage rows survive failure.** Provider costs are incurred even when the
  client disconnects mid-stream — so usage records are written and committed
  on the error path, with output estimated from streamed characters.
- **429 ≠ outage.** Rate limiting is backpressure with its own pacing
  (`retry-after`); only real failures (5xx, timeouts) feed the circuit
  breaker.
- **BYO keys are write-only.** Org API keys are Fernet-encrypted at rest and
  the API only ever returns `is_set` + the last 4 characters. A database
  leak does not leak provider keys.
- **One normalized message format, many providers.** Domain code speaks one
  block vocabulary; each provider translates to its own dialect. The agent
  loop runs unchanged on Claude, GPT, Gemini, Mistral, Grok and friends —
  and a parameterized test enforces the new-provider checklist (pricing
  entry, key column, settings field) straight from the catalog.
- **Queues and storage behind interfaces.** ARQ/local-disk for dev,
  Cloud Tasks/GCS adapters for prod — swapping is configuration, not
  refactoring.

## Project structure

```
apps/
├── web/          # Next.js 15 — Better Auth, typed OpenAPI client, chat UI
└── api/          # FastAPI — src/core (auth, tenancy, telemetry),
                  #           src/llm (catalog, providers, resilience, pricing),
                  #           src/domains (chat, documents, usage, billing, admin, ...)
evals/            # eval harness, fixture corpus, per-commit results
infra/terraform/  # the $0-tier deployment (modules + demo environment)
BOOTSTRAP.md      # agent-driven "make it yours" guide + scripts/bootstrap.py
```

More docs: [extending the LLM layer](docs/extending-llm-providers.md) ·
[auth flow](docs/auth-flow.md) · [deployment](docs/deploy.md) ·
[backlog & decisions](tech-steps.md)

## Status

**v1 is live** — [demo](https://saas-genai-starter-web.vercel.app) deployed
from this repo, CI green, eval baseline 0.96. The full build history is
ticket-by-ticket in [`tech-steps.md`](tech-steps.md), including the
decisions and the post-launch roadmap.

## License

[MIT](LICENSE)
反馈内容错误

看看同类模板

对比同技术栈与用途的模板,找到更适合的视觉与内容结构。