Lexical logo

Lexical

Meta 出品的可扩展、高性能富文本编辑器框架,驱动 Facebook、Instagram、WhatsApp 等产品的编辑体验。

富文本编辑器MetaTypeScript高性能

Lexical 是 Meta 开发的下一代富文本编辑器框架,采用 TypeScript 编写和不可变状态模型,通过单向数据流确保状态可预测,支持四种核心节点类型灵活组合,已在 Facebook、Instagram、WhatsApp 等产品大规模验证。

Lexical

Meta 出品的可扩展、高性能富文本编辑器框架,驱动 Facebook、Instagram、WhatsApp 等产品的编辑体验。

技术简介说明

Lexical 是 Meta(Facebook)开发并开源的富文本编辑器框架。它诞生于 Meta 内部多个产品(Facebook、Instagram、Workplace、Messenger、WhatsApp)对编辑器的共同需求,是 Meta 在放弃 Draft.js 之后重新设计的下一代编辑器解决方案。

Lexical 的核心设计围绕可靠性、可访问性、性能和可扩展性四大原则。它使用 TypeScript 编写,采用不可变的编辑器状态模型,通过 EditorState → Update 的单向数据流确保状态的可预测性。其节点系统支持四种核心类型(RootNode、ElementNode、TextNode、DecoratorNode),可灵活组合构建任意复杂的文档结构。

作为 2025–2026 年增长最快的编辑器框架之一,Lexical 的 GitHub Stars 从 2024 年初的 ~15K 增长到 2026 年的 ~23K+,npm 周下载量达到 3.2M。Meta 自身的大规模生产验证赋予了 Lexical 独特的可信度。

基本信息

快速上手

安装

# 核心包
npm install lexical
 
# React 集成
npm install @lexical/react
 
# 富文本编辑插件
npm install @lexical/rich-text
 
# 常用功能包
npm install @lexical/list        # 列表
npm install @lexical/link         # 链接
npm install @lexical/table        # 表格
npm install @lexical/code         # 代码块
npm install @lexical/history      # 撤销/重做
npm install @lexical/clipboard    # 剪贴板
npm install @lexical/markdown     # Markdown 支持
npm install @lexical/utils        # 工具函数

基础配置

import { createEditor } from 'lexical'
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin'
import { ContentEditable } from '@lexical/react/LexicalContentEditable'
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary'

最小示例(React)

import { LexicalComposer } from '@lexical/react/LexicalComposer'
import { RichTextPlugin } from '@lexical/react/LexicalRichTextPlugin'
import { ContentEditable } from '@lexical/react/LexicalContentEditable'
import { HistoryPlugin } from '@lexical/react/LexicalHistoryPlugin'
import { LexicalErrorBoundary } from '@lexical/react/LexicalErrorBoundary'
import { HeadingNode, QuoteNode } from '@lexical/rich-text'
import { ListNode, ListItemNode } from '@lexical/list'
 
const theme = {
  heading: {
    h1: 'editor-heading-h1',
    h2: 'editor-heading-h2',
  },
  list: {
    ol: 'editor-list-ol',
    ul: 'editor-list-ul',
    listitem: 'editor-listitem',
  },
  text: {
    bold: 'editor-text-bold',
    italic: 'editor-text-italic',
    underline: 'editor-text-underline',
  },
}
 
const editorConfig = {
  namespace: 'MyEditor',
  theme,
  onError(error: Error) {
    throw error
  },
  nodes: [HeadingNode, QuoteNode, ListNode, ListItemNode],
}
 
export default function Editor() {
  return (
    <LexicalComposer initialConfig={editorConfig}>
      <RichTextPlugin
        contentEditable={<ContentEditable className="editor-input" />}
        placeholder={<div className="editor-placeholder">开始编辑...</div>}
        ErrorBoundary={LexicalErrorBoundary}
      />
      <HistoryPlugin />
    </LexicalComposer>
  )
}

自定义节点

import {
  DecoratorNode,
  EditorConfig,
  LexicalEditor,
  LexicalNode,
  NodeKey,
  SerializedLexicalNode,
} from 'lexical'
 
export type SerializedImageNode = SerializedLexicalNode & {
  src: string
  altText: string
}
 
export class ImageNode extends DecoratorNode<JSX.Element> {
  __src: string
  __altText: string
 
  static getType(): string {
    return 'image'
  }
 
  static clone(node: ImageNode): ImageNode {
    return new ImageNode(node.__src, node.__altText, node.__key)
  }
 
  constructor(src: string, altText: string, key?: NodeKey) {
    super(key)
    this.__src = src
    this.__altText = altText
  }
 
  createDOM(_config: EditorConfig): HTMLElement {
    const span = document.createElement('span')
    span.setAttribute('data-lexical-image', 'true')
    return span
  }
 
  decorate(): JSX.Element {
    return (
      <img
        src={this.__src}
        alt={this.__altText}
        style={{ maxWidth: '100%' }}
      />
    )
  }
 
  serialize(): SerializedImageNode {
    return {
      ...super.serialize(),
      type: 'image',
      src: this.__src,
      altText: this.__altText,
    }
  }
 
  static importJSON(json: SerializedImageNode): ImageNode {
    return $createImageNode(json.src, json.altText)
  }
}
 
export function $createImageNode(src: string, altText: string): ImageNode {
  return new ImageNode(src, altText)
}
 
export function $isImageNode(node: LexicalNode | null | undefined): node is ImageNode {
  return node instanceof ImageNode
}

核心概念与架构

架构设计

Lexical 的架构围绕以下核心原则:

  1. 不可变状态:EditorState 是不可变的快照,每次更新产生新的状态
  2. 单向数据流:用户输入 → Transaction → Update → 新 EditorState
  3. 节点系统:四种核心节点类型构成文档树
  4. 插件系统:通过 Composer 模式组合功能
  5. 框架无关核心lexical 核心包不绑定任何框架

核心概念

  • Editor:编辑器实例,管理状态和更新循环
  • EditorState:不可变的编辑器状态快照,包含完整的节点树
  • Node:文档树的节点,四种核心类型:
    • RootNode:根节点
    • ElementNode:容器节点(段落、标题、列表等)
    • TextNode:文本叶子节点
    • DecoratorNode:装饰节点(嵌入 React 组件、图片等)
  • Command:命令系统,通过优先级传播处理用户意图
  • Transform:节点级别的自动转换规则
  • Listener:监听编辑器事件(选择变化、内容变化等)
  • Update:每次状态变更触发 Update 回调

Lexical Extensions(2026 新特性)

// Lexical Extensions 是模块化的配置和行为组合
import { createEditor } from 'lexical'
 
const editor = createEditor({
  extensions: [
    // 框架无关的功能组合
    myRichTextExtension,
    myCollaborationExtension,
  ],
})

核心特性

  • Meta 生产验证:驱动 Facebook、Instagram、Messenger、WhatsApp 等大规模产品
  • TypeScript 原生:完整的 TypeScript 类型支持
  • 不可变状态:函数式状态管理,确保可预测性
  • 四种核心节点:Root、Element、Text、Decorator 灵活组合
  • Named Slots(v0.46.0):实验性特性,让装饰节点管理多个子区域
  • DOMImportExtension(v0.45.0):实验性 DOM 导入 API
  • Lexical Extensions:模块化、框架无关的功能组合模式
  • 协作编辑:通过 @lexical/react 的 CollaborationPlugin 支持
  • Markdown 往返:支持 Markdown 的双向转换
  • AI 演示:官方展示基于 WebAssembly 的浏览器内 AI(SmolLM2、BERT-NER)
  • Headless SSR:@lexical/headless 支持服务端编辑
  • LexKit:基于 Lexical 的上层 React 框架

生态图

核心包

包名说明
lexical核心引擎
@lexical/reactReact 集成(Composer、Plugin、Hook)
@lexical/rich-text富文本编辑能力
@lexical/list列表支持
@lexical/link链接支持
@lexical/table表格支持
@lexical/code代码块支持
@lexical/history撤销/重做
@lexical/clipboard剪贴板处理
@lexical/markdownMarkdown 转换
@lexical/headless无头/服务端编辑
@lexical/utils工具函数
@lexical/extension扩展系统(2026 新增)
@lexical/yjsYjs 协作集成

上层生态

  • LexKit:基于 Lexical 的开源 React 编辑器框架
  • Liveblocks:提供 Lexical 协作编辑集成

对比生态

Lexical 与 TipTap、Slate、Quill 是 2025–2026 年 React 富文本编辑器的四大选择。

适用场景

  • 大规模社交/消息产品:Facebook、Instagram 级别的编辑需求(最佳选择)
  • 高性能编辑器:对性能有严格要求的场景
  • React 项目:@lexical/react 提供最成熟的集成
  • React Native:支持 React Native 平台
  • AI 驱动编辑:利用 WebAssembly 在浏览器内运行 AI 模型
  • 复杂内容编辑:需要深度嵌套和自定义节点的场景
  • CMS 内容管理:与 Payload CMS、Strapi、Webiny 等 Headless CMS 集成

开发与工程化

开发流程

# 克隆仓库
git clone https://github.com/facebook/lexical.git
cd lexical
 
# 安装依赖
npm install
 
# 构建
npm run build
 
# 运行开发服务器
npm run dev
 
# 测试
npm run test-unit
npm run test-e2e

命令系统

import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { $getSelection, $createParagraphNode, $createTextNode } from 'lexical'
import { useEffect } from 'react'
 
function MyPlugin() {
  const [editor] = useLexicalComposerContext()
 
  useEffect(() => {
    // 注册命令
    return editor.registerCommand(
      MY_COMMAND,
      (payload) => {
        editor.update(() => {
          const selection = $getSelection()
          // 处理命令...
        })
        return true // 已处理
      },
      // 命令优先级
      COMMAND_PRIORITY_LOW
    )
  }, [editor])
 
  return null
}

Transform 系统

// Transform 在节点变化时自动运行
editor.registerNodeTransform(TextNode, (textNode) => {
  // 自动将 ":)" 转换为表情
  if (textNode.__text === ':)') {
    textNode.replace($createEmojiNode('😊'))
  }
})

性能与安全

性能特点

  • 高效更新:不可变状态 + diff 算法,最小化 DOM 更新
  • 大文档支持:Lexical 的节点模型在大规模内容下表现良好
  • Meta 验证:在 Facebook 等超大用户基数产品中经过生产验证

性能注意事项

  • 包体积较大(核心包比 TipTap 和 Slate 更重)
  • 避免在 Transform 中创建循环依赖
  • 合理使用 DecoratorNode 减少重渲染范围
  • 长文档考虑虚拟滚动

安全注意

  • Meta 的安全审查流程确保代码质量
  • 对用户输入的内容进行 HTML 消毒
  • 自定义节点的 createDOM 方法注意 XSS 防护
  • 粘贴内容的 DOM 导入需经过验证

技术对比

特性LexicalTipTapSlateQuillCKEditor 5
底层自研ProseMirror自研Parchment自研 MVC
框架React/通用React/Vue/SvelteReact框架无关React/Vue/Angular
TypeScript原生原生(3.0 增强)支持2.0 重写TypeScript
纯装饰
协作编辑✅ 支持✅ 付费slate-yjs需自建✅ 付费
SSR✅ headless✅ 3.0 原生有限
Yjs 集成✅ 但有限制✅ y-tiptap✅ slate-yjs需自建❌ 私有云
包体积较大较小中等较大
学习曲线较陡中等较陡中等
AI 集成实验性✅ AI Toolkit需自建需自建✅ AI Assistant
Meta 验证Discord 等广泛使用企业广泛

Yjs 协作的限制

Lexical 的 Yjs 集成存在已知限制:

  • Yjs 协作中硬编码了根节点名称,限制每个 Yjs 文档只能有一个编辑器
  • 协作功能相比 TipTap 的 y-tiptap 不够成熟

最佳实践

  1. 使用 Composer 模式:通过 LexicalComposer 包裹编辑器,统一管理配置
  2. 合理设计节点系统:自定义节点时注意 importJSON/exportJSON 的对称性
  3. Command 优先级:合理使用 COMMAND_PRIORITY 控制命令传播
  4. Transform 谨慎使用:Transform 在每次节点变化时运行,避免重计算
  5. 错误边界:始终使用 LexicalErrorBoundary 包裹编辑器
  6. 主题系统:使用主题对象集中管理 CSS 类名
  7. 测试自定义节点:确保序列化/反序列化的正确性,这对协作编辑至关重要

技术局限与边界

  • 学习曲线陡峭:节点系统、Command 系统、Transform 等概念较多
  • 包体积较大:核心包比 TipTap、Slate 更重
  • 无纯装饰:缺乏纯装饰(pure decorations)支持,协作光标等需要 DOM workaround
  • Yjs 集成有限制:硬编码根节点名称,一个 Yjs 文档只能一个编辑器
  • 框架支持不均:React 集成最成熟,其他框架支持有限
  • 仍在 0.x 阶段:API 可能随版本更新有 breaking change
  • 社区资源少于 TipTap:教程和第三方资源相对较少
  • iOS 支持实验性:Lexical iOS 仍处于早期阶段

学习资源

2026 年现状

最新版本

  • v0.46.0(2026 年 6 月):Named Slots(实验性)
  • v0.45.0(2026 年 5 月):DOMImportExtension(实验性)
  • 发布频率:约每月一个版本

发展趋势

  1. Named Slots(v0.46.0):允许装饰节点在单个宿主元素中管理多个命名子区域
  2. DOMImportExtension(v0.45.0):全新的 DOM 导入 API,改进粘贴和剪贴板处理
  3. Lexical Extensions:模块化、框架无关的功能组合新模式
  4. AI 集成深化:基于 WebAssembly 的浏览器内 AI(SmolLM2 + BERT-NER)
  5. LexKit 生态:基于 Lexical 的上层框架持续完善
  6. 协作改进:持续改进 Yjs 集成和实时协作能力

社区活跃度

  • GitHub Stars:~23,300+(2024 年初 ~15K,增长最快的编辑器框架)
  • npm 周下载量:~3.2M
  • Meta 内部持续投入,多个产品线依赖
  • 月度版本发布节奏稳定

定位总结

Lexical 是 2026 年增长最快的富文本编辑器框架,Meta 的大规模生产验证是其最大背书。适合对性能、可靠性有严格要求的 React 项目。如果你需要跨框架支持(Vue/Svelte),TipTap 是更成熟的选择;如果需要极致的底层控制,Slate 可能更合适。