Best JS rich text editors for 2023
What You See Is What You Get (WYSIWYG), aka Rich Text Editors (RTE) are everywhere. Whenever you want to have an input with different formatting options, the ability to insert embeds, images, etc. - you want a WYSIWYG editor.
In a world of web development, this means going beyond just input
or textarea
into the unknowns of contenteditable
. But the thing is, contenteditable
is difficult to work with - especially if you want to build any kind of complex editing experience.
That’s why you’d likely want a JS RTE framework or library, to provide an easy-to-work-with abstraction over contenteditable
and a base for you to build upon.
WYSIWYG editor requirements
I’ve already covered this topic a while back when working on CodeWrite - a browser extension tool for blogging developers. That said, now (almost two years later), some things have changed - both in the selection of available tools, as well as the product I’m building.
For Vrite - a headless CMS intended for developers - I had to step up my requirements for both the feature set and performance of the rich text frameworks. That said, this list will be much more focused and stricter when it comes to comparison.
Here’s what I was looking for when compiling this list (by importance and complexity):
Inline/block content and formatting support - content formatting (bold, italic, etc.) and embedding (images, videos, iframes, etc.) are a must for every rich text editor;
UI customization - the ability to customize the editor to be in line with your brand image and UI/UX design is crucial to providing users with a great, consistent experience;
Keyboard/Markdown shortcuts - keyboard shortcuts are a must-have for all professional users; For developers, Markdown shortcuts (aka input rules) are at least equally important;
History/clipboard operations - copy, paste, undo, redo - all those actions, though seemingly simple, have to be handled properly by the editor to support all its formatting, embed, and input rules features;
API and documentation - while it’s not a user-facing feature, the quality of the API and documentation makes or breaks any library or framework; It’s required for developers to understand the tool they’re using and build on top of it;
Collaborative editing - real-time collaboration is a feature that’s well-established and, by now, required by all teams; Syncing document updates, resolving real-time conflicts, and sharing the user’s presence (i.e. cursor position) are all required for this feature to work;
Embedded editors - while not often required, the ability to embed editable content - especially ones like rich text or code editors can result in many great functionalities for your editor; For Vrite, it’s necessary to integrate a full code editor for every snippet;
Mobile support -even in complex editors, users might sometime want to edit their documents from mobile; Supporting and providing a good user experience for it isn’t easy without a properly built editor framework;
Grammarly support - browser extensions for grammar checking and AI text analysis (such as Grammarly) are becoming increasingly popular, with proper support for them being a decisive factor for users; While not a must-have it’s worth knowing how your editor framework works with such services.
Editor.js
In my opinion, Editor.js remains the WYSIWYG framework with one of the friendliest APIs and documentation on top of, probably the best JSON-based document representation. That said, it’s a block-styled editor, using separate contenteditable
elements for every section (limiting Grammarly support), with both the UI and functionality tightly integrated (limiting customizability).
Still, it’s my go-to choice for simple editors and when building for less technical audiences. The fact that it’s framework-independent, very easy to set up, and comes with many plugins to build just the feature set you want makes it a great option for the vast majority of use cases.
Inline/block content and formatting support: ✅
UI customization: ⚠️ (limited but UI is great out-of-the-box)
Keyboard/Markdown shortcuts: ⚠️ (no support for Markdown input rules)
History/clipboard operations: ✅
API and documentation: ✅
Collaborative editing: ⛔️ (full-featured support on the roadmap)
Embedded editors: ⛔️
Mobile support: ✅
Grammarly support: ⚠️ (Grammarly enabled per section, due to separate
contenteditable
elements)
Slate
Slate (still in beta) is one of the most well-rounded WYSIWYG editor frameworks out there. It builds a complete suite of tools on top of React for you to create the exact RTE you want. The best way to describe it is: “a pluggable implementation of contenteditable
“ (taken from the docs).
Given the customizability it provides, Slate has a clean API and solid documentation to go with it. When paired with tons of available plugins, it makes for a great development experience. Still, it’s React-only and lacks in a few (though somewhat niche) areas.
Inline/block content and formatting support: ✅
UI customization: ✅
Keyboard/Markdown shortcuts: ✅
History/clipboard operations: ✅
API and documentation: ✅
Collaborative editing: ⚠️ (possible with official mentions and good plugins, though hardly documented)
Embedded editors: ⚠️ (technically possible though hardly documented and with no official support)
Mobile support: ✅
Grammarly support: ✅
ProseMirror
ProseMirror is the top player when it comes to WYSIWYG editors. It has it all - customization, Markdown, embedded editors, mobile support - you name it! On top of that, it’s framework-independent and integrates well with libraries like Y.js for fully-featured real-time collaboration. Its only downside is its complexity.
ProseMirror is notoriously difficult to understand and work with. Although the documentation gives a solid overview of the framework and provides various practical examples, the API does take a long while to learn.
Inline/block content and formatting support: ✅
UI customization: ✅
Keyboard/Markdown shortcuts: ✅
History/clipboard operations: ✅
API and documentation: ⚠️ (difficult API)
Collaborative editing: ✅
Embedded editors: ✅
Mobile support: ✅
Grammarly support: ✅
TipTap
While ProseMirror’s API is difficult, it’s a powerful base to build upon. That’s why there are many RTE frameworks built on top of it, such as TipTap. You can look at it as ProseMirror with developer-friendly API and very in-depth documentation.
TipTap is a headless WYSIWYG editor framework. Thanks to its API, a whole set of plugins, and dedicated integrations for popular UI frameworks, it’s your go-to for any kind of customized editor you want to create. In case you need more customizability, you can always tap into the underlying ProseMirror. If you don’t - just use the available plugins and examples to build your editor and style it accordingly.
Inline/block content and formatting support: ✅
UI customization: ✅
Keyboard/Markdown shortcuts: ✅
History/clipboard operations: ✅
API and documentation: ✅
Collaborative editing: ✅
Embedded editors: ✅
Mobile support: ✅
Grammarly support: ✅
Honorable mentions
Naturally, this list doesn’t cover all the available options. While I’d argue that most other RTE frameworks out there just build on top of e.g. ProseMirror or Slate, there are still two options I’d like to specifically mention:
Remirror - much like TipTap it builds on ProseMirror to provide a more developer-friendly experience with a primary focus on React users. If you’re considering using TipTap with React integration, it’s worth checking out to see which API you like better.
Lexical - a spiritual successor to Draft.js, coming from Facebook. While focused on React, it’s framework-independent and seems to have a sleek API. It’s still relatively new and I haven’t explored it yet, but it might be worth taking a look at.
Bottom line
From my side, I see pretty much only two great choices: Editor.js and TipTap. If you need a quick drop-in editor with great UI and super-simple API, Editor.js should be your choice. This serves a vast majority of use cases. However, when you’re willing to spend more time, want to customize your editor a bit more, or add some advanced functionalities to it, TipTap is your best option.
Still, Slate might be just the tool you’re looking for, because of its focus on React and a vast amount of plugins if nothing else.
For Vrite, combining Solid.js with TipTap results in an amazing combo. The performance and customizability are right there, all behind a well-crafted API that’s a joy to use. On top of that, having access to ProseMirror under the hood makes the majority of Vrite editor’s advanced features possible.