没有人第一次就能一鸣惊人。相信我,我见过这个故事无数次上演。一位创始人在随意的周五晚上开始用 Bolt.new 进行试验。到了周一,他们已经有了可行的东西。然后就开始了这场舞蹈:在接下来的十八个月里,他们系统地逐个替换掉每个部分。这不是失败。各位,这就是构建有价值的东西的真正魔力。

我们在这里深入探讨这个历程。忘掉那个一切都计划得面面俱到的完美世界吧。这里会很混乱——你从一些 AI 生成的片段开始,可能会用到 Strapi 这样的无头 CMS。最终,你会落地到那个感觉量身定做的定制方案。在 Social Animal,我们带领过不少客户经历这段混乱。模式往往会浮现出来。通常都会。

From Bolt to Strapi to Custom Architecture: The Real Product Journey

第一阶段:AI 原型时代

这就是 Bolt.new 的情况。它既超级酷,又有点危险。

与 Lovable(前身是 GPT Engineer)、Vercel 的 v0 和 Cursor 等竞争对手一样,Bolt 让你能够在几小时内将一个想法转化为一个运行的应用。不是天。是几小时。我看过创始人在一个下午就搭建起完整的 Next.js 应用程序,带有身份验证甚至支付钩子。

这是 Bolt 生成的代码的一个示例:

// Bolt 生成的 API 路由——看起来很干净,对吧?
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
import { getServerSession } from 'next-auth';

export async function GET(req: NextRequest) {
  const session = await getServerSession();
  if (!session) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
  }
  
  const projects = await prisma.project.findMany({
    where: { userId: session.user.id },
    include: { tasks: true, members: true },
  });
  
  return NextResponse.json(projects);
}

这段代码?它能工作,而且质量不错,特别是对于 2025 年来说。但不要被光滑的语法欺骗。问题从来都不在代码质量,而在于周围的一切。

AI 原型做得好的地方

  • 快速到达第一版本。 没有什么能与之相比。
  • UI 脚手架。 基于 Tailwind 的界面看起来很流畅?这就是 Bolt 的专长。
  • 基本的 CRUD 操作。 对于主要是表格和列表的应用,你都能覆盖。
  • 想法验证。 在几天而不是很长时间内向用户展示你的应用。

他们做得不太好的地方

AI 生成的代码?它对你的独特需求一无所知。不知道你的"项目"实体是一个复杂的野兽,有多个阶段,或者你的层级远不止"管理员"和"用户"。

有一次,我查看了一个 Bolt 生成的建筑项目管理工具。这确实是一个整洁的 CRUD 应用。但没有项目阶段,没有细致的角色,也没有对大数据拉取的分页。快速演示?完美。扩展到 500 个项目和 2,000 个用户?那艘船会沉没。

第二阶段:为什么原型会遇到瓶颈

瓶颈像列车一样向你迎面而来。通常在两到三个月左右,其中一个会让你绊倒:

  1. 内容需求每天都在变化。 营销想随意调整登陆页面。
  2. 数据模型复杂性。 关系、工作流——AI 不会看未来。
  3. 团队成员需要访问权限。 突然,非技术人员需要参与内容工作。
  4. 性能问题。 现实世界的用户、现实世界的数据、现实世界的连接?会暴露出你走过的任何捷径。
  5. 整合需求。 支付、电子邮件、分析、CRM——压力测试在这里发生。

这里经常被忽视的是:原型不是一场失败。 这就像彩排;在展示什么有效、什么需要调整方面无价。

但伙计,我见过团队花半年时间在 AI 代码上修修补补,创建一个技术债的意大利面怪物,而理智的重建只需要两个月。

第三阶段:无头 CMS 折中方案

当你需要的超过原型,但还不准备从零开始构建一切时,这就是你的缺口填补阶段。Strapi 在这里发挥作用。

为什么特别是 Strapi?

我与一堆无头 CMS 选项接触过——Strapi、Contentful、Sanity。以下是 Strapi 的表现:

功能 Strapi Contentful Sanity Payload Directus
自托管选项
开源 部分
自定义字段/插件 优秀 良好 优秀 优秀 良好
学习曲线 中等 中等 中等
定价(2025) 免费自托管,$29/月+ 云版本 $300/月+ $99/月+ 免费自托管,$29/月+ 云版本 免费自托管
API 灵活性 REST + GraphQL REST + GraphQL GROQ + GraphQL REST + GraphQL + 本地 API REST + GraphQL
TypeScript 支持 良好(v5+) SDK 仅 优秀 原生 良好

Strapi 之所以出众是因为它开源、自托管且可定制。非开发者可以参与其中,而无需每五分钟就打电话给开发人员。

在 Social Animal,我们构建了很多无头 CMS 项目。Strapi 通常是我们的首选,除非 Payload 或 Sanity 更适合特定需求。

Strapi 阶段看起来是什么样的

一个真实场景?一个客户使用 Bolt 创建了自由设计师市场。这个东西被硬编码得面目全非,而且缺少博客的 CMS。

我们这样重组了它:

  • 前端: Next.js 15 使用 App Router
  • CMS: Strapi v5 管理内容和用户
  • 数据库: 从 SQLite 切换到 PostgreSQL
  • 身份验证: Strapi 的身份验证用于管理员;NextAuth.js 用于应用
  • 托管: Vercel 上的前端,Railway 上的 Strapi 加 Postgres
// 在 Next.js 服务器组件中从 Strapi 获取
async function getDesignerProfiles() {
  const response = await fetch(
    `${process.env.STRAPI_URL}/api/designers?populate[0]=portfolio&populate[1]=reviews&pagination[pageSize]=20&sort=rating:desc`,
    {
      headers: {
        Authorization: `Bearer ${process.env.STRAPI_TOKEN}`,
      },
      next: { revalidate: 60 }, // ISR:每分钟重新验证
    }
  );
  
  if (!response.ok) throw new Error('Failed to fetch designers');
  
  const data = await response.json();
  return data.data;
}

这个设置让他们能够坚持大约八个月。他们从 50 个用户增长到 2,000 个用户,并无缝地管理内容。管理团队无需一通开发人员电话就能跟上。

成本?大约 $150/月加上他们在初始开发上花费的任何费用。

From Bolt to Strapi to Custom Architecture: The Real Product Journey - architecture

第四阶段:当 Strapi 不再足够

Strapi 在你的逻辑超出简单内容 CRUD 之前闪闪发光。当你的应用业务逻辑比包里底部的耳机还要缠绕时,是时候考虑更大的东西了。

自定义业务逻辑变得尴尬

使用 Strapi,自定义规则被硬塞进生命周期钩子中:

// 这是一个真实的 Strapi 生命周期钩子,变得失控了
// 不要这样做。
module.exports = {
  async afterCreate(event) {
    const { result } = event;
    
    // 计算设计师评分
    const reviews = await strapi.entityService.findMany('api::review.review', {
      filters: { designer: result.designer.id },
    });
    const avgRating = reviews.reduce((sum, r) => sum + r.rating, 0) / reviews.length;
    
    // 更新设计师档案
    await strapi.entityService.update('api::designer.designer', result.designer.id, {
      data: { rating: avgRating, reviewCount: reviews.length },
    });
    
    // 发送通知电子邮件
    await strapi.plugins['email'].services.email.send({
      to: result.designer.email,
      subject: 'New Review',
      text: `You received a ${result.rating}-star review!`,
    });
    
    // 更新搜索索引
    await updateAlgoliaIndex('designers', result.designer.id, { rating: avgRating });
    
    // 检查设计师是否符合精选状态的条件
    if (avgRating >= 4.8 && reviews.length >= 10) {
      await strapi.entityService.update('api::designer.designer', result.designer.id, {
        data: { featured: true },
      });
      // 通知营销团队
      await notifySlackChannel('marketing', `${result.designer.name} is now featured!`);
    }
  },
};

看到了吗?一个简单的 after-create 钩子爆炸成了怪物——评分、电子邮件、搜索更新、团队通知。维护起来不有趣。

性能天花板

Strapi 是为内容设计的,不是为繁重的数据运算或复杂查询。一旦事物规模化,你最终会编写原始 SQL 来绕过她的限制。老实说?当事情到了这一步时,你在质疑为什么还在使用她。

API 表面超出内容增长

需要 WebSocket、后台作业或自动 webhook?就像试图把方形钉子塞进圆孔。

第五阶段:正确完成的定制架构

这是我们拿出大枪的时候。你现在了解你的领域;你已经看到了用户喜欢什么。是时候进行那个定制设置了。

不过不是从零开始。

以下是我们如何加快那个相同市场的速度的方式:

┌─────────────────────────────────────────────────────┐
│                    前端层                             │
│  Next.js 15(App Router)+ React 服务器组件         │
│  部署在 Vercel(边缘 + 无服务器)                     │
├─────────────────────────────────────────────────────┤
│                     API 层                           │
│  tRPC 用于类型安全的内部 API                          │
│  REST webhook 用于第三方集成                          │
│  WebSocket 服务器(Fly.io 上的 Hono)用于实时       │
├─────────────────────────────────────────────────────┤
│                   服务层                             │
│  身份验证:Clerk(从 DIY 迁移——每分钱都值得)      │
│  支付:Stripe Connect(市场支付)                    │
│  搜索:Typesense(替代 Algolia——便宜 90%)          │
│  电子邮件:Resend + React Email                      │
│  作业:Trigger.dev(后台处理)                       │
│  CMS:Sanity(仅编辑内容)                           │
├─────────────────────────────────────────────────────┤
│                    数据层                             │
│  Neon 上的 PostgreSQL(无服务器,分支)              │
│  Drizzle ORM(类型安全,高性能)                     │
│  Upstash 上的 Redis(缓存、速率限制)                │
└─────────────────────────────────────────────────────┘

注意 Sanity 仍然存在。它非常适合处理编辑部分。同时,所有繁重的产品数据都落脚在好老的 PostgreSQL。

要点是什么?需要的地方使用定制应用,有意义的地方使用 CMS。他们是不同的;这样对待他们。我们经常将此架构与Next.js 项目用于内容丰富的网站的 Astro 配对。

每个阶段的成本现实

钱会说话,所以让我们直言不讳地说出来:

阶段 时间表 开发成本 月度基础设施 月度 SaaS
Bolt 原型 1-2 周 $0-500(你的时间) $0-20(Vercel 免费层) $20(Bolt Pro)
Strapi + Next.js 4-8 周 $15,000-40,000 $50-200 $0-100
定制架构 8-16 周 $40,000-120,000 $200-800 $200-600
扩展定制 持续 $5,000-20,000/月(团队) $500-5,000 $500-2,000

真实数字,没有虚张声势。规则是什么?每个阶段都应该通过上一阶段的收入或见解为自己买单。 在你准备好之前,永远不要把你的积蓄花在梦想设置上。

如果你需要帮助理解你处于哪个阶段,让我们聊天——看看我们的定价概述

如何知道什么时候该往前迈进

这个很棘手,但这里有一些危险信号:

从原型到无头 CMS

  • 你仍然在为内容调整编辑原始 JSON 或 HTML。
  • 非技术团队成员被卡住,等待开发管道。
  • 你的应用看起来像一个巨大的复制粘贴工厂。
  • 你仍然在使用 SQLite 或者,天哪,JSON 文件。
  • 你已经用真实用户验证了你的想法。

从无头 CMS 到定制架构

  • 你的 Strapi 设置因自定义代码而满负荷。
  • 你在 CMS 外部直接戳数据库。
  • 即使在温和的流量下性能也会下降。
  • 复杂的需求将 CMS 变成了一个缠绕的混乱。
  • 良好的收入反映了更好的可扩展性的需要。

真正重要的技术栈决策

经过了所有这些,一些选择的重要性比你想的要大。

重要的决策

数据库选择。 PostgreSQL 十次中有九次获胜,除非你有该死的好理由去别处。

身份验证。 永远不要自己动手。无论是 Clerk、Auth.js 还是 Supabase,价格相对于潜在陷阱都微不足道。

托管模型。 无服务器对一般使用来说很棒,除非实时应用需要更强大的东西。

尚未重要的决策

CSS 框架。 选一个就去做。Tailwind、CSS Modules,随便——你以后总能交换。

状态管理。 React 服务器组件缓解了争论。在绝对需要之前,不要拖入额外的套件。

Monorepo 工具。 一旦你需要它,好吧,可以,但不要在第一天就陷入其中。

黄金法则很简单:"为今天的速度构建,为明天的选项保持开放。" 没有银弹,只有明智的决策制定。如果你正在这些水域中航行,想要一个老手站在你身边,联系我们。我们在这个街区转过很多圈,可能会让你避免一些陷阱。

常见问题

我应该从 Bolt.new 开始还是从一开始就正确构建? 如果你仍在测试想法,可以从 Bolt 或类似的东西开始。这是在不烧钱的情况下快速验证你的想法并做出果断转向的最快方法。

Strapi 在 2025 年仍然值得使用,因为 Payload CMS 获得了这么多关注? 当然,两者都有各自的优点。Strapi v5 的改进使其成为一个坚实的竞争者。不过,对于一个以 Next.js 为中心的产品,Payload 可能有优势。

从 Strapi 迁移到定制架构需要花多少钱? 对于典型的 SaaS 设置,预计 $40,000-$120,000。复杂性和数据迁移需求会影响时间和成本。

Bolt.new 能生成生产就绪的代码吗? 这是一个起点,不是终点。使用 Bolt 进行原型设计,并计划随后加强和改进代码。

团队在这个进程中犯的最大错误是什么? 在一个阶段卡太久。当问题出现时你会看到——不要忽视他们。

我应该使用无头 CMS 还是构建自定义管理面板? 除非你的管理系统是核心产品,否则从 CMS 开始。构建一个精抛的行政后端是耗时且昂贵的。

我如何说服我的技术联合创始人停止在原型上构建? 量化它。绘制错过的截止日期、低效率,以及新功能如何演变成苦役。以速度而不是自大的案例。

有可能完全跳过无头 CMS 阶段吗? 是的,但很少见。你需要坚如磐石的技术领导力和对你的需求的铁石心肠理解才能直接跳到定制——通常仅适用于小众开发工具或交互式应用。