AI 写到 25 万行,前端仍用 HTML 字符串
Formgong 作者分享用 AI 编程 Agent 开发约 25.1 万行 TypeScript 应用的经验,页面不依赖 React、Vue 或 Svelte,而由函数返回 HTML。其交互采用表单提交、数据库写入和 303 重定向重新渲染,文章也讨论规模增长后的代价。
AI 深度解读
Formgong 用 AI 编程代理写出了 251,000 行 TypeScript,没有 React、Vue、Svelte,也没有一个 .tsx 文件。页面只是返回 HTML 字符串的函数。但作者的结论有明确前提:当状态留在服务端、页面以表单为主时,AI 能让前端框架成为可选项;页面自己管理复杂状态时,框架仍有价值。
这篇值得读的地方,是它把省下的工作和补上的成本都摊开了:模板代码便宜了,转义、组件一致性和交互维护却不会自动解决。
不用前端框架,页面靠什么运转
Formgong 是一个表单后端产品,还提供管理后台、评价组件和帮助聊天。作者说,项目从 9 月下旬开始增长到了上述规模,原文没有交代具体年份。
先划清范围:他们没有放弃所有框架。服务端使用 Hono,由它负责路由、中间件和请求解析。作者采用的区分是:库由业务代码调用,框架则掌握生命周期,决定何时调用业务代码。按这个标准,React 虽自称库,在常见用法中也承担框架职责。
页面侧的核心是服务端持有状态。用户修改数据时提交 HTML 表单,服务端写数据库,再返回 303 重定向到同一页面,重新读取数据库渲染。仓库里有 260 个这样的表单、180 处这样的重定向。
浏览器不保存一份需要同步的业务数据,因此也就省去了相应的数据绑定。这不是解决了所有状态同步问题,而是通过架构减少了需要同步的状态。

交互由一个 42 KB 的脚本挂接到 data-* 属性上,处理复制按钮、代码标签页、月付与年付切换等功能。脚本没加载时,底下的链接和表单仍能工作。这种设计很适合列表、设置和提交后保存的后台页面。
AI 降低了重复劳动,却没有接管一致性
组件在这里仍然存在,只是形式变了:select()、field()、settingRow()、table()、dialog() 等函数返回字符串,共同放在一个 212 行文件里,此外还有 8 个函数。它们是在开发约一个月、后台已经出现多种略有差异的下拉框后才抽出来的。
这个细节很关键。AI 愿意重复写模板,并不代表它能主动发现重复实现已经分叉。
他们用 AGENTS.md 给代理提供任务前约定,再用测试阻止代码继续偏离。其中一项测试统计视图里的原生 <button>、<select>、<table> 标签,数量超过 366、40、38 就让构建失败,要求新增代码使用组件。
这类「棘轮测试」的大白话解释是:先给已有问题设一个上限,允许逐步减少,但不准继续增加。
他们没有省掉框架维持一致性的工作,而是把这项工作交给了约定、测试和代码审查。
另一笔成本是转义。JSX 会自动转义普通插值内容,他们则手动调用 esc(),目前已有 3,808 次。漏掉一次,就可能产生 XSS 漏洞。仓库中有 44 个测试文件在某处检查转义,但这个数量不能证明所有输出位置都已覆盖。代理不会因为重复调用而厌烦,也仍然可能漏写。
页面开始自己管理状态,边界就出现了
260 个表单对应的是以服务端为中心的主体架构,但项目还有 34 个客户端代码文件,会调用 fetch 并手动更新页面。
其中不少是嵌入客户网站的组件。作者认为,为这些组件携带一个框架并不合适。剩下的则是更接近应用的界面:表单构建器、评价导入向导,以及支持拖拽的邮件编辑器。
邮件编辑器是最明显的边界。他们把一个已有构建器移植成了原生 TypeScript;如果今天重做,作者会考虑为这个文件引入小型响应式库。
原因不难理解:服务端表单提交后可以整页重建,而编辑器需要在连续操作中维护界面状态。多个区域如何随状态变化、如何保持一致,不能靠 AI 更快地写 HTML 来消除。
AI 改变了模板代码的生产成本,没有消除客户端状态管理的复杂度。
我的判断
我认同作者按状态归属选择技术的思路。对以查询、配置、提交为主的后台,服务端渲染加少量脚本是一条成立的路线;Hono 继续承担通用服务端能力,也说明作者并不主张所有东西都自己写。
但 251,000 行是仓库规模,不是效率证明。原文没有提供与 React、Vue 或 Svelte 方案的开发时间、缺陷率、维护成本对照,也没说这部分代码中页面逻辑占多少。因此,「AI 让前端框架可选」有案例支撑,「不用框架更划算」仍属于经验判断。
常见框架把组件复用、渲染更新和默认转义放进统一机制;这套方案则需要团队持续维护自己的组件、规则和测试。AGENTS.md 能表达要求,真正限制偏离的是构建检查与审查。普通团队能否承担这些维护工作,是迁移经验时必须核算的前提。
能拿来做什么
- 给后台页面先按状态归属分类:列表、设置、提交后保存的表单,可以评估服务端渲染;构建器和拖拽编辑器,应单独评估响应式方案。
- 让 AI 写页面时,把组件使用要求写进 AGENTS.md,并用检查阻止新增代码绕过组件。单靠代理每次读约定,不足以保证一致。
- 如果选择 HTML 字符串模板,把动态输出转义列为审查重点,并验证遗漏风险。不要把 esc() 调用次数或测试文件数量当成安全结论。
- 对嵌入客户网站的组件,单独核算脚本体积与交互需求;不要因为后台采用某种方案,就要求所有客户端代码跟随。