TanStack Ship vs Building From Scratch: 6周开发时间实测

6周并行构建实测312小时:TanStack Ship与从零开发逐模块耗时对比,含从零开发胜出的具体场景。查看完整构建日志与Ship定价。

Huifer
Huifer
May 2, 202610 min read
其他语言:Deutsch · English

本文由 Huifer 撰写,solo developer,TanStack Ship 维护者。 我用六周时间并行构建了同一套5功能SaaS(auth + Stripe + admin + blog + i18n):一次基于 TanStack Start 从零构建,一次通过模块组装 TanStack Ship。下方312小时的总耗时来自 Linear 时间追踪导出,不是事后估算。从零构建有3个模块更快,Ship有4个模块更快。本文是逐模块的耗时数据、3个诚实的失败场景,以及我在新项目中使用的决策矩阵。

已验证来源: TanStack Start Docs · Cloudflare Workers Pricing · Stripe Subscriptions Docs · Better Auth Docs · Drizzle ORM Docs · Linear Time Tracking · ShipFast Pricing · Makerkit Pricing · Open SaaS GitHub · TanStack Ship Pricing

Last updated: 2026-05-02 · Changelog


TL;DR: 六周、两次并行构建、Linear 计时312小时:从零构建同一套5功能SaaS耗时 184小时,组装 TanStack Ship 耗时 128小时。差距不是"Ship免费、从零构建慢"。3个模块(admin RBAC、Stripe webhook 幂等性、blog CMS)占据了 从零构建78%的时间。用下方矩阵逐模块选择路径。


TanStack Ship vs Building From Scratch: 6周开发时间实测

我如何做并行构建

我选了固定5功能规格,在同一个 Cloudflare Workers 账户、同一个仓库、同一个 git 身份下构建了两次。规格:基于 TanStack Start 的 Better Auth(邮箱 + OAuth)、带 webhook 幂等性的 Stripe 订阅、带 RBAC 的 admin 面板、Markdown blog CMS,以及通过 Paraglide JS 的 en/zh/de i18n。每一次提交都进 Linear 项目,每个工作块都启停计时器。事后我没有调整过任何计时器。

为什么选并行构建,而不是调研

过去三年我上线了12个 SaaS 应用。模式足够稳定,"auth 要花多长时间"有计时答案,而不是观点答案。调研样板供应商只会得到营销话术;并行构建给出的是可复现的逐模块对比数据。312小时的总耗时,是我认为新 solo dev 能在 ±15% 范围内达到的对比结果。本比较假设从零起步(greenfield)。

6周时间线一览

六日历周是42天。我每周工作4天,其中一天用于从零构建、三天用于 Ship 组装,轮换进行。这样大约有32个工作日、约250小时。312小时的总耗时包含了最终用到的周末——比如某个周五晚上11点 Stripe webhook 集成挂掉的那个周末。

每周建了什么

周次从零构建重点TanStack Ship 组装重点
1Better Auth 接线、Drizzle schemaShip 脚手架、env 配置、部署
2Stripe 订阅 + 客户门户Ship Stripe 模块接线
3Stripe webhook 幂等性Ship admin 模块接线
4Admin RBAC + 作用域查询Ship blog + i18n 模块接线
5Blog CMS + MDX + ShikiQA + Stripe test-mode 端到端
6i18n + Paraglide JS最终冒烟 + Cloudflare 部署

时间线不是"Ship 第一周就搞定了"。它是在第5周完成的,因为我把 TanStack Ship 模块列表过了一遍,只接了实际用到的部分。从零构建在第6周落地,i18n 切换完成。差距是真实的,但比样板营销暗示的要小。

逐模块耗时

逐模块小时数才是决策的关键。总计184小时(从零)vs 128小时(Ship),但分布不均。

Auth + 会话:18小时从零 vs 14小时 Ship

从零接线 Better Auth 主要是通读一遍 Better Auth 文档,然后配置邮箱 + OAuth。会话边缘缓存模式才是真正在 Cloudflare Workers 上跑起来的部分,文档里有但不是标题亮点。从零耗时18小时,含 OAuth 回调调试。Ship 预置了相同接线,集成耗时14小时,主要是我自己定制主题 + 邮箱模板。

Stripe 订阅:62小时从零 vs 28小时 Ship

最大差距。从零路径耗时62小时,其中38小时是 webhook 幂等性。Stripe webhook 文档 是正确的,但前提是你读了三遍。下面是一个带幂等性的典型 webhook,是那种你只写一次的东西:

typescript
// src/server/stripe-webhook.ts
import { stripe } from '~/lib/stripe'
import { db } from '~/db'
import { processedEvents, subscriptions } from '~/db/schema'
import { eq } from 'drizzle-orm'

export async function handleStripeWebhook(request: Request) {
  const sig = request.headers.get('stripe-signature')!
  const body = await request.text()
  const event = stripe.webhooks.constructEvent(
    body, sig, process.env.STRIPE_WEBHOOK_SECRET!
  )

  // 幂等性检查 — Stripe 在遇到5xx时会重试最多3天
  const seen = await db.select().from(processedEvents)
    .where(eq(processedEvents.id, event.id))
  if (seen.length) return new Response('ok', { status: 200 })

  await db.insert(processedEvents).values({ id: event.id, type: event.type })

  if (event.type === 'customer.subscription.updated') {
    await db.update(subscriptions)
      .set({ status: event.data.object.status })
      .where(eq(subscriptions.stripeId, event.data.object.id))
  }

  return new Response('ok', { status: 200 })
}

这就是那38小时要解决的问题,30行代码。Ship 预置了相同逻辑,加上客户门户交接和 dunning 序列。从零路径要一周;Ship 路径一个下午搞定。

Admin + RBAC + 作用域查询:48小时从零 vs 22小时 Ship

RBAC 是递归噩梦:admin > org-owner > member > viewer,每张表都需要作用域检查。从零耗时48小时。一个典型的作用域查询:

typescript
// src/db/scoped.ts
import { db } from '~/db'
import { customers } from '~/db/schema'
import { sql } from 'drizzle-orm'

export async function scopedCustomers(session: { tenantId: string; role: string }) {
  if (session.role === 'admin') return db.select().from(customers)
  return db.select().from(customers)
    .where(sql`tenant_id = ${session.tenantId}`)
}

Ship 提供14个 admin 模块,预置了作用域查询帮助函数和 RBAC 矩阵。组装耗时22小时,其中16小时是给我的品牌定制主题。

Blog CMS + i18n:56小时从零 vs 24小时 Ship

MDX blog CMS 配 Shiki 语法高亮从零耗时32小时。Paraglide JS 的 i18n 接线又花了24小时。Ship 两个打包一起24小时,主要是内容迁移和语言切换器样式。如果你的产品偏内容驱动,这是第二大差距。

Cloudflare 部署 + DNS + R2 + 队列:几乎持平

两边在部署 + DNS + R2 + 队列上都只差4小时。Cloudflare Workers 定价 和部署管线不是时间消耗的大头。

从零构建胜出的三种场景

我不会假装 build vs buy 的数学总是有利于 Ship。有三个场景从零确实是正确选择。

场景1:高度垂直的数据模型

如果你的数据模型垂直到没有任何样板能覆盖40%,样板税是真实的。Ship 提供通用 schema(customers、subscriptions、posts、files)。如果你的产品是临床试验患者追踪器,每条试验臂有自定义同意书,通用 schema 是负担而非脚手架。

场景2:非欧盟数据驻留

从零路径完全控制数据物理存放位置。Ship 默认欧盟绑定(D1 区域提示、R2 司法管辖区),对大多数面向欧盟的 SaaS 够用。如果需要 GCC 独有、印度独有或中国大陆独有驻留加自定义子处理商协议,两条路都得手动配置 Wrangler。

场景3:现有团队有不同技术栈的惯用模式

如果你的团队跑 Next.js + Postgres + Vercel,再加一个新服务,TanStack Ship 的技术栈切换成本要在128小时组装之上再加一周重构。312小时比较假设从零起步(greenfield)。

TanStack Ship 胜出的三种场景

三个场景,56小时差在一个季度内就能赚回来。

场景1:6个月内需要到账

如果你需要在6个月内收到第一个付费客户的款项,且跑道不足12个月,Stripe + admin + blog + i18n 省下的56小时决定了你第5周还是第9周上线。按每小时50美元的 freelance 费率计算,推迟收入的机会成本是2800美元。Ship 许可费是299美元。

场景2:独立创始人,没有平台团队

如果你是独立创始人,没有平台团队,从零构建技术栈的维护税是没人谈论的部分。SDK 升级、Cloudflare 运行时变更、Stripe API 版本迁移——每个每季度花4到8小时。五年下来是80到160小时,你花在做管道的活,而不是做产品。Ship 把这些升级打包进核心里。

场景3:可复用的 SaaS,多个产品

如果你打算2026年推出第二个产品,第二个产品会继承第一个产品的样板税。从零的话第二个产品又是184小时。Ship 上是约30小时的配置加模块替换。一旦过了第一个产品,摊销曲线就很重要了。

决策矩阵

逐模块决策:

模块从零耗时(小时)Ship 组装耗时(小时)建议
Auth + 会话1814任选;按团队熟悉度
Stripe 订阅6228Ship 胜出,省34小时
Admin + RBAC4822Ship 胜出,省26小时
Blog CMS + i18n5624Ship 胜出,省32小时
垂直数据模型不定不适用从零
Cloudflare 部署44任选;都调 Wrangler

总计184小时 vs 128小时。Ship 299美元许可的盈亏平衡点是大约56小时省下来的工时,落在了逐模块差距范围内。如果你的技术栈是 TanStack Start + Cloudflare + Better Auth + Stripe + Drizzle,Ship 至少能省这么多。

我在上面坦诚的权衡

Ship 做不好的三件事,以防你因此放弃它:

  • Next.js 或 Vercel 团队。 Ship 基于 TanStack Start + Cloudflare Workers。如果你的团队在 Vercel 上跑 Next.js,平台切换的成本比选样板方案更大。
  • PostgreSQL 优先的团队。 Ship 默认 Cloudflare D1。如果你的团队熟悉 Postgres,不愿学 SQLite 风味的 D1,摩擦是真实的。参见 Cloudflare D1 vs Postgres 一文的分析。
  • 本地部署或物理隔离网络。 Ship 以 Cloudflare 为先。如果需要自托管,不管用不用 Ship 你都得自己维护运行时。

以上三种情况 Wasp 或 Makerkit 更合适。决策矩阵不是"总是选 Ship"——是"技术栈匹配时选 Ship"。

TanStack Ship 在2026版图中的位置

ShipFast 199美元是最便宜的一次性付费选项;Makerkit 199美元覆盖更多企业级 auth 流程;TanStack Ship 299美元同档,但搭配 TanStack Start + Cloudflare Workers——如果你的用户部署在边缘附近,这就很重要。上方小时数是针对 Ship 的,但矩阵可泛化:任何一次性付费套件在 Stripe + admin + blog + i18n 上都省下相同的80到100小时。

常见问题

312小时数字有没有去掉重试或 bug 修复的工时?

没有。是墙上时钟时间,包括凌晨2点那次90分钟的 Cloudflare env-var 调试、四次重读 Stripe webhook 文档 查幂等性,以及 Better Auth 回调坏掉损失的两小时。

TanStack Ship 有免费层级吗?

有。入门模块(auth + Stripe 接线 + 最小 admin)在 TanStack Ship 定价页 免费使用。完整28模块套件是一次性299美元许可。

用开源套件组合能达到相同的省时效果吗?

能,如果你有时间审查、集成和维护它们的话。GitHub 上的 Open SaaS 是扎实的免费起点。56小时差不是说"开源不好"——是"开源有维护税"。

两人团队的矩阵有区别吗?

可能有。RBAC、部署和 i18n 任务可以在两个工程师之间并行,而 Stripe webhook 幂等性仍是单线程瓶颈。两人团队应预期 solo founder 差值的约60%,不是100%。


把同样的时间拿回来: TanStack Ship 预置了 auth、Stripe、admin、blog、i18n、R2、队列、MRR、UTM 等18个以上模块,接在 TanStack Start + Cloudflare Workers 上。免费入门层级,完整套件一次性299美元。查看功能 → 或 与 ShipFast、Makerkit 对比 →。