比较 CodeMirror ProseMirror Tiptap
比较 CodeMirror ProseMirror Tiptap
全方位比较 ProseMirror 和 CodeMirror
by deepseek-v4-search
核心定位:文档编辑器 vs 代码编辑器
ProseMirror 和 CodeMirror 虽然都由 Marijn Haverbeke 创建,但它们的核心定位截然不同:
- ProseMirror:是一个用于构建富文本编辑器(WYSIWYG)的框架,面向的是像文档、博客、协同办公这类结构化内容的编辑场景。
- CodeMirror:是一个代码编辑器组件,专门为编辑代码、HTML、配置文件等纯文本内容而生。
两者最根本的区别在于数据模型:
- ProseMirror 将内容视为树形结构的节点树(如段落、标题、列表)
- 而 CodeMirror 将内容视为扁平的字符串(按行分割存储)
架构与设计哲学
ProseMirror:乐高积木式的结构化框架
ProseMirror 并非一个开箱即用的编辑器,而是一套底层工具集,强调模块化与完全控制权。其核心模块包括:
| 模块 | 职责 |
|---|---|
prosemirror-model | 定义文档的 Schema(节点类型与结构约束) |
prosemirror-state | 管理编辑器状态(文档内容、选区等)与 Transaction |
prosemirror-view | 渲染 UI 并处理用户交互 |
prosemirror-transform | 提供文档变换能力,支撑撤销重做与协同编辑 |
开发者需要通过 Schema 严格定义文档允许包含的元素及其关系。所有编辑操作都被抽象为 Transaction(事务),便于记录、回放和合并。这种设计非常适合需要精确控制文档结构的场景。
CodeMirror:函数式核心与插件化扩展
CodeMirror 6 采用模块化设计,核心约 15KB,功能通过扩展(Extensions) 按需组合。其架构遵循 "函数式核心,命令式外壳" 原则:
- State 层(
@codemirror/state):不可变的数据结构,表示文档和编辑器状态 - View 层(
@codemirror/view):负责渲染和用户交互 - 语言包(如
@codemirror/lang-javascript):提供语法高亮和智能缩进
使用 CodeMirror 6 构建一个基础编辑器非常简洁:
import {EditorState} from "@codemirror/state"
import {EditorView, keymap} from "@codemirror/view"
import {defaultKeymap} from "@codemirror/commands"
let view = new EditorView({
state: EditorState.create({doc: "Hello World", extensions: [keymap.of(defaultKeymap)]}),
parent: document.body
})对比
数据模型与内容处理对比
| 维度 | ProseMirror | CodeMirror |
|---|---|---|
| 数据模型 | 树形结构的节点(Node)与标记(Mark) | 按行分割的扁平字符串 |
| 内容类型 | 结构化富文本(标题、列表、表格、图片等) | 纯文本 / 代码 |
| 文档约束 | 通过 Schema 严格定义允许的元素与关系 | 无结构约束 |
| 选区模型 | 基于节点树的选区 | 基于字符位置的选区 |
核心能力对比
ProseMirror 的优势:
- 协同编辑:内置基于 OT(操作转换)的协同编辑模型,支持多用户实时协作
- 文档结构控制:可精确控制文档的每个元素及其关系,适合复杂文档模型
- 不可变数据与事务:所有修改通过 Transaction 进行,便于实现撤销、重做和版本控制
CodeMirror 的优势:
- 虚拟滚动:仅渲染视口内的内容,支持数十万行代码的流畅编辑
- 语法高亮:支持 130+ 种编程语言,开箱即用
- 增量解析:基于
@lezer的增量语法分析,编辑时只重新解析变化部分 - 移动端友好:基于
contenteditable,在 iOS 等移动设备上表现良好
性能对比
ProseMirror 的性能特点
- 全量渲染:每次更新都需要整个文档树在内存中并挂载为 DOM
- 文档规模限制:在 50,000 行的大型文档中,输入和换行会出现明显卡顿
- 优化手段:通过增量更新(仅重绘变更节点)、虚拟滚动和操作批处理来优化性能
CodeMirror 的性能特点
- 视口渲染:只渲染可见区域的内容,文档规模对性能影响极小
- 线性扩展:大量编辑器实例的创建时间呈线性增长,而非指数级
- 轻量级:压缩后约 100KB,核心仅 15KB
适用场景
ProseMirror 适合的场景
- 富文本编辑器:如博客后台、CMS 内容编辑、在线文档
- 协同办公:多人实时协作的文档、表格、PPT 等(如金山文档底层采用 ProseMirror)
- 复杂文档结构:需要精确控制文档元素类型和关系的场景(如学术论文、法律文书)
- 自定义文档模型:需要定义完全自定义的节点类型和标记
CodeMirror 适合的场景
- 代码编辑器:IDE 中的代码编辑、在线编程工具
- 配置文件编辑:JSON、YAML、XML 等配置文件的编辑
- Markdown 源码编辑:纯粹的 Markdown 文本编辑
- 表单中的文本输入:需要语法高亮但不需要富文本格式的场景
- 移动端 Web 应用:对移动端兼容性有要求的场景
学习曲线与开发体验
ProseMirror:陡峭但强大
ProseMirror 的学习曲线非常陡峭。开发者需要理解 Schema、Transaction、View、Plugin 等一系列抽象概念。从零开始构建一个可用编辑器,需要自行实现 marks、nodes、commands、keymaps、input rules、paste handling 等大量功能。
正因如此,绝大多数开发者不应直接使用 ProseMirror,而应选择基于 ProseMirror 的上层封装,如 Tiptap。Tiptap 提供了开箱即用的扩展(表格、协作、评论、@提及等),让开发周期从数月缩短到数周。
CodeMirror:相对平缓
CodeMirror 6 的 API 设计较为清晰,开箱即用。通过 basicSetup 可以快速获得一个功能完整的代码编辑器。扩展系统虽然需要一定时间理解,但一旦掌握,扩展编辑器会非常有趣。
生态系统
| 维度 | ProseMirror | CodeMirror |
|---|---|---|
| 上层封装 | Tiptap、Milkdown 等 | HyperMD(已停止维护) |
| 官方扩展 | 协同编辑、撤销历史、输入宏等 | 语言包(130+)、括号匹配、自动补全等 |
| 社区生态 | Tiptap 生态有 100+ 扩展 | 丰富的第三方插件和主题 |
| TypeScript | 原生 JS,类型支持一般 | 原生 TypeScript 编写 |
如何选择?
选择 ProseMirror(建议通过 Tiptap)如果:
- 你需要构建富文本/WYSIWYG 编辑器
- 内容具有复杂的结构化需求(标题、列表、表格、图片等)
- 需要多人实时协同编辑功能
- 你需要对文档模型有完全的控制权
选择 CodeMirror 如果:
- 你需要编辑代码、配置文件或纯文本
- 内容没有复杂的结构,只需要语法高亮
- 文档可能非常庞大(数万行以上)
- 你需要移动端友好的编辑器
- 你希望快速集成,开箱即用
特别提醒
- 如果选择了 ProseMirror,强烈建议使用 Tiptap 而非裸写 ProseMirror。
- ProseMirror 和 CodeMirror API 不兼容,无法混用。
- 两者并非竞争关系,而是服务于不同需求的工具——正如它们的名字所示:"Prose"(散文/文章) vs "Code"(代码)。
其他选择?
除了这两还有更好的选择吗。我观察到 CodeMirror5 停止维护,CodeMirror6 则闭源,ProseMirror 也在26年4月左右归档不维护了
你观察到的没错,开源项目的维护状态发生变化,确实会让人在选择时感到困扰。
不过,这背后有一个积极的信号:ProseMirror 和 CodeMirror 的原作者 Marijn Haverbeke 在2026年7月发布了一个全新的、集两者思想于一体的编辑器框架——Wordgard。这更像是一次“凤凰涅槃”,而非简单的停止维护。
下面我为你梳理了当前可用的替代方案,分为富文本和代码编辑器两大类。
📝 富文本编辑器 (替代 ProseMirror)
ProseMirror 的许多核心思想在社区中得到了继承和发展,选择非常丰富。
| 框架 | 核心特点 | 适合场景 | 注意事项 |
|---|---|---|---|
| Wordgard | ProseMirror 与 CodeMirror 原作者的新作,采用全新的 Delta 变更模型,MIT 协议。 | 全新项目,尤其是对协同编辑有高要求的场景。 | 2026年7月发布,目前是 v0.1 版本,API 尚未稳定,不适合生产环境。 |
| Tiptap | ProseMirror 最成功的上层封装,提供开箱即用的体验和庞大的扩展生态。 | 绝大多数需要快速构建、功能丰富的富文本编辑器的场景。 | 部分高级功能(如协同、评论)需要付费。 |
| Lexical | Meta 出品,以卓越的性能和可靠性著称,架构现代,体积小巧(~30KB)。 | 对性能要求极高或希望紧跟技术前沿的项目。 | 社区和第三方工具相比 Tiptap 还不够成熟。 |
| Slate | 一个完全可定制的 React 框架,插件化程度极高。 | React 技术栈,且需要深度定制编辑器行为的项目。 | 目前仍处于 Beta 阶段,API 可能变化。 |
| Quill | 非常流行、成熟的富文本编辑器,API 简单,兼容性好。 | 需要稳定、简单、开箱即用的经典富文本编辑器。 | 其数据模型不如 ProseMirror/Lexical 等框架灵活。 |
| Editor.js | 采用独特的块(Block)风格,输出干净的 JSON 数据。 | 构建类似 Notion 的块编辑器或 CMS 内容编辑。 | 编辑体验与传统的富文本编辑器(如 Word)差异较大。 |
| CKEditor 5 | 功能非常全面、成熟的商业级编辑器,提供丰富的 UI 组件。 | 需要类 Word 的完整办公体验的企业级应用。 | 体积较大,部分高级功能需付费。 |
补充说明:还有 ProseKit、Domternal 等基于 ProseMirror 的新封装库,如果你对 ProseMirror 生态有路径依赖,可以作为备选。Remirror 已进入维护模式,不推荐新项目使用。
补充: 飞书用的 Slate
💻 代码编辑器 (替代 CodeMirror)
代码编辑器领域同样有成熟稳定的选择。
| 框架 | 核心特点 | 适合场景 | 注意事项 |
|---|---|---|---|
| Monaco Editor | VS Code 的核心编辑器,功能最强大,提供桌面级 IDE 体验。 | 需要完整 IDE 功能(如智能提示、调试)的 Web 应用。 | 体积庞大,如果只需要基础高亮会显得“过重”。 |
| Ace Editor | 非常老牌、成熟的代码编辑器,被广泛使用。 | 需要稳定、功能全面的代码编辑场景。 | 架构相对较老,某些方面不如 CodeMirror 6 现代。 |
| Prism Code Editor | 极其轻量,基于 Prism.js 实现高亮。 | 在表单、代码示例、Playground 等轻量级场景替代 CodeMirror。 | 性能随代码行数增加而下降,不适合大文件(>1000行)。 |
💎 总结与建议
综合来看,你的选择可以这样考虑:
如果你要构建一个全新的、对协同编辑要求高的复杂应用,且不介意尝鲜:可以密切关注 Wordgard,它代表了作者对未来编辑器的最新思考。但在其达到 1.0 稳定版之前,请勿用于生产环境。
对于绝大多数富文本编辑需求:Tiptap 是目前最稳妥、最高效的选择。它继承了 ProseMirror 的强大,又大大降低了使用门槛和开发成本。如果你对性能和体积有极致要求,可以考虑 Lexical。
对于代码编辑需求:
- 如果需要最强大的功能,选择 Monaco Editor。
- 如果追求极致的轻量和简单,选择 Prism Code Editor。
- 如果需要一个平衡的选择,Ace 依然稳健可靠。
最后,关于“闭源”的误解:CodeMirror 6 本身是 MIT 开源协议的。你提到的“闭源”可能是指某些基于它的商业产品。