In the previous article, we introduced the basic concepts of rich text and its development history. In this article, we will explore the currently mainstream open-source rich text editor engines. The most widely used rich text editor currently is the L1
rich text editor, which can meet the needs of the vast majority of use cases. As a result, many excellent open-source rich text engines have been born. These include standalone engine editors such as Slate.js
, partially out-of-the-box functional editors like Quill.js
, and secondary development based on these engines such as Plate.js
. This article mainly introduces three editing engines: Slate.js
, Quill.js
, and Draft.js
.
Slate
is a rich text core
that only provides an engine. Simply put, it does not provide various rich text editing functions by itself, and all rich text features need to be implemented through its provided API
. Even its plugin mechanism needs to be expanded by oneself, so using Slate
to build a rich text editor can be highly customizable. Although the documentation for Slate
is not particularly detailed, its examples are very rich. The documentation also provides a tutorial as a starting point, which is quite friendly for beginners. Speaking of which, if only an engine is provided, no one knows how to use it, haha.
In the Slate
documentation, there are descriptions of the design principles of the framework:
- Plugins are first-class citizens. The most important part of
Slate
is that plugins are first-class citizen entities, which means you can completely customize the editing experience to build complex editors likeMedium
orDropbox
without struggling with the default settings of the library. - Lean
schema
core. The core logic ofSlate
imposes very few presets on the structure of your edited data. This means that when you build complex use cases, you will not be hindered by any pre-existing content. - Nested document model. The model used by
Slate
documents is a nested, recursive tree, just likeDOM
. This means that for advanced use cases, it is possible to build complex components such as tables or nested references. Of course, you can also use a single-level structure to keep it simple. - Same as
DOM
,Slate
's data model is based onDOM
. The document is a nested tree, using text selections and ranges, and exposes all standard event handling functions. This means that advanced features such as tables or nested references that can be done inDOM
can also be done inSlate
. - Intuitive commands.
Slate
documents execute commands to edit. It is designed to be advanced and very intuitive for editing and reading, so that customized features are as expressive as possible, greatly improving your understanding of the code. - Collaborative data model. The data model used by
Slate
, especially how operations are applied to the document, is designed to allow collaborative editing at the highest level, so if you decide to implement collaborative editing, you don't have to consider a complete refactor. - Clear core division. The structure of prioritizing plugins and a lean core makes the boundary between the core and customization very clear, meaning that the core editing experience will not be troubled by various edge cases.
The data structure of a text sample looks like this:
[
{
children: [
{ text: "Like this" },
{ text: "a text sample", italic: true },
{ text: "of" },
{ text: "data structure", bold: true },
{ text: "as shown below." },
],
},
];
- Highly customizable, almost all rich text display layer functions need to be implemented independently.
- Very lightweight, it has only one core, and the functionality is implemented as needed, making the volume controllable.
- Implemented OP-optimized incremental changes for collaboration during the architecture design.
- The data structure is a nested
JSON
structure similar toDOM
, making it intuitive and easy to understand.
- Still in the
Beta
stage, there may be majorAPI
changes. For example, version0.50
was completely refactored. - Although it has collaborative design, it lacks direct support for
OT
orCRDT
algorithms for transformation operations. - The architecture with only the core is also a disadvantage, as all functionality needs to be implemented independently, resulting in higher cost.
- The new version of
Slate
does not have aschema
, which means thatNormalize
needs to be implemented independently.
- Official documentation for
slate
can be found athttps://docs.slatejs.org/
. - Check out some examples from the
slate
official website athttps://www.slatejs.org/examples/richtext
. - Personally implemented rich text editor based on
slate
can be accessed athttps://github.com/WindrunnerMax/DocEditor
. - Get started with a ready-to-use rich text editor based on
slate
athttps://plate.udecode.io/docs/playground
. - For reference on collaborative implementation of
OT
withslate
, visithttps://github.com/solidoc/slate-ot
. - Visit
https://github.com/pubuzhixing8/ottype-slate
forOTTypes
reference forslate
. - Explore collaborative implementation with
CRDT
forslate
athttps://github.com/humandx/slate-automerge
. - For information on combining
slate
withYJS
collaboration, refer tohttps://github.com/BitPhinix/slate-yjs
. - Excellent articles on
slate
can be found athttps://github.com/yoyoyohamapi/book-slate-editor-design
.
Quill
is a modern rich text editor with excellent compatibility and powerful extensibility, offering some out-of-the-box features. It was open-sourced in 2012
and brought many new features to the rich text editor, making it one of the most popular open-source editors with a rich ecosystem. You can find numerous examples, including comprehensive collaborative instances, on platforms like GitHub
.
The design principles of the framework are described in the documentation:
- API-driven design: All of
Quill's
features are implemented through the API and data changes can be intuitively obtained through the API. It is built on a text-centric API, eliminating the need to parseHTML
orDIFF DOM
trees, making its functionality more flexible and highly extensible. - Custom content and formats:
Quill
provides its document model as a powerful abstraction of the DOM, allowing for expansion and customization, with data structures such asBlots
,Parchment
, andDelta
taking center stage. - Cross-platform:
Quill
has excellent compatibility and can run in the same way on older browser versions, ensuring consistent views and interactions across different browsers, as well as desktop and mobile devices. - Ease of use:
Quill
comes with some out-of-the-box features that are sufficient if customization is not required. Additionally, it offers high extensibility for customizing various functions.
The data structure for a piece of text is as follows:
{
ops: [
{ insert: "This" },
{ insert: "is a piece of text", attributes: { italic: true } },
{ insert: "with", },
{ insert: "customized content", attributes: { bold: true } },
{ insert: "as shown.\\n" },
],
};
- API-driven design with rich support for basic functionality and extensibility.
- Implementation of a view layer independent of the framework, making it easy to use with
Vue
orReact
. - Use of a more intuitive
Delta
to describe data structures, implementing logic for operation transformation and facilitating collaboration. - Rich ecosystem with numerous plugins and design schemes to reference, particularly in terms of its support for collaboration.
- The
Delta
data structure is flat, making it cumbersome to implement features like tables. Quill 2.0
has been in development for a long time and has not been formally released yet. The current version,1.3.7
, has not been updated for many years.- While
Quill
comes with a rich set of features, this also results in a larger package size.
- Official documentation for
Quill
can be found athttps://quilljs.com/docs/quickstart/
. - Check out some examples from the
Quill
official website athttps://quilljs.com/standalone/full/
. - For
Delta
design and implementation inQuill
, refer tohttps://quilljs.com/docs/delta/
. - Explore
OTTypes
reference for collaborative implementation withQuill
athttps://github.com/ottypes/rich-text
. - Collaborative implementation of
OT
withQuill
can be found athttps://github.com/share/sharedb/tree/master/examples/rich-text
. - For collaborative implementation with
CRDT-yjs
forQuill
, refer tohttps://github.com/yjs/y-quill
.
Draft
is a framework for building rich text editors in React
, providing a powerful API for creating and customizing text editors. It aims to be easy to extend and integrate with other libraries. Combining it with React
allows developers to develop editors without directly manipulating the DOM or learning a separate UI building paradigm. Instead, they can directly write React
components to implement the editor's UI. The overall concept of draft
aligns very well with React
. For example, it uses state management to store data structures, leverages the immutable.js
library, delegates most data structure modifications to the browser's default behavior, and modifies rich text data through state management.
The README
of draft
describes the framework's design principles:
-
Scalable and customizable, providing building blocks to create various rich text editing experiences, from basic text styles to support for embedded media.
-
Declarative rich text, seamlessly integrating with
React
using a declarativeAPI
familiar toReact
users, abstracting the details of rendering, selection, and input behavior. -
Immutable editor state. The
draft
model is built usingimmutable.js
, providing an API for functional state updates and actively utilizing data persistence to achieve scalable memory usage.
The data structure of a piece of text with emphasis is as follows.
{
blocks: [
{
key: "3eesq",
text: "This is an example of a text structure.",
type: "unstyled",
depth: 0,
inlineStyleRanges: [
{ offset: 2, length: 4, style: "ITALIC" },
{ offset: 7, length: 4, style: "BOLD" },
],
entityRanges: [],
data: {},
},
],
entityMap: {},
};
- Flexible API for easily extending and customizing blocks and inline elements.
- Leveraging
React
for the UI layer and data management, making it user-friendly forReact
users. - Relatively stable with minimal breaking changes, advantageous in terms of stability and detail handling.
- Heavily dependent on
React
as the UI layer, making it difficult to use with other UI frameworks. - Limited flexibility in the design of data structure models, especially when implementing nested structures such as tables.
- While
draft
has been heavily optimized for performance, it still exhibits lag when rendering a large amount of content.
- Official
draft
documentation:https://draftjs.org/docs/overview
. - Official
draft
examples:https://draftjs.org/
. draft
codesandbox
example:https://codesandbox.io/s/github/gupta-piyush19/Draft-JS-Editor
.
https://github.com/WindrunnerMax/EveryDay
https://github.com/hzjswlgbsj/blog
https://zhuanlan.zhihu.com/p/425265438
https://jkrsp.com/slate-js-vs-draft-js/
https://www.zhihu.com/question/404836496
https://www.zhihu.com/question/449541344
https://juejin.cn/post/6844903838982340622
https://juejin.cn/post/7034480408888770567
https://juejin.cn/post/6974609015602937870
https://github.com/cudr/slate-collaborative
https://blog.logrocket.com/what-is-slate-js-replace-quill-draft-js/
https://dev.to/charrondev/getting-to-know-quilljs---part-1-parchment-blots-and-lifecycle--3e76