An open-source Next.js starter for AI image-generation products.
一句人话: 这不是“炫技 demo”,而是一套能让你把 AI 图像产品更快搭起来的基础盘。 它已经把登录、积分、支付、图片生成、对象存储、多语言这些高频脏活先铺好了。
许可证先说在前面:
- 当前仓库就是标准 MIT License
- 可以商用、可以修改、可以二次分发
- 但你要保留原始许可证声明
如果把做网站比作开店:
Next.js是门店主体Supabase是账本和会员系统NextAuth是门禁fal / KIE / WaveSpeed是后厨出图引擎Stripe / Creem是收银台Cloudflare R2是仓库
你不需要从地基开始浇。 你只需要决定:这家店卖什么、给谁卖、定价多少、视觉长什么样。
适合:
- 想做 AI 图像生成站的人
- 想做 AI 图片编辑站的人
- 想要“可登录、可收费、可上线”的模板,而不是只会本地跑的玩具项目的人
- 想基于
fal,同时保留以后切KIE / WaveSpeed能力的人
不太适合:
- 完全不想碰环境变量、不想注册第三方服务的人
- 只想写一个纯静态落地页的人
开箱就有:
Next.js 15 + React 18 + TypeScript- Google 登录
- 积分系统
- AI 图像生成 / 编辑入口
fal / KIE / WaveSpeedprovider 适配层Stripe / Creem支付接入- Supabase 数据库
- Cloudflare Turnstile 防滥用
- Cloudflare R2 文件存储
- 多语言页面骨架
- 基础 SEO、Analytics、部署脚手架
当前真正接好的支付提供商是 2 个:
StripeCreem
另外有个容易误会的点:
- 仓库里有个通用 webhook 路由提到了
paypal - 但它现在还是预留分支,不是完整生产接入
- 所以最终口径按 2 个已支持支付 来算,不按 3 个写
大白话:
- 真正在营业的收银台有两台:
Stripe和Creem PayPal现在更像“柜台上留了个插座”,不是已经通电的机器
当前数据库主方案是:
Supabase PostgreSQL
再拆开说:
- 认证:
Supabase Auth+NextAuth - 业务数据:
Supabase PostgreSQL - 代码访问层:自己写的一层 Prisma 风格适配器
关键提醒:
- src/lib/database.ts 里导出了一个叫
prisma的对象 - 但它不是 Prisma ORM
- 它只是“长得像 Prisma”的 Supabase 适配层
这点一定要记住,不然后面很容易误判成:
- “是不是少装了 Prisma”
- “是不是还缺
schema.prisma”
答案是:
- 不是
- 这仓库当前主路就是
Supabase
初始化 SQL 在:
核心表主要是:
usersorderscredit_transactionssubscriptionspayment_configs
可以把它理解成:
users是会员表orders是订单表credit_transactions是积分流水subscriptions是订阅关系payment_configs是收银台配置表
如果你就想先把项目跑起来,看这一段就够。
你本机至少需要:
- Node.js
20+ - npm
- Git
git clone https://github.com/CharlieLZ/flux-kontext-template.git
cd flux-kontext-template
npm cicp env.example .env.local如果你想让站点“真正能登录、能生成”,最少先填:
FAL_KEY=""
NEXT_PUBLIC_SUPABASE_URL=""
NEXT_PUBLIC_SUPABASE_ANON_KEY=""
SUPABASE_SERVICE_ROLE_KEY=""
DATABASE_URL=""
NEXTAUTH_URL="http://localhost:3000"
NEXTAUTH_SECRET=""
GOOGLE_ID=""
GOOGLE_SECRET=""npm run dev打开:
http://localhost:3000
npm run lint
npm run build如果这两步都过,说明这套站点骨架是完整的。
先讲大图,不讲代码细枝末节。
- 用户打开首页或
/generate - 用户登录
- 用户输入 prompt,或者上传参考图
- 前端把请求发到
/api/flux-kontext - 服务端检查:
- 有没有登录
- 有没有积分
- 是否需要 Turnstile
- 参数是否合法
- 服务端把请求交给统一的 provider facade
- 当前 provider 再去调用
fal / KIE / WaveSpeed - 返回结果后,图片可选保存到 R2
- 前端展示结果,并允许继续编辑或下载
最常改的是这些:
- 页面和视觉:
src/app/src/components/
- 生成器 UI:
src/components/FluxKontextGenerator.tsxsrc/components/flux-kontext/
- 服务端生成入口:
src/app/api/flux-kontext/route.ts
- provider 适配层:
src/lib/flux-kontext.tssrc/lib/image-generation/providers/
- 用户和积分逻辑:
src/lib/user-tiers.tssrc/api/user/*
src/
├── app/ # 页面和 API 路由入口
├── components/ # React 组件
│ ├── flux-kontext/ # 生成器拆分后的子模块
│ └── ui/ # 基础 UI 组件
├── lib/
│ ├── flux-kontext.ts # 统一生成服务门面
│ ├── image-generation/ # provider 适配层
│ │ └── providers/
│ │ ├── fal-provider.ts
│ │ ├── kie-provider.ts
│ │ └── wavespeed-provider.ts
│ ├── payment/ # 支付相关
│ ├── services/ # R2 / 内容安全等服务
│ └── user-tiers.ts # 用户等级与限制
└── hooks/ # 自定义 hooks
很多新手卡在这,不是不会写代码,是不知道“每个钥匙是开哪扇门的”。
把环境变量想成一串钥匙。
这些不填,项目核心功能跑不起来:
-
FAL_KEY作用:默认 AI 生成 provider 的 API key -
NEXT_PUBLIC_SUPABASE_URL -
NEXT_PUBLIC_SUPABASE_ANON_KEY -
SUPABASE_SERVICE_ROLE_KEY -
DATABASE_URL作用:数据库和用户数据
补一句容易误解的:
-
运行时主要还是通过
Supabase client / admin client在读写数据 -
DATABASE_URL仍然建议配好,因为数据库工具链、连通性检查和排错都可能用到它 -
NEXTAUTH_URL -
NEXTAUTH_SECRET作用:登录态和 cookie 安全 -
GOOGLE_ID -
GOOGLE_SECRET作用:Google 登录
-
R2_*作用:把图片存到 Cloudflare R2 不填会怎样: 页面能开,某些生成后存储链路会降级或报提示 -
STRIPE_*作用:收费 不填会怎样: 不能收款,但不影响你先做产品原型 -
NEXT_PUBLIC_ENABLE_TURNSTILE -
NEXT_PUBLIC_TURNSTILE_SITE_KEY -
TURNSTILE_SECRET_KEY作用:防刷、防滥用
IMAGE_GENERATION_PROVIDER="fal"可选值:
falkiewavespeed
建议新手先用:
IMAGE_GENERATION_PROVIDER="fal"原因很简单:
- 这仓库默认主路径已经按
fal打磨过 KIE / WaveSpeed更适合你后面要接 webhook、任务队列时再打开
适合:
- 先想看到页面
- 先不急着收钱
你只做这些:
- 配
Supabase - 配
Google OAuth - 配
FAL_KEY npm run dev
适合:
- 你已经准备上线
你要再补:
Stripe或CreemR2Turnstile- 正式域名
- 生产环境变量
适合:
- 你想在
fal / KIE / WaveSpeed之间切换
你要看:
src/lib/flux-kontext.tssrc/lib/image-generation/types.tssrc/lib/image-generation/providers/
npm run dev开发模式,默认端口 3000
npm run dev:clean先清 3000-3010 端口,再启动开发环境。 适合“端口被占了,我懒得自己查”的时候。
npm run lint跑 ESLint + TypeScript 类型检查。
npm run build生产构建检查。
npm run start跑生产模式。
npm run check检查配置是否缺项。
npm run check:supabase检查 Supabase 连通性。
npm ci
cp env.example .env.local
npm run check
npm run lint
npm run build
npm run dev你可以把 Supabase 理解成“数据库 + 账号系统 + 后台面板”。
操作步骤:
- 去 Supabase 创建项目
- 拿到:
NEXT_PUBLIC_SUPABASE_URLNEXT_PUBLIC_SUPABASE_ANON_KEYSUPABASE_SERVICE_ROLE_KEY
- 在数据库面板里拿
DATABASE_URL - 写入
.env.local - 在 SQL 编辑器里执行:
如果你漏了第 5 步,最常见结果就是:
- 页面能开
- 登录表面上像成功了
- 但用户、订单、积分流水这些业务表其实没建好
大白话: 门店门锁装好了,但账本和收银小票机还没搬进来。
你可以把 Google OAuth 理解成“让用户用 Google 直接刷脸进门”。
操作步骤:
- 去 Google Cloud Console
- 创建 OAuth Client
- 回调地址本地填:
http://localhost:3000/api/auth/callback/google
- 把
GOOGLE_ID和GOOGLE_SECRET写入.env.local
最简单的一条出图路。
步骤:
- 去
https://fal.ai/dashboard - 创建 API key
- 写入:
FAL_KEY=""
IMAGE_GENERATION_PROVIDER="fal"适合后面做任务型生成或 webhook。
步骤:
- 拿
KIE_API_KEY - 如需 webhook,再配
KIE_WEBHOOK_SIGNING_SECRET - 把 provider 改成:
IMAGE_GENERATION_PROVIDER="kie"和 KIE 类似,更偏任务式接口。
步骤:
- 拿
WAVESPEED_API_KEY - 如需 webhook,再配
WAVESPEED_WEBHOOK_SECRET - 把 provider 改成:
IMAGE_GENERATION_PROVIDER="wavespeed"当前真实已支持支付:
StripeCreem
环境变量开关是:
NEXT_PUBLIC_ENABLE_STRIPE="true"
NEXT_PUBLIC_ENABLE_CREEM="false"
NEXT_PUBLIC_DEFAULT_PAYMENT_PROVIDER="stripe"主要代码位置:
最简单的建议:
- 先把
Stripe跑通 - 之后如果你确实需要双支付,再把
Creem打开
再强调一次:
- webhooks/payments route 里虽然提到了
paypal - 但现在只是预留,不算完整支持
通常是:
FAL_KEY没填- provider 选了
kie / wavespeed,但对应 key 没填
通常是:
NEXTAUTH_URL错NEXTAUTH_SECRET太短GOOGLE_ID / GOOGLE_SECRET没配好- Google OAuth 回调地址没填对
通常是:
DATABASE_URL错- Supabase service role key 错
如果日志里出现:
R2 storage not configured - missing environment variables
这不一定表示整个项目坏了。 它的意思通常是:
- 页面能跑
- 但对象存储这条链路还没配
这仓库当前是:
package-lock.jsonnpm ci
所以默认请用 npm。
不要一上来混着 npm 和 pnpm 用,不然锁文件会打架。
为了不把代码越改越乱,建议坚持下面这套流程:
master只做同步,不直接开发- 每次都从最新
origin/master切新分支 - 最好配一个独立 worktree
- 一个分支只做一个主题
- 本地先跑
npm run lint和npm run build - 推远端后开 PR
- 等 GitHub checks
- 自己看一遍本地或 Preview
- 没问题再合并
- 合并后删远端分支和本地 worktree
最稳的顺序通常是:
- 先跑通登录、生成、支付三件套
- 再做 UI 优化
- 再做 provider 扩展
- 最后再做内容安全和更多自动化
不要反过来。
大白话讲: 先把店开起来,再装修,再扩仓库,再装更多安保系统。 顺序反了,你会很累。
别一味加文件,也别一味把所有东西塞回一个文件。
最好的状态是:
- 页面只负责编排
- API route 只做入口校验和 orchestrate
- provider 细节放 adapter
- 支付逻辑单独放 service
- 大组件继续往子模块拆
一句话: 前台、后厨、收银台、仓库要分房间,不要堆在一张桌子上。
本仓库使用 MIT License。
这意味着:
- 你可以商用
- 你可以修改
- 你可以二次分发
- 但你需要保留原始许可证声明
如果你打算基于这个模板做收费产品,MIT 对你是友好的。
当前检查结果:
- LICENSE 是标准 MIT 文本
- 没有发现“文件名写 MIT,但正文不是标准 MIT”的问题
- README 和 LICENSE 的口径现在是一致的
先别急着做“最强版本”。
最靠谱的路线永远是:
- 先跑起来
- 再跑通一条完整业务链
- 再做视觉
- 再做扩展
不要一开始就想同时做:
- 多 provider
- 多支付
- 多语言
- 多角色
- 多主题
- 多套内容安全
那样最容易把自己绕进去。
先让产品像一辆能开动的车,再考虑换轮毂、贴膜和改涡轮。