Show HN:NoDiff,一个运行在 monorepo 中的框架
NoDiff 是一个极简 TypeScript 框架,将 TSX 视为浏览器原生语法,直接创建真实 DOM 节点,无需 React、虚拟 DOM 或调度器。它提供状态绑定、zod 校验、缓存、认证、路由和表单等功能,并采用 fork-first 的 monorepo 工作流,让框架与应用同步演化。
NoDiff 是一个正在开发中的轻量 TypeScript 框架,目标是为富客户端应用提供“刚好够用”的运行时。它把 TSX 当作浏览器的语法来使用:通过 Vite 编译后,JSX 会变成对 @nodiffjs/core/jsx-runtime 的调用,这些调用直接创建 HTMLElement 实例,并完成属性设置、事件绑定和子节点挂载,整个过程不产生虚拟 DOM,也不做 diff 或组件重放。
这个项目采用 fork-first 的 monorepo 结构,仓库里同时包含框架包 packages/nodiff(发布名为 @nodiffjs/core)和演示应用 apps/demo。开发时,演示应用通过 Vite 和 TypeScript 别名把 @nodiffjs/core 指向 packages/nodiff/src,因此修改框架源码和应用代码可以在同一个工作区里即时热更新;构建产物 dist 则被保留为发布/消费前的检查。作者认为,在 LLM 时代,应用和框架同库演化更容易被开发者或编码代理理解、修改和推理。
NoDiff 刻意利用浏览器原生能力,包括 DOM 树、事件监听、表单校验、fetch、AbortController、localStorage、history/hashchange 和原生模块,只补充一层干净的 TypeScript 接口。它提供 JSX 运行时、mount/append 等 DOM 工具、生命周期清理、文本/区域/列表状态绑定,并兼容 zustand/vanilla 这类 store。数据层支持 zod 解析的 API 客户端、带 TTL 的 localStorage 缓存、token 认证、资源状态机,还包含哈希/历史路由、zod 表单和 CSRF 辅助。核心判断是:即使没有 React,TSX 依然很有用。
安全方面,NoDiff 默认把“安全路径”变短:DOM 文本通过构造转义,拒绝 innerHTML,除非显式用 trustedHTML 或 sanitizeHTML;URL 属性会做 scheme/origin 检查,CSS 执行点被禁用,_blank 链接自动加 noopener noreferrer。configureSecurityPolicy 可以安装全局策略,createApi 会限制跨域 auth 头、强制请求超时和缓存 schema,createAuth 默认只在内存保存 token,持久化需要显式开启。渲染错误和路由异常默认显示脱敏信息,避免泄露堆栈。
演示应用围绕 JSONPlaceholder 构建,路线包括 / 首页状态绑定、/posts 的 zod 校验与缓存、/auth 的模拟登录以及 /cache 的缓存检查。README 还附带教程,从创建 zustand/vanilla store、用 TSX 渲染真实 DOM、text 绑定文本、view/For 重绘区域,到用 zod 解析 API 数据,逐步建立心智模型。工具链方面,项目使用 Bun workspaces、Vite 8、TypeScript 7 native preview、oxlint 和 oxfmt,并提供了 typecheck、lint、format、security:check 等脚本。