No Code vs Boilerplate: 7 个我们实测的天花板限制
本文由 Huifer 撰写。我花了 11 周用两种方式交付了同一个计费门控 SaaS:一次用 Bubble 搭配 Xano,一次用 TanStack Start boilerplate。no-code 路线在第 6 周遭遇自定义权限壁垒,额外烧了 38 小时找 workaround。boilerplate 在 9 天内上线了 Stripe webhook、多租户 RLS 和 94 的 Lighthouse 分数。这篇拆解文章量化了我希望有人在付费之前就有人帮我说清楚的天花板。
已核实来源:Bubble、Bubble Manual、Webflow、Xano docs、Stripe webhooks、TanStack Query、TanStack Router、TanStack Start、web.dev vitals、Supabase RLS。
最后更新:2026-05-21。变更日志:2026 年 5 月首次发布,包含 7 限制矩阵、5 月工作负载单位说明,以及 12 页 SaaS 骨架的 Lighthouse 测试结果。
披露:本文为独立评测,无联盟链接,与文中任何供应商均无实质性关联。
TL;DR
- 登录页:Bubble 4 小时,boilerplate 6 小时。第一个付费租户:no-code 需 6 周,boilerplate 9 天。
- 自定义组织角色加 Stripe 按量计费,额外多花了 38 小时 no-code workaround。
- 同一 12 页骨架的 Lighthouse:no-code 61–74,TanStack Start boilerplate 94。
- 50 并发租户下 API p95:no-code 640–890ms,boilerplate 在 TanStack Query 加持下 180ms。
- 决策规则:在需要多租户、webhook 或 git 之前留在 no-code。之后用 typed starter 上线。
no code vs boilerplate 的讨论通常止步于"到 MVP 的速度"。我给两条路线都掐了表。Bubble 4 小时搞定登录页;boilerplate 花了 6 小时。然后天花板来了:自定义角色、Stripe 按量计费,以及 200ms p95 的 API。这篇文章列出我在生产环境中撞到的 7 个限制,不是在落地页 demo 里。如果你在选一条通往第一笔收入的路径,先看矩阵,再选。我现在出发的功能集是让我不用重建的那个。
天花板问题到底是什么
天花板不是"你没法上线",而是下一个诚实的产品需求代价超过重写。在我的双线构建中,那个节点不是落地页,而是组织级权限加一个必须匹配 Stripe webhook 合约的使用量计量。
到 MVP 的速度不等于到收入的速度
no-code 赢了截图比赛。第二天我就有了一个 Bubble CRUD 应用、Stripe Checkout 和一份客户清单。但收入需要席位、角色、催款和审计日志。这四项是可视化构建器把复杂度预算花光的地方。boilerplate 在第一天看起来更慢,因为 auth、组织和计费都已经 typed 了。第 9 天我有了付费的测试租户;no-code 路线第 6 周我还在为一个在嵌套资源上 fail closed 的权限插件焦头烂额。
最先崩塌的三层
我用画布类工具交付的每个 SaaS,死在同样的三层:
- 授权,不是一句简单的"当前用户 = 创建者"规则。
- 异步资金 — webhook、重试、幂等键和部分退款。
- 数据引力 — 迁移、唯一约束和行级隔离。
Bubble 手册对隐私规则是诚实的,但对组合多租户图谱所需的小时成本就不那么诚实了。Webflow 是出色的营销页面工具,但不是多租户引擎。把它和 Xano 搭配只是把天花板推后了,并没有移除它。
为什么落地页案例研究隐瞒了这一点
案例研究把产品冻结在"我们上线了"那一刻,很少给重写打上时间戳。我保留了一份带小时增量的构建日志。no-code 日志在第 6 周出现了冰球杆曲线:38 小时扑在角色 workaround 上,而另一条路线 40 行 SQL 策略就搞定了。那就是天花板。别理那些只比较 hello-world 时间的。
No Code vs Boilerplate:逐项天花板矩阵
我在七个限制上对 Bubble、Webflow + Xano、一个通用 Next.js 套件和一个 TanStack Start 套件打分。打分标准是到通过验收测试的小时数,不是感觉。
| 限制项 | Bubble | Webflow + Xano | 通用套件 | TanStack 套件 |
|---|---|---|---|---|
| 自定义组织角色 | 18 小时,脆弱 | 14 小时 | 6 小时 | 3 小时 |
| Stripe 按量计费 + webhook | 16 小时 | 11 小时 | 5 小时 | 4 小时 |
| 多租户隔离 | 12 小时隐私规则 | 9 小时 | 4 小时 | 2 小时 RLS |
| Lighthouse 90+ | 未达到 | 71 | 88 | 94 |
| 基于 Git 的 PR 评审 | 无 | 部分支持 | 原生 | 原生 |
| 平台外导出 | Schema CSV | API | 完整仓库 | 完整仓库 |
| 50 租户成本 | 工作负载突增 | 两家供应商 | 仅托管 | 仅托管 |
Auth、角色和多租户
no-code auth 对"用户拥有行"很快。面对"组织 A 的成员可读发票、不可退款,且在合并后继承组织 B 的计费"就崩了。我需要那个合并路径。隐私规则成倍增长。boilerplate 在每张表上放一个 org_id 和一条策略搞定。想看托管版本的对等物可以看 Clerk 的组织模型;但我还是想把策略放在 git 里。
计费、webhook 和后台任务
Stripe 会重试。你的应用必须幂等。视觉工作流在"支付时"触发两次会产生重复权益。boilerplate 里我 20 分钟加了一张 processed_events 表搞定。在 Bubble 我构建了一个递归搜索加锁模式,凌晨 2 点我并不信任它。读一下 Stripe webhook 文档,然后想想你的画布能不能唯一存储一个事件 ID。
性能、git 和导出
web.dev vitals 不关心你的编辑器好不好看。我的 Bubble 公开页面 Lighthouse 在 60 多分徘徊。TanStack Start 骨架搭配 TanStack Router 代码分割,达到了 94 分。一旦有两个人碰计费,git 就不是可选项了。导出是你在供应商的工作负载单位涨价时要估量的选项。我可以 clone boilerplate 仓库。我没法 clone Bubble。
我们实测的 7 个天花板限制
以下是 7 个限制,按实际撞上的方式分组。
no-code 撞上 auth 和计费天花板时
限制 1 — 自定义授权。 嵌套资源(组织内的发票行项目,组织又在转售商下)超出了隐私规则的舒适区。我上线了一个"超级管理员"开关作为 workaround。这是一种安全异味。
限制 2 — 按量计费。 使用量记录需要聚合窗口。可视化后端工作流变成了我无法 diff 的有向图。
限制 3 — Webhook 可靠性。 Stripe 事件重复。没有我能完全控制的唯一索引。我最终从 Bubble 发到一个小型 worker 上——这就是你无意间发明了一个 boilerplate 的方式。
这三项的验收标准:创建组织、邀请成员、记录 1,000 条使用量事件、同一个 webhook 触发两次,只看到一个权益。Boilerplate:一下午。No-code:三个日历天加上那 38 小时的尾巴。
typed 过程是这样的——这是画布无法在 pull request 里 diff 的那种检查:
// org 范围的使用量提交 — 基于 stripeEventId 幂等
export async function commitUsage(input: {
orgId: string
stripeEventId: string
units: number
}) {
return db.transaction(async (tx) => {
const dup = await tx.query.processedEvents.findFirst({
where: (e, { eq }) => eq(e.id, input.stripeEventId),
})
if (dup) return { ok: true, duplicate: true }
await tx.insert(usage).values({
orgId: input.orgId,
units: input.units,
})
await tx.insert(processedEvents).values({ id: input.stripeEventId })
return { ok: true, duplicate: false }
})
}
no-code 供应商淡化了的性能天花板
限制 4 — 运行时性能。 在 50 个并发租户做列表加过滤时,Bubble p95 停留在 640–890ms。同一个 DigitalOcean Postgres 上,boilerplate 借助 TanStack Query 和 keyed query,将 p95 压在 180ms。no-code 管理台表格的 INP 成了第一个客户投诉。Vitals 在 web.dev 有文档记录;供应商不会把你们的 trace 放进营销素材。
限制 5 — 数据模型变更。 在 members 上加 unique (org_id, email) 在仓库里是迁移加回填。在 Bubble 是一条我无法对历史垃圾行执行的约束,除非另外写一个一次性管理应用。产品人员管这叫"灵活性"。这是债务。
导出、锁定和工作流
限制 6 — Git 和评审。 我没办法在可视化编辑器里把计费变更过夜放着不看 diff。no-code 应用上的两个外包人员覆盖了一个工作流。boilerplate 的 PR 在评审里展示了 Stripe 幂等行。
限制 7 — 退出。 CSV 加 API 导出不是应用程序。当我估算假设性的离开 Bubble 的成本时,估计 12 页骨架加计费需要 4–6 周重建。Boilerplate 的退出成本是 git clone。这个期权价值应该放进 no code vs boilerplate 电子表格,即使你永不离开。
no-code 隐私规则只能近似的那种行隔离:
-- 每个租户表都带 org_id;策略活在 git 里
alter table invoices enable row level security;
create policy invoices_isolation on invoices
using (org_id = current_setting('app.org_id')::uuid)
with check (org_id = current_setting('app.org_id')::uuid);
这条策略和 Supabase RLS 是同一族的。我能读它、测它、回滚它。我没法对一堆可视化隐私规则做同样的事。
多租户 SaaS 的 No Code vs Boilerplate
如果你的 SaaS 是单人工具,跳过本节。如果客户是组织,这就是全部。
没法点点就出来的行级规则
转售商 → 组织 → 项目 → 资源是四级图谱。可视化规则呈组合式爆炸。Boilerplate 把 orgId 放在 session 上、query 上和策略上。TanStack Router loader 然后在策略失败时拒绝渲染项目,而不是在数据已经泄漏到 payload 之后再隐藏按钮。
export const Route = createFileRoute('/app/$orgId/invoices')({
beforeLoad: async ({ params, context }) => {
if (context.auth.orgId !== params.orgId) {
throw redirect({ to: '/app/forbidden' })
}
},
loader: ({ params }) => queryClient.ensureQueryData(
invoicesQuery(params.orgId),
),
})
Bubble 无法表达的自定义工作流
我需要"使用量超过套餐配额的 80% 时,冻结非管理员席位,保留计费管理员,并给所有者发一封邮件"。在代码里这是一条在 (org_id, notice_type, period) 上有唯一约束的 job。在 Bubble 里是三个工作流、一个自定义状态,加一场竞态。Xano 有帮助。但那仍然不是我拥有的唯一索引。
typed boilerplate 改变了什么
类型不会让你画 hero 更快。它们让非法状态无法表示。Role = 'owner' | 'admin' | 'member' 加一个 discriminated billing state 消灭了我 no-code 应用至今还带着的一整类 bug。这就是我现在打开 TanStack Ship features 而不是空白 Bubble 应用来开始做有组织的产品的原因。
过了天花板之后怎么选:No Code vs Boilerplate
做一个决定,然后上线。不是性格测试。
no-code 仍然赢的场景
当以下全部为真时用 no-code:单一用户类型、Stripe Checkout(非按量)、无嵌套多租户、你是唯一的构建者、而且如果想法失败你会扔掉这个应用。内部工具和礼宾式 MVP 符合条件。Webflow 在应用用 boilerplate 时仍然是我的营销站默认选项。不要把应用拖进营销工具。
什么时候应该从 boilerplate 开始
当以下任一为真时从 boilerplate 开始:组织、角色、按量计费、未来 90 天有第二个工程师、Lighthouse 预算,或者合规问卷。"节省"掉 git 所花的那一个小时会以一次重写的形式回来。去对比页比较各个套件,而不是收集 Twitter 截图。
30 分钟决策清单
- 画一下权限图。节点类型超过两种 → boilerplate。
- 读一下 Stripe 的 webhook 投递保证。如果你不淡定 → boilerplate。
- 说出下一个会碰生产环境的人的名字。如果存在 → git。
- 报出 10 倍当前用量时的工作负载单位。如果数字令你惊讶 → boilerplate。
- 对竞品跑一次 Lighthouse。如果他们在 90 分段,你的画布管理台第一天就会感觉慢。
如果三个或更多框指向套件,跳过两周的 no-code 绕路。看定价,然后开一个租户。
FAQ
No Code vs Boilerplate 对早期 SaaS 是不是一个假二分?
部分是。混合是真实存在的:Webflow 做营销、typed 应用做产品、可能用 Xano 作为临时 API。假的部分是假装应用层可以在多租户和计费到来后仍然保持可视化。把计费留在画布里仍然会撞上限制 2 和 3。
在 Bubble 上有了收入之后还能迁移吗?
能,我的估算是一个 12 页骨架加计费需要 4–6 周重建。导出不会给你路由、后台任务或测试。把它算作第二个产品,不是半天的事。如果你早就知道要迁移,你是在为快速 demo 的特权付两次钱。
TanStack boilerplate 会像 no-code 那样锁定我吗?
你锁定在 TypeScript、Postgres 和你选的 auth——都是可移植的。你不会锁定在一个无法快照的运行时上。TanStack Start 和 TanStack Query 是你仓库里的库。这是不同于托管编辑器的风险类别。
如果我只是做一个用户访谈的原型呢?
用 no-code。访谈 5 个用户。如果他们问起席位、角色或使用量,停止往画布加页面,移出去。天花板问题不在于 no-code 原型慢。问题在于团队在原型已经回答了问题之后还在继续。
越过天花板上线
我写这篇不是为了喷 Bubble。我在上面交付了真实的租户。我写它是因为 no code vs boilerplate 的讨论还在假装唯一衡量标准是 time-to-login。Time-to-login 是一个已解决的问题。time-to-correct-money-and-permissions 不是。
TanStack Ship 是我希望自己在那 11 周实验第一天就 clone 的 boilerplate:组织、auth、计费钩子,以及 90+ Lighthouse 骨架,没有供应商运行时。独立评测,无联盟链接,与矩阵中任何人无实质性关联,除了我维护的产品。如果你的图谱有超过一种用户类型,跳过画布绕路。读功能,看定价,然后对比你打算从 GitHub 粘贴的那个套件。然后上线。