Markdown 项目别再混着看:remark、rehype 和 ByteMD 的真实分工

发布于 2026年05月29日 01:15 #DevOps#Github

Markdown 项目别再混着看:remark、rehype 和 ByteMD 的真实分工 封面图

大家好,我是若风。

前几天我在看一类 Markdown 项目,本来只是想顺手梳理一下编辑器选型,结果越看越觉得,很多人其实把几个完全不同层级的东西混在一起了。

看到 remark,说这是 Markdown 渲染器。看到 rehype,说这也是 Markdown 插件。看到 ByteMD,又说这不就是另一个 Markdown 编辑器吗?

说实话,这种混淆挺正常。因为它们都出现在 Markdown 工具链里,名字又都短,README 里也经常同时出现 pluginprocessoreditor 这些词。读 3 个项目很快,真正麻烦的是把它们放回同一张工程地图里。

表面上看,它们都在处理 .md。真正关键是,它们站的位置完全不一样。

如果只用一句话概括:

remark 和 rehype 是内容处理管线,ByteMD 是面向用户的编辑器组件。前者关心 AST 怎么流动,后者关心人怎么写、怎么预览、怎么扩展。

先把位置摆清楚

可以先看一张表。

项目核心对象处理阶段典型用途
remarkMarkdown AST,也就是 mdastMarkdown 解析、检查、改写、再输出GFM、frontmatter、lint、目录生成、Markdown 到 HTML
rehypeHTML AST,也就是 hastHTML 解析、检查、改写、再输出sanitize、slug、代码高亮、HTML 压缩、HTML 到组件
ByteMD编辑器和预览 UI用户输入、编辑、预览、插件集成在 React、Vue、Svelte、Angular 里嵌入 Markdown 编辑器

这张表基本就够用了。我倒是觉得,先把这 3 个位置摆清楚,比一上来追 API 更重要。

remark 解决的是「Markdown 作为结构化数据怎么处理」。rehype 解决的是「HTML 作为结构化数据怎么处理」。ByteMD 解决的是「给用户一个可用、可扩展、能预览的 Markdown 编辑器」。

这三个项目可以在同一个产品里合作,但它们不是同一种东西。

remark:它不是编辑器,而是 Markdown 管线

remark 官方对自己的定义很直接:一个由插件驱动的 Markdown processor,属于 unified collective。

这句话听起来有点抽象,翻译成人话就是:它把 Markdown 解析成一棵树,然后让插件在这棵树上做事。

比如一段 Markdown:

## Hello *Markdown*

remark 里,它不会只被当成一段字符串,而会变成类似这样的结构:

{
  "type": "heading",
  "depth": 2,
  "children": [
    { "type": "text", "value": "Hello " },
    { "type": "emphasis", "children": [{ "type": "text", "value": "Markdown" }] }
  ]
}

这就是 mdast 的价值。你想把所有一级标题降成二级标题,想自动生成目录,想检查链接,想支持 GFM 表格,想读取 frontmatter,本质上都是在这棵树上做转换。字符串时代会让你焦虑的正则边界,到了 AST 时代会清爽很多。

所以 remark 的重点不是「把 Markdown 展示出来」,而是给 Markdown 建一条可编排的处理流水线。

这也是为什么 Astro、MDX、Docusaurus、Next.js 博客生态里经常能看到 remark-* 插件。它们通常在内容还处于 Markdown 阶段时动手。比如:

  • remark-gfm:支持 GitHub Flavored Markdown
  • remark-frontmatter:识别 YAML frontmatter
  • remark-toc:生成目录
  • remark-rehype:把 Markdown AST 转成 HTML AST

注意最后这个点。remark-rehype 是桥。

它把 Markdown 世界接到 HTML 世界。

rehype:它接管的是 HTML 阶段

rehyperemark 很像,但对象换了。

remark 处理 Markdown AST,rehype 处理 HTML AST。

如果说 remark 站在内容源头,关心「作者写了什么 Markdown」,那 rehype 更靠近渲染结果,关心「最终 HTML 应该长什么样」。

比如一篇文章已经从 Markdown 变成了 HTML 结构:

<h2>Hello Markdown</h2>
<p>Visit <a href="https://example.com">example</a>.</p>

进入 rehype 以后,插件可以做很多渲染层面的事:

  • 给标题加 id,方便锚点跳转
  • 给外链加 target="_blank"rel
  • 清理不安全 HTML,避免 XSS
  • 给代码块做高亮
  • 压缩 HTML
  • 把 HTML AST 转成 React、Vue、Svelte 等组件

这就是 hast 的价值。

很多人第一次接触 remark / rehype 会觉得绕:为什么 Markdown 不能一步到 HTML?为什么要分 mdasthast

原因其实很工程化。Markdown 和 HTML 的问题域不一样。坦白讲,这也是我后来对 unified 生态改观的地方,它不是为了显得高级才引入 AST,而是在给插件复用留边界。

Markdown 阶段适合处理作者意图,比如标题层级、列表、引用、frontmatter、任务列表。HTML 阶段适合处理页面结构,比如链接属性、元素安全、代码高亮、组件输出。两者硬揉在一起,插件会变得很难复用,也很容易在错误阶段做错误的事。

我之前在这个博客里修过一个类似问题:想让一段 Markdown 内容不渲染,最稳的方案不是等到 HTML 阶段再删,而是在 remark 阶段直接删掉 AST 范围。因为等到 rehype 阶段,很多 Markdown 内容早就被拆成独立节点了。

这就是两个阶段的边界感。

ByteMD:它不是普通渲染器,而是编辑器产品底座

再看 ByteMD

ByteMD 的定位就完全不同了。它是一个 Markdown editor component,核心是编辑器和预览器,而不是底层语法树处理库。

官方 README 里有几个关键词很重要:

  • built with Svelte,但可以用于 React、Vue、Angular 等框架
  • 轻量,编译后不依赖某个 UI 框架运行时
  • 有插件系统,可以扩展代码高亮、数学公式、Mermaid、GFM 等能力
  • 默认处理 XSS 风险
  • 支持 SSR

这意味着 ByteMD 解决的是产品层问题。

普通的 Markdown 开源项目,常见有三类:

第一类是 parser / renderer。它关心 Markdown 怎么变成 HTML,比如 markdown-itmarked 这类项目。

第二类是 processor / plugin ecosystem。它关心内容怎么在 AST 管线里被解析、检查、改写,比如 remarkrehype

第三类是 editor component。它关心用户怎么输入、怎么预览、怎么插插件、怎么嵌进你的业务系统。ByteMD 属于这一类。

所以 ByteMD 和「普通 md 开源项目」最大的不同,不在于它也支持 Markdown,而在于它把 Markdown 能力包装成了一个可嵌入的编辑体验。你不是拿到一把螺丝刀,而是拿到一块能直接塞进后台系统的编辑区域。

一个普通 Markdown parser 给你的通常是一个函数:

const html = render(markdown)

ByteMD 给你的更像是一块产品积木:

<Editor value={value} plugins={plugins} onChange={setValue} />
<Viewer value={value} plugins={plugins} />

差异就在这里。

parser 处理文本,processor 处理树,editor 处理人。

ByteMD 比普通 Markdown 编辑器多了什么

ByteMD 还有一个值得注意的点:它不是只做一个「textarea + preview」。

它把几个工程问题一起打包了。

第一,是跨框架包装。

ByteMD 本体用 Svelte 构建,但提供了 React、Vue 2、Vue 3 等包。对业务团队来说,这很实用。你不用因为项目是 React 就重写一套编辑器逻辑,也不用因为迁移 Vue 版本就完全换工具。

第二,是插件模型。

Markdown 编辑器真正麻烦的地方,从来不是基础语法,而是业务扩展。代码高亮、公式、Mermaid、frontmatter、GFM、emoji、图片上传、自定义工具栏,这些才是长期维护成本。

ByteMD 的插件系统把这些能力放在一个统一入口里。你不是到处 patch 编辑器,而是围绕插件扩展。

第三,是安全默认值。

Markdown 编辑器如果允许预览 HTML,就绕不开 XSS。ByteMD 明确把 <script><img onerror> 这类风险纳入默认处理。对一个要嵌进后台、CMS、知识库的编辑器来说,这不是锦上添花,而是底线。

第四,是 SSR 兼容。

很多 Markdown 编辑器默认假设自己只跑在浏览器里,一碰到 SSR 就要加动态导入、关闭服务端渲染,最后项目里多出一堆奇怪判断。ByteMD 把 SSR 当作目标之一,说明它不是玩具级组件,而是面向真实应用集成。

不过也要注意一个现实:pd4d10/bytemd 当前 README 已经标明这是 ByteMD v1 repository,v2 正在 HashMD 下开发。也就是说,选型时不能只看 ByteMD 这个名字,还要看你要的是稳定 v1,还是愿意跟进 HashMD 的后续路线。

真正的选择题:你到底要解决哪一层问题

如果你在做一个博客系统,选择路径大概是这样的。

你只是要把 Markdown 渲染成 HTML,可以先看 markdown-itmarked,或者直接用框架内置能力。

你要对 Markdown 做结构化处理,比如自动补目录、改写图片路径、检查链接、处理 frontmatter,那就看 remark

你要处理最终 HTML,比如 sanitize、标题锚点、代码高亮、外链属性,那就看 rehype

你要给用户一个编辑器,让他能写 Markdown、实时预览、插入插件、集成到 React / Vue 后台,那就看 ByteMD 或 HashMD 这一类 editor component。

很多技术选型踩坑,问题不在工具不好,而在把层级选错了。

你想修水管,却买了一套餐桌。

最后说两句

回到这三个项目。

截至我写这篇文章时,GitHub 上的数据大致是:

  • remarkjs/remark:约 8.9k stars,Markdown processor powered by plugins
  • rehypejs/rehype:约 2.2k stars,HTML processor powered by plugins
  • pd4d10/bytemd:约 1.3k stars,ByteMD v1 repository
  • pd4d10/hashmd:约 4.3k stars,ByteMD v2 方向的 Hackable Markdown Editor and Viewer

这组数据也挺有意思。

remark 的影响力更像基础设施,因为它被大量内容系统、文档系统、MDX 工具链间接使用。rehype 的存在感稍低,但它在 HTML 阶段非常关键。ByteMD / HashMD 则更靠近最终用户体验,它的价值不是生态底层,而是把这些能力包装成一个能用、能嵌、能扩展的编辑器。

所以,下次再看到 Markdown 开源项目,可以先问一个问题:

它是在处理文本,处理树,还是处理人的编辑体验?

这个问题一问,很多项目的差异就清楚了。

总结一下,remark 是 Markdown 的结构化处理层,rehype 是 HTML 的结构化处理层,ByteMD / HashMD 是把 Markdown 能力产品化的编辑器层。

选型时别急着问「哪个更强」。先问自己一句:我现在卡住的是文本转换、AST 管线,还是用户编辑体验?

答案一变,工具就会跟着变。

评论互动

© 2026 王若风的技术博客 · Powered by Astro