Top JS rich text editor frameworks for 2021
Tags: webdev, javascript, typescript
Published: 2021-03-26 13:46:27

**Rich text editors**, also known as **WYSIWYG** (What You See Is What You Get) editors are everywhere - comment sections, forums, online text editors. Whenever you want to go beyond plain `<input>` or `<textarea>` and enable visible, interactive formatting in your editor, you have to go the `contenteditable` route and build a proper rich editor.

Thankfully, with the plethora of JavaScript frameworks and libraries, created with the sole purpose of building **rich web-based editing experiences**, you’ll never again have to [deal with the evil](https://medium.engineering/why-contenteditable-is-terrible-122d8a40e480) that is `contenteditable`.

In this blog post, I’d like to present you with my top picks for **the best JS rich text editor frameworks** for 2021.

# What we’re looking for?

So, this whole list is based on in-depth research I’ve done while working on my first product - [CodeWrite](https://codewrite.io), *a blogging tool for developers*.

**CodeWrite** was created to provide the best technical blogging and cross-posting experience possible. It has a form of a browser extension + PWA hybrid providing an auto-filling system for popular blogging platforms and a dedicated rich content editor.

With that said, CodeWrite is the product that determined my framework requirements. So, what are they?

## The basics

For the baseline of features that the framework has to have, I’ve chosen the ones which CodeWrite definitely required. Those included:

-   rich **inline content formatting**, with options for customization and extension of the provided functionality
-   **embeds** and other block content support - `<iframe>`s, lists, blockquotes, etc.
-   ability to use and define custom **keyboard shortcuts** and **Markdown input rules** (important for developers, dynamically changing input MD to formatted content)
-   deep **UI customization** and flexibility, the ability to create formatting toolbars, “block” side menus, floating toolbars, etc.
-   “Out-of-the-box” support for basic operations - history, undo, redo, copy, paste.

Except for deep customization and Markdown input rules, these are all functionalities that you should expect every modern framework to provide.

Of course, we also look for the quality of **maintenance**, community size, **documentation**, and ease-of-use of **API**.

## Specifics

Apart from the basics, I had some additional requirements that were very specific to what I wanted CodeWrite to be.

### Grammar checking tooling support

You know these browser extensions that provide you with AI grammar checking on every input, like, e.g., [Grammarly](https://www.grammarly.com/)? Those work really well in plain `<textarea>`s but often struggle in complex, rich text editors. That’s because of the differences in the handling of `contenteditable` elements. Different structures work better or worse with tools like Grammarly.

Although one could argue that such issues should be solved on Grammarly’s side, they can’t possibly account for every possible `contenteditable` structure out there, and so a little help is necessary.

### Editor within an editor

This is very CodeWrite-specific. To provide the best technical blogging experience, I wanted to have both the best writing and **coding experience**. This meant that code snippets should be treated properly as well - with something like [CodeMirror](https://codemirror.net/), or [Monaco Editor](https://microsoft.github.io/monaco-editor/) - which, in turn, meant embedding an editor within an editor!

Editable embeds differ from traditional ones like `<iframe>`s, as they’re much more **interactive**. They can’t be embedded through `<iframe>`, as multiple separate Monaco Editor instances would bring any device to its knees. Also, you have to be able to edit the content within any of these instances, including operations like select, copy, paste, etc. Add **syncing cursor** between inner and outer editors to all this, and you’ve got a pretty complex setup on your hands.

## Good to have

Apart from everything already listed, I did have even more requirements. The *“good-to-have”*s, as I called them, were those features that I knew I won’t use right-away but would be useful down the line. These were:

-   **Mobile support** - as a desktop browser extension, CodeWrite wasn’t intended for mobile. Apart from that, it’s challenging to provide proper editing and coding experience on small, touch-only devices without a physical keyboard. With that said, I did think about making CodeWrite for mobile one day and so wanted my framework of choice to support it.
-   **Collaborative editing** - now, initially, I wanted CodeWrite to be for individual code-bloggers, but I always planned to support *“live collab”* down the line. You know, real-time cursors, conflict resolving, etc.? Live collab is a demanding feature that requires the framework to have a well-structured API and properly structure, handle, and store updates.

# How we’re doing it?

With all the feature requirements out of the way, let me quickly explain how this list will be structured.

All the mentioned features will be brought together to a short list for you to be able to quickly glance at the given framework’s feature-set, with each feature being marked with 🎉, 👎, or 😑 for “passed”, “failed”, and “somewhat passed” respectively.

Now, not every framework on this list includes every feature - even from the basic category! Still, these truly are the best options from all that I know of, and all of them truly deserved a place on this list.

With that said, some deserve it more than the others, and so I’ve divided all the **6 entries** on this list into 3 categories - *“worth mentioning”*, *“runners-up”*, and *“the winner”*. This way, you not only have a clear distinction between the frameworks but can also follow my journey, as I was deciding on my final pick.

Hopefully, that’s enough of the intro. We know what we’re looking for, we know how it all works, and now - onto the list!

# Worth-mentioning

## [Quill](https://quilljs.com/)
<figure>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0h19n5oi29gqromtgxut.png" alt="Quill landing page"/>
<figcaption>Quill landing page</figcaption>
</figure>
**Quill** seemed like a good framework from the start. It’s UI framework-independent, works with Grammarly, has easily customizable UI, and all that good stuff.

However, the problems arise as you dig deeper. Seemingly simple API becomes increasingly complex as you seek customizability, Markdown input rules aren’t supported, and the whole project’s maintainability is [questionable](https://github.com/quilljs/quill/issues/3251).

Weirdly, the repo seems active, yet docs, however broad, seem to be a bit stuck in the past, and the [NPM package](https://www.npmjs.com/package/quill) hasn’t been updated for over a year.

With that said, Quill still made it to this list (though the very bottom), thanks to its *“seeming simplicity”*. If all you want is a simple but rich editor, you don’t have any custom requirements and don’t seek deep customizability; Quill is a good, quick, and easy-to-setup editor.

-   Basic operations: 🎉
-   UI customizability: 🎉
-   Inline formatting: 🎉
-   Embeds and blocks: 😑 (except for images and videos, requires complex setup)
-   Keyboard shortcuts: 🎉
-   Markdown input rules: 👎 (see [https://github.com/quilljs/quill/issues/3192](https://github.com/quilljs/quill/issues/3192))
-   Good API: 😑 (simple on the outside, complex on the inside)
-   Documentation: 😑 (broad, but stuck in time)
-   Maintenance: 😑 (maintained, but not really)
-   Grammarly: 🎉
-   Nested editors: 👎 (see [https://github.com/quilljs/quill/issues/2772](https://github.com/quilljs/quill/issues/2772))
-   Mobile support: 🎉
-   Collaborative editing: 😑 (see [https://github.com/quilljs/quill/issues/2099](https://github.com/quilljs/quill/issues/2099))

## [Draft.js](https://draftjs.org/)
<figure>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kol9lx4hqv9ow2p3dqgc.png" alt="Draft.js landing page"/>
<figcaption>Draft.js landing page</figcaption>
</figure>
Now, **Draft.js** is seemingly the “go-to” rich editor framework for React. It comes straight from the Facebook team, has a deeply *“react-ish”* API, and powers likes of Facebook Messenger or Twitter.

If you’ve enjoyed working with React before, you’ll love the Draft.js API. Apart from being tailored towards React, it’s clean, simple, and well-documented.

This simplicity, however, affects not only the API but also the whole design of the framework. The framework itself is just a core, with limited functionality but a **robust plugin system**. This means that you’ll have to either do some more research and find good plugins (here’s [a good collection](https://www.draft-js-plugins.com/)) or build the required plugins on your own.

-   Basic operations: 🎉
-   UI customizability: 🎉
-   Inline formatting: 🎉
-   Embeds and blocks: 🎉
-   Keyboard shortcuts: 🎉
-   Markdown input rules: 😑 (possible through a [plugin](https://github.com/ngs/draft-js-markdown-shortcuts-plugin))
-   Good API: 🎉
-   Documentation: 🎉
-   Maintenance: 🎉
-   Grammarly: 🎉
-   Nested editors: 😑 (possible, though no resources on that are available)
-   Mobile support: 🎉
-   Collaborative editing: 👎 (see [https://github.com/facebook/draft-js/issues/93](https://github.com/facebook/draft-js/issues/93))

## [Editor.js](https://editorjs.io/)
<figure>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eo8xetmumnadb83p1433.png" alt="Editor.js landing page"/>
<figcaption>Editor.js landing page</figcaption>
</figure>
**Editor.js** has hands-down, the best API from any framework on this list. It’s simple, framework-independent, easy-to-use, and has clean, readable JSON output.

Such a great API comes at a price, though. The framework lacks support for collaborative editing and Markdown input rules. Grammarly support is also hit or miss, as Editor.js is a **block-styled editor** (each paragraph of content is its own `contenteditable`). On top of that, mobile support, although present, comes with a few hiccups.

As for customizability - there is a plugin architecture in place to support it, although it’s rather limited. Plugins allow you to add additional features like blocks or inline formatting, but UI customization is not as extensive as with other frameworks.

With that said, I whole-heartedly recommend Editor.js for anyone who’s looking for a drop-in, easy-to-use editor with stunning UI out-of-the-box. Something like Quill, just actually maintained, and arguably even better!

-   Basic operations: 🎉
-   UI customizability: 😑 (possible, but limited compared to other frameworks)
-   Inline formatting: 🎉
-   Embeds and blocks: 🎉
-   Keyboard shortcuts: 🎉
-   Markdown input rules: 👎 (see [https://github.com/codex-team/editor.js/issues/709](https://github.com/codex-team/editor.js/issues/709))
-   Good API: 🎉
-   Documentation: 🎉
-   Maintenance: 🎉
-   Grammarly: 😑 (works, but only “per-paragraph”)
-   Nested editors: 😑 (possible, “proof-of-concept” [plugin available](https://github.com/alexiej/editorjs-codemirror))
-   Mobile support: 😑 (works, but is buggy)
-   Collaborative editing: 👎 (see [https://github.com/codex-team/editor.js/issues/819](https://github.com/codex-team/editor.js/issues/819))

# Runners-up

## [Slate](https://docs.slatejs.org/)
<figure>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gqeh24lofpa45co8w85w.png" alt="Slate documentation"/>
<figcaption>Slate documentation</figcaption>
</figure>
With **Slate**, we’re stepping up the game! Seemingly forever in **beta**, Slate is a deeply-customizable rich editor framework dedicated for React.

Similarly to Draft.js, it has a good API, robust plugin infrastructure, and deep connections with React. However, it does have some additional advantages and is generally more **customizable**. Also, the plugin ecosystem is a bit smaller than Draft.js’, but it could be said that, on average, the plugin quality is better. As an example, here’s a [good plugin collection](https://slate-plugins-next.netlify.app/).

Slate is the first framework on this list that somewhat checks all the boxes. Even though Slate currently lacks documentation on collaborative editing and nested editors, the API does allow for such functionalities. This leaves the **lack of Android support** as the biggest drawback.

-   Basic operations: 🎉
-   UI customizability: 🎉
-   Inline formatting: 🎉
-   Embeds and blocks: 🎉
-   Keyboard shortcuts: 🎉
-   Markdown input rules: 🎉
-   Good API: 🎉
-   Documentation: 🎉
-   Maintenance: 🎉
-   Grammarly: 🎉
-   Nested editors: 😑 (possible, “proof-of-concept” [available](https://codesandbox.io/s/ck0pq))
-   Mobile support: 😑 (Android [unsupported](https://github.com/ianstormtaylor/slate/issues/3786), iOS mostly works)
-   Collaborative editing: 😑 (possible, but [hardly documented](https://github.com/ianstormtaylor/slate/issues/3715))

## [ProseMirror](https://prosemirror.net/)
<figure>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7p5h6rjx76ro7s1m0ioe.png" alt="Prosemirror landing page"/>
<figcaption>Prosemirror landing page</figcaption>
</figure>
With **ProseMirror**, we’re reaching the top! It’s by far **the most feature-complete framework** on this list.

All the features that we’re looking for are present in ProseMirror. Basics - checked, customizability - checked, mobile and Grammarly support - checked! Even collaborative editing and nested code editors get a pass - there are dedicated examples for [both](https://prosemirror.net/examples/collab/#edit-Example) of [these](https://prosemirror.net/examples/codemirror/) edge-cases! The only drawback that ProseMirror has is its **complexity**.

It’s expected that a framework that’s that feature-packed would have a complex API. It’s natural, but still, something to point out, as the newcomers to the framework, i.e., the vast majority, might struggle at first. Add to that the minimalism of the toolkit (it includes only the core “building blocks” for you to put them together), and you’re up for quite a challenge.

With that said, I’d say that there’s no better framework for creating rich text editors in 2021 than ProseMirror. However, this leaves a question - why isn’t ProseMirror the winner?

-   Basic operations: 🎉
-   UI customizability: 🎉
-   Inline formatting: 🎉
-   Embeds and blocks: 🎉
-   Keyboard shortcuts: 🎉
-   Markdown input rules: 🎉
-   Good API: 😑 (quite complicated)
-   Documentation: 🎉
-   Maintenance: 🎉
-   Grammarly: 🎉
-   Nested editors: 🎉
-   Mobile support: 🎉
-   Collaborative editing: 🎉

# The winner

## [Tiptap](https://tiptap.dev/) (v2)
<figure>
<img src="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zlch3zq9ge7lwcwc22ki.png" alt="Tiptap v1 landing page"/>
<figcaption>Tiptap v1 landing page</figcaption>
</figure>
So, “the winner”, as well as the best rich editor framework for 2021, is **Tiptap**! It’s built **on top of ProseMirror** (so my point about it being the best still stands) but provides a much friendlier API, allowing you to create great editing experiences much faster!

There is one caveat, though. You see, when I’m putting TipTap on the podium, I’m actually referring to **Tiptap v2**.

Tiptap v1 is already a nice, helpful wrapper around ProseMirror, but it lacks good documentation, TypeScript typings and is compatible only with Vue 2.

Tiptap v2 fixes all those issues with improved, framework-independent API, TypeScript rewrite, and great docs. However, it is in beta - **closed beta**. To access the framework, you have to [sponsor its developers](https://github.com/sponsors/ueberdosis) on GitHub. A noble cause, but a barrier to entry nonetheless.

They [openly stated](https://blog.ueber.io/post/tiptap-2-0-beta/) that the framework will be made available publically once it reaches a goal of **$5000/month** from GitHub sponsors.

Now, think of it what you will, but personally, I value good products, and Tiptap is one of them. Thus, as a GitHub sponsor, I got access to Tiptap v2, and I must admit - this is the best tool for the job. I can’t say it’s the best rich content editor framework, as it’s the ProseMirror’s role, but it’s a great extension on top of.

With combined APIs and documentation of both tools, you’ll be able to create any rich editor you can think of, just like I was able to create CodeWrite. You’ll still have to learn the ProseMirror API to implement more advanced features, although it’ll come gradually and be much easier thanks to Tiptap wrappers.

So, that’s my **no. 1**. And you can either wait for it to become public (it’s really close) or sponsor the awesome team behind Tiptap and get access right now!

-   Basic operations: 🎉
-   UI customizability: 🎉
-   Inline formatting: 🎉
-   Embeds and blocks: 🎉
-   Keyboard shortcuts: 🎉
-   Markdown input rules: 🎉
-   Good API: 🎉
-   Documentation: 🎉
-   Maintenance: 🎉
-   Grammarly: 🎉
-   Nested editors: 🎉
-   Mobile support: 🎉
-   Collaborative editing: 🎉

# Bottom line

That’s it for this list. I hope you find it helpful. After all, you’ve just learned in a few minutes what took me days! I can’t wait to see what awesome editing experiences you create with any of these wonderful tools! Feel free to share them, your thoughts, and anything related to the topic in the comments below!

Anyway, for more web development stuff, follow me on [Twitter](https://twitter.com/areknawo), [Facebook](https://www.facebook.com/areknawoblog), or through [my newsletter](https://areknawo.com#newsletter). Thanks for reading, and happy coding!

> As for CodeWrite - you now know. It’s powered by **Tiptap v2**, alongside [Vue 3 and TSX](https://areknawo.com/vue-with-tsx-the-perfect-duo/) combo. If you’re a technical blogger like I am, feel free to [check out CodeWrite](https://codewrite.io)! It’ll boost your writing productivity and experience with a great **Grammarly-compatible rich text editor**, dedicated **Monaco Editor** for handling code snippets (the same one behind VS Code), and Prettier integration for formatting them. Also, you’ll get **one-click auto-filling** functionality for blogging platforms, like [Medium](https://medium.com), [Dev.to](http://dev.to/), [Hashnode](https://hashnode.com/), all [Ghost blogs](https://ghost.org/), and even more in the future, with an automatic **issue-resolving mechanism** for handling nasty stuff like resizing images, or snippet to GitHub Gist conversion for Medium!
> 
> CodeWrite paid plans start at as little as **$3/month**, but you can also try it for free! Also, if you’re reading this, use the code `first100` to get **lifetime 20% off**, if you’re one of the first 100 people to use the code. That’s as little as **$2.40/month** or just **$24/year**!