模型 / 数据集
Simon-He95/markstream-vue avatar
Simon-He95/markstream-vue

markstream-vue 评测:为 AI 流式输出而生的 Markdown 渲染器

Multi-framework streaming Markdown renderers for AI apps: Vue/Nuxt, React/Next.js, Svelte, and Angular, with Mermaid, KaTeX, stream-diffs code blocks, safe HTML, and low-jitter updates.

3,009 个 Star182 个 ForkVueMIT

秒懂

它是什么?
markstream-vue 是一套面向 AI 聊天场景的流式 Markdown 渲染器,覆盖 Vue、React、Svelte 等框架。它解决的是不完整 Markdown 在阅读过程中的稳定渲染问题,但引入它意味着要放弃传统文档渲染器的简单替换逻辑。
适合谁用?
如果你的应用正在接收 LLM 的 token 流、SSE 或 WebSocket 输出,并且用户会直接阅读尚未写完的 Markdown,那么 markstream-vue 值得作为首选方案。它把流式状态、代码块 diff 和 Mermaid 图表的渐进渲染都打包好了,省去自研解析器的成本。
能商用吗?
可以。MIT 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
还在维护吗?
在维护。仓库最近一次提交在 2 天前。
用什么语言写的?
主要是 Vue(依据 GitHub 的语言统计)。

以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。

开源项目深度解析

传统 Markdown 渲染器的盲区

marked、markdown-it 和 react-markdown 都假设输入是一份完整的文档。它们把字符串一次性解析成 AST,再渲染成 DOM,整个过程没有中间状态。这在处理静态文档时没有问题,但 AI 聊天场景完全不同。LLM 的 token 流是逐段到达的,用户看到的 Markdown 永远处于半成品状态。一个未闭合的代码块、一个写到一半的表格、一个还在生成中的 Mermaid 图表,如果按传统方式反复整体重渲染,页面会闪烁,滚动位置会跳动,代码块的高亮也会在每次增量更新时重新计算。markstream-vue 就是针对这个缺口设计的。它不是一个通用 Markdown 渲染器,而是一个专门处理持续变化内容的渲染器。README 明确区分了使用场景:处理完整文档用 marked 或 markdown-it,处理正在被用户阅读的流式内容才用 Markstream。

流式渲染的核心机制

这个项目的关键设计是把 final 状态和流式状态分开处理。组件接受的 props 是 content 和 isDone,后者在 README 的示例中对应 final 属性。当 final 为 false 时,渲染器知道内容还在增长,它会维护一个稳定的部分 Markdown 状态,而不是每次收到新 token 就推倒重来。这种做法的直接收益是低抖动更新,也就是页面不会因为内容频繁变化而出现明显的视觉跳动。另一个重要机制是渐进式重块渲染。Mermaid 图表和 KaTeX 公式都属于重计算单元,如果每次都完整执行,流式输出的每一帧都会卡顿。Markstream 的处理方式是让这些块在内容稳定后才逐步渲染,而不是边输入边渲染。对于代码块,2.x 版本移除了 Monaco 和 stream-markdown 运行时,改为可选的 stream-diffs peer 依赖,这意味着基础版本只处理普通代码块的流式显示,增强的 diff 功能需要额外安装。

安装与最小可用代码

安装命令是 pnpm add markstream-vue,如果只需要基础功能,不需要任何额外依赖。需要增强代码块和 diff 功能时,才安装 stream-diffs peer。README 给出的最小 Vue 3 用法非常直接:先引入组件和样式文件 markstream-vue/index.css,然后传入 content 和 isDone 两个 props。组件内部通过 mode="chat" 激活聊天模式。一个值得注意的细节是,1.x 版本仍然维护,通过 markstream-vue@1 安装,npm 的 legacy 标签也保留了这个版本线。如果项目已经在 1.x 上运行且不想立即迁移到 2.0,可以锁定版本号。但 2.0 的代码块运行时变化是破坏性的,升级前必须阅读迁移指南。对于 Vue 2 项目,有独立的 markstream-vue2 包,版本号与主包保持同步,例如 2.0.11 同时发布了 markstream-vue 和 markstream-vue2。

多框架家族的结构与代价

这个仓库不是一个单一包,而是一个渲染器家族。除了 Vue 3 版本,还有 markstream-react、markstream-svelte、markstream-angular,甚至 markstream-octane 对应 Octane 框架。每个框架的安装命令和文档入口都独立存在。这种做法的好处是每个包可以针对框架特性做优化,比如 Svelte 5 的响应式模型和 Angular standalone 的组件体系。但代价也很明显:版本同步是一个持续负担。从发布记录看,2.0.11 在同一天发布了 markstream-vue、markstream-vue2 和 markstream-svelte,但无法确认所有包每次都保持完全一致的版本号。如果你在一个 monorepo 里同时使用 Vue 和 React,需要跟踪两个包的独立发布节奏。另外,框架无关的解析逻辑被拆到了 stream-markdown-parser,流式控制器工具在 markstream-core,这意味着一个完整方案可能涉及多个包的组合。

安全策略与渲染边界

AI 生成的内容天然不可信,LLM 可能输出任意 HTML 标签或 JavaScript 片段。markstream-vue 提供了 safe HTML 策略,README 将其列为稳定接口的一部分。这意味着默认情况下,渲染器不会直接输出未经处理的 HTML,而是有一套白名单机制。具体的过滤规则在 README 中没有展开,但既然它被列为 stable surface,可以推断有一套明确的策略文件或配置项。对于 Mermaid 和 KaTeX,它们是可选功能,这暗示默认包体积不会包含这两者的完整实现。如果你需要图表和公式渲染,需要确认具体的启用方式。安全方面的另一个问题是代码块中的内容,特别是 stream-diffs 增强的 diff 块,它们可能包含特殊字符,渲染器需要正确处理转义,避免破坏页面结构。文档没有详细说明这些边界情况,实际使用前需要查看文档站点的安全策略页面。

与 marked 和 Streamdown 的真实差异

README 提供了多条对比文档链接,包括与 vue-stream-markdown、Streamdown、react-markdown 以及 marked 和 markdown-it 的比较。与 marked 的差异是根本性的:marked 是同步解析完整字符串,输出静态 DOM,它不理解流式内容的概念。如果强行用 marked 处理流式输出,每次新增 token 都要重新解析整个文档,性能会随内容长度线性恶化。Streamdown 是另一个流式 Markdown 方案,README 没有给出具体的技术差异,只提供了对比页面。react-markdown 则受限于 React 的渲染模型,它适合一次性渲染,但在流式场景下需要外部管理增量状态。markstream-vue 的价值在于它把流式状态管理内建到了组件里,开发者不需要自己设计 diff 算法或增量渲染逻辑。但这也意味着它比传统渲染器更重,引入了一个额外的抽象层。如果你的 AI 输出只是偶尔流式,大部分时间是完整文档,混合使用两种渲染器可能是更务实的选择。

版本策略与长期维护判断

2.x 版本被标记为 stable,发布在 npm 的 latest 标签上。1.x 版本线仍然维护,通过 legacy 标签访问。这种双版本线策略在开源项目中并不常见,说明作者对既有用户有兼容性承诺。但 2.0 的变更并不小:移除了 Monaco 和 stream-markdown 代码块运行时,这是一个实质性的架构调整。Monaco 是微软的代码编辑器,把它从依赖中移除意味着包体积大幅下降,但也意味着代码块编辑能力不再内建。如果你之前依赖 Monaco 提供的交互功能,升级后需要自行处理。仓库的最近提交时间是 2026 年 9 月,说明项目仍在活跃维护。MIT 许可证没有附加限制,商用和修改都允许。但多框架包意味着维护者需要同时跟进 Vue、React、Svelte、Angular 的版本更新,任何框架的重大变更都可能影响对应的包。在采用前,检查各包的最后发布时间是否与主包一致,可以判断维护是否均衡。

编辑结论

如果你的应用正在接收 LLM 的 token 流、SSE 或 WebSocket 输出,并且用户会直接阅读尚未写完的 Markdown,那么 markstream-vue 值得作为首选方案。它把流式状态、代码块 diff 和 Mermaid 图表的渐进渲染都打包好了,省去自研解析器的成本。如果你的场景只是渲染一篇已经完整的 Markdown 文档,或者你的团队对包体积和依赖数量极其敏感,那么 marked 或 markdown-it 仍然更合适,它们没有流式状态的概念,也不会有 2.x 版本移除 Monaco 运行时的这类破坏性变更。在决定采用前,先确认你的代码块需求:如果只是普通代码高亮,基础版本足够;如果需要 stream-diffs 的增强代码块和 diff 功能,必须额外安装该 peer 依赖,并阅读迁移指南确认 2.0 的运行时变化。另外,MIT 许可证允许商业使用,但你需要自行评估多框架包(React、Svelte、Angular)与主包之间的版本同步风险,因为它们的发布节奏并不完全一致。

官方来源

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. Simon-He95/markstream-vue on GitHub
社区笔记

社区笔记