Which rich text editor framework should you choose in 2025?

Looking to integrate a WYSIWYG editor into your JavaScript app? This comparison dives into the best frameworks available, including Tiptap, Lexical, BlockNote, and Slate.

, on
Which rich text editor framework should you choose in 2025?

A rich text editor, sometimes referred to as a WYSIWYG (what you see is what you get), is an essential part of many of today’s apps such as Linear, Notion, Google Docs. Even experienced developers find choosing the right one a daunting task that often leads to analysis paralysis. At Liveblocks, we’ve spent the last year digging deep, providing solutions for some of the industry’s most popular editors, and we’ve got opinions and facts, about each.

In this guide we’ll be exploring a number of different editors: Tiptap, BlockNote, Lexical, Slate, ProseMirror, Quill, Plate, Remirror, Editor.js, CKEditor, TinyMCE.

Introduction

In general, these editors fall into two categories: core and batteries-included. Your choice of editor will depend on whether you are building a small feature like a single composer or a fully-fledged collaborative editor with many custom features.

If you’re here for a quick recommendation, we think the most well-rounded choice is Tiptap because it strikes a balance between being a feature-rich editor without being overly opinionated.

Sometimes you want an opinionated editor that delivers what you need out of the box, or a lightweight editor you can mold into your own. We encourage you to read on to explore the potential drawbacks and advantages of other choices.

Collaboration

At Liveblocks, we really care about collaboration. Most editors on this list have realtime collaboration support thanks to a wonderful CRDT library called Yjs. When utilizing Yjs, you still need a backend service to store your document and enable realtime collaboration.

Liveblocks provides a general Yjs backend that will work with any editor that supports Yjs, and we also provide editor-specific integrations for Tiptap and Lexical, with more coming soon. These solutions mean you can get started without maintaining your own back end.

Some editors also have their own operational transform-based solutions or a closed-source cloud solution, which we’ll detail below.

Before we start

For the scope of this article, we won’t include abandoned or unmaintained editors like Draft.js or editors with small communities. We also won’t cover closed-source editors like Froala. Additionally, when it comes to accessibility, each editor will require some work especially if you add plugins, extensions, or frontend frameworks into the mix. We’ll highlight any relevant documentation if it exists.


Tiptap

Tiptap logo

Tiptap is built on top of ProseMirror, a robust yet difficult to master editor. Tiptap abstracts away the cumbersome parts of ProseMirror, leaving an enjoyable developer experience. It also gives you the ability to easily extend its functionality, including an interface into its core ProseMirror plugin system.

Loading

Our advanced collaborative text editor built using Tiptap.

Tiptap has a friendly MIT license and has out-of-the-box support from both Liveblocks and Tiptap Cloud. While Tiptap is packed full of features, they are divided into tree-shakable packages which keep the core bundle size smaller than Quill, Slate, and Lexical.

Extensions

Extending Tiptap is easy, with the ability to add simple nodes, marks, custom commands, and extensions. You can also override the behavior of other extensions, making it simple to customize them to your needs without having to fork or rewrite from scratch.

// Adding some pre-built extensionsconst editor = useEditor({  extensions: [    StarterKit, // Adds standard features, e.g. styles, quotes, lists    Typography, // Adds smart typography, e.g. curly quotes, fractions    liveblocks, // Adds realtime collaboration, comments, mentions  ],});

While most of Tiptap’s features are open-source and MIT-licensed, there are some extensions and features called “pro” extensions which are not open source.

Advanced customization

If you’re planning on a more advanced integration with Tiptap, you’ll most likely need to get your hands dirty with ProseMirror, which has a steeper learning curve. Tiptap’s command system can also take some time to get up to speed with as it hides some complexity of ProseMirror’s transactions while adding the ability to chain commands.

// Toggle the current selection between <p> and <blockquote><button onClick={() => editor.chain().focus().toggleBlockquote().run()}>  💬 Quote</button>

Tiptap relies on a schema for its data model, but unlike ProseMirror, the schema is generated for you by the extensions you add. Most implementations will never need to touch or even know about the schema, but it can be extremely useful for parsing and validation of your document.

Drawbacks

Reading documentation between ProseMirror and Tiptap can be tricky at times, but thankfully Tiptap’s source code is easy to read and has many examples of working with ProseMirror’s core for more advanced plugins. Accessibility is also somewhat poorly documented in Tiptap, whose guide essentially leaves it up to the implementer to handle.

Another drawback is that Tiptap’s performance can slow down quite a bit if you don’t follow a few best practices, such as avoiding traversing document state during transactions and setting shouldRerenderOnTransaction to false when rendering inside React.

Server-side mutations

It’s not easy to run Tiptap on the server to mutate documents. For that, you’ll want to use ProseMirror directly, which can be tricky after getting used to the convenience of Tiptap. Another option is to simply modify the JSON directly. At Liveblocks, we recently released a library to make this a bit easier.

import { withProsemirrorDocument } from "@liveblocks/node-prosemirror";import { Liveblocks } from "@liveblocks/node";
const client = new Liveblocks({ secret: "sk_prod_xxxxxxxxxxxxxxxxxxxxxxxx" });
// Update the document and return the text contentconst text = await withProsemirrorDocument<string>( { client, roomId: "my-room-id", }, async (api) => { // Get and execute a new transaction (tr) await api.update((doc, tr) => { return tr.insertText("hello"); });
return api.getText(); });

Realtime collaboration

Tiptap has extensions that support realtime collaboration backed by Yjs. There’s also two official cloud solutions for adding realtime collaboration to your editor, Tiptap Cloud and Liveblocks Text Editor. Liveblocks Text Editor integrates into all our other features, and includes realtime collaboration, live cursors, comments, mentions, notifications, and version history with more coming soon.

Our Next.js Starter Kit which uses Liveblocks Text Editor + Tiptap.

ProsCons
  • Great documentation.
  • Excellent realtime collaboration support.
  • Framework-agnostic and React-specific packages.
  • Highly extensible.
  • Liveblocks and/or Tiptap Cloud integration.
  • Performance can slow down if you don’t follow best practices.
  • Developing advanced features requires learning ProseMirror internals.
  • Lacks headless server-side editing out-of-the-box.

Get started with Tiptap

If you’d like to build your collaborative Tiptap editor on Liveblocks, we have a number of different ways to get started.

BlockNote

BlockNote logo

BlockNote is an opinionated, batteries-included, block-based editor (like Notion) that extends both Tiptap and ProseMirror. If you’re looking for a block-based editor, this is a great starting point. Most of the same pros as Tiptap make this a solid choice.

Loading

Our advanced collaborative text editor built using BlockNote and Yjs.

In addition to what you get from Tiptap, BlockNote provides many features out-of-the-box, like a slash menu, floating formatting toolbar, slick animations, and more. Unlike Tiptap, BlockNote is primarily focused on React. While it’s possible to use it with vanilla JavaScript or other frameworks, you’ll miss out on the benefits of the UI elements provided by BlockNote.

Drawbacks

While BlockNote itself is completely free and open-source, some packages—such as docx and PDF exporters—require a subscription for use in closed-source products.

Realtime collaboration

BlockNote has realtime collaboration support with Yjs and Liveblocks. We also have a full first-party integration coming soon, make sure to look out for that.

ProsCons
  • Based on battle-tested Tiptap and ProseMirror.
  • Realtime collaboration with Yjs and Liveblocks.
  • Block-based editing API and UI components out-of-the-box.
  • (Mostly) React-only.
  • Heavier bundle size compared to more basic editors.

Check out our guide to getting started with Yjs, React, and BlockNote.


Lexical

Lexical logo

Lexical has gained a lot of popularity lately because it’s backed by Facebook (Meta) and used in their projects. We spent several months developing comments, mentions, version history, and realtime collaboration support for Lexical, and our takeaway is that although Lexical has a large community and commercial backing, it needs more time to mature before we can recommend it over Tiptap. This isn’t surprising, as at the time of writing, it hasn’t received a 1.0 release.

Loading

Our Notion-like AI editor built using Lexical.

If you like Lexical, need comments, collaboration, or mentions while also avoiding some of the growing pains we discovered, our package is a good place to start.

Drawbacks

One of the main issues in extending Lexical is its lack of pure decorations—the ability to style content without affecting the document itself. While Lexical does have “decorator nodes,” they mutate the content of the document. This means that features like collaborative cursors must calculate and draw HTML divs on top of the text and listen to scroll/resize events to compensate. Slate (Plate) and ProseMirror (Tiptap, Remirror, BlockNote) both have a pure decorations feature.

Realtime Collaboration

Without the ready-made Liveblocks package, collaboration in Lexical is also particularly difficult. While no editor’s collaboration features are perfect (it’s a really difficult problem to solve well), there are still quite a few issues that cause concern. Lexical’s collaboration implementation hardcodes the name of the root node, making it impossible to have more than one Lexical editor per Yjs document.

Some of the examples, like StickyNotes in the playground, get around this using nested Lexical composers, instantiating new documents, and new WebSocket connections for each sticky note. This workaround would not scale in production. The good news is that development is moving fast, and we’ve already seen many issues resolved since we began integrating with Lexical.

Extending Lexical

Lexical’s data structure is a hierarchy of nodes and each node is overridable and customizable. You can also add your own nodes based on one of the 4 core node types:

Lexical’s core is framework-agnostic, but it has a first-party React integration with its own context, called LexicalComposer, as part of the @lexical/react package. Most of the core plugins are then reimplemented as children of the LexicalComposer. Lexical also allows you to run headless on a backend without DOM, using the @lexical/headless package. This is useful for editing documents server-side.

Server-side mutations

It’s possible to edit Lexical on the server using its core helper functions. We’ve created a library at Liveblocks to make this simpler.

import { $getRoot } from "lexical";import { $createParagraphNode, $createTextNode } from "lexical/nodes";import { withLexicalDocument } from "@liveblocks/node-lexical";import { Liveblocks } from "@liveblocks/node";
const client = new Liveblocks({ secret: "sk_prod_xxxxxxxxxxxxxxxxxxxxxxxx" });
await withLexicalDocument({ client, roomId: "my-room-id" }, async (doc) => { await doc.update(() => { // Adding a paragraph node with contained text node const root = $getRoot(); const paragraphNode = $createParagraphNode(); const textNode = $createTextNode("Hello world"); paragraphNode.append(textNode); root.append(paragraphNode); });});
ProsCons
  • Yjs realtime collaboration support.
  • Framework-agnostic and React-specific packages.
  • Liveblocks integration with comments, mentions, and version history.
  • Very active development and a large community with Meta backing.
  • Yjs realtime collaboration support is a bit buggy without handling edge cases yourself.
  • Lacks pure decorations, requiring DOM workarounds for advanced features.
  • Heavier core package than Tiptap and Slate.

Check out our guide to getting started with Lexical.


Slate

Slate logo

Slate is a customizable and powerful framework for creating rich text editors. It’s used by Discord, Grafana, Sanity.io, Slite, and more. Slate provides developers with complete control over the editing experience while maintaining an intuitive design.

Loading

Our collaborative text editor built using Slate and Yjs.

At Liveblocks, we also chose Slate as the default editor for our comments composer UI component. We chose Slate because it supports a wide range of functionalities, including rich text formatting, complete control of the editor, custom node types, and an acceptable bundle size. Slate is vanilla JavaScript, but a React package exists and can be integrated with other frameworks as well.

Extending Slate

Slate has a very well documented system for extending its functionality. You can define custom elements, transforms, styles, and events. While Slate’s core feature set is not as complete as some other editors, it has a very extensive list of examples to show you how to add those features on your own. If you want a more opinionated and batteries-included version of Slate, Plate is an excellent option.

Drawbacks

Slate’s bundle size is slightly larger than Tiptap and there aren’t quite as many plugins/extensions in the ecosystem, leaving it up to you to implement some features.

Realtime collaboration

Slate can be made collaborative with external extensions such as slate-yjs and @liveblocks/yjs.

ProsCons
  • Great documentation.
  • Yjs realtime collaboration support.
  • Framework-agnostic and React-specific packages.
  • Highly extensible.
  • Slightly heavier bundle size than Tiptap.
  • Lacks out-of-the-box features.

Get started with Slate

Check out our guide to getting started with Yjs, React, and Slate.


Quill

Quill logo

Quill is a powerful editor that has been used by many popular apps like Slack, LinkedIn, Figma, Zoom, Miro, and Airtable. Quill has been stagnant in recent years; however, its version 2, released in April 2024, is a rewrite that focuses on fixing many of the issues which caused some developers to move on. Quill 2 has also been rewritten in TypeScript. Quill’s document model is called Parchment, and users can use it to define their own “blots” that describe attributes, blocks, embeds, and anything else. This is a similar concept to ProseMirror’s schemas, nodes, and marks.

Loading

Our collaborative text editor built using Quill and Yjs.

Quill is licensed under the permissive BSD-3-Clause license, making it ideal for both personal and commercial use. Quill is backed by Slab, a commercial company, and also has a very strong community on GitHub. Before April’s release, it had only received a few updates in the previous few years. We’ll keep an eye on Quill to see if its comeback is sustained.

Quill does not require a specific framework, so it can be seamlessly integrated into various frameworks such as React.

Drawbacks

Like Lexical, Quill lacks pure decorations, which allow you to style content without modifying the document model. This is useful for things like search/replace, collaborative cursors, etc. An entire library called quill-cursors exists just to overcome this limitation by placing DOM elements on top of the editor.

Realtime collaboration

Quill can be made collaborative by using Yjs and y-quill with an optional backend like Liveblocks. Quill also has an Elixir-based operational transform backend called Delta.

ProsCons
  • Good documentation.
  • Framework-agnostic and React-specific packages.
  • Yjs realtime collaboration support.
  • Simple delta format.
  • Fewer out-of-the-box features and plugins haven’t yet updated to Quill 2
  • Lack of pure decorations.
  • Somewhat less active development and a smaller community.
  • Twice the bundle size of Tiptap or Slate.

Check out our guide to getting started with Yjs, React, and Quill.


ProseMirror

ProseMirror logo

ProseMirror powers Tiptap, Remirror, BlockNote, and others. It is one of the most battle-tested editors out there. ProseMirror relies on a schema for its data structure and has a clear separation of concerns in its codebase. The main ingredients of a ProseMirror editor are state, view, model, and transforms, which are individual packages that can be imported on their own. In addition to these modules, you will also need a schema and at least the prosemirror-example-setup just to get going.

Drawbacks

To quote ProseMirror’s documentation directly:

“Setting up a full editor ‘from scratch’, using only the core libraries, requires quite a lot of code.”

For this reason, unless you’re a purist, masochist, or both, we recommend starting with one of the excellent ProseMirror-based editors such as Tiptap, Remirror, or BlockNote. However, if you’re going to be modifying any of the aforementioned editors, it’s definitely worth learning how ProseMirror works. Thankfully, stellar documentation and an active community make this easier.

ProsCons
  • Excellent documentation with an active community.
  • Yjs realtime collaboration support.
  • Requires a lot of code for a basic example.
  • Fewer out-of-the-box features.
  • Steeper learning curve.

Plate

Plate logo

Plate is built on top of Slate and adds a host of features like UI, dozens of prebuilt plugins, and entire templates. This is an impressive upgrade over Slate if you’re looking for a more opinionated “batteries-included” editor.

Plate also maintains a large amount of flexibility with its plugins, so you can choose to incorporate block-based editing, floating toolbars, mentions, comments, and AI features. Most of these advanced features will require some additional work to implement, such as a backend to store comments. While Plate is free and open-source under the MIT license, it also offers a paid template with lifetime access for a fixed price.

Drawbacks

One drawback to Plate is that most of its functionality—such as plugins, primitives, and components—is React-only. Another drawback is that, at the time of writing, collaboration is only possible through Hocuspocus. However, there’s no technical reason for this, and it wouldn’t be too difficult to add support for other Yjs providers such as Liveblocks. Let us know if you’d like us to build a compatible package backed by Liveblocks!

ProsCons
  • Extensive library of plugins.
  • Server-side editing support.
  • Templates to help you get started fast.
  • React-only.
  • Collaboration is only available through Hocuspocus.
  • Heavier bundle size compared to more basic editors.

Remirror

Remirror logo

Remirror is a project very similar to Tiptap that takes a more opinionated and batteries-included approach, with over 30 plugins, React hooks, i18n, and a11y accessibility. It is built on top of ProseMirror, just like Tiptap, and has a friendly MIT license.

It is one of the few editors that explicitly states its support of a11y and accessibility. Now at version 3, it’s considered a stable and mature editor.

Drawbacks

Drawbacks compared to Tiptap are that its community is a bit smaller, with slower updates, and most of its functionality is React-only. Additionally, the bundle sizes of Remirror and its extensions tend to be larger than Tiptap.

Realtime collaboration

Remirror supports realtime collaboration with Yjs and Liveblocks through its YjsExtension.

ProsCons
  • Great documentation.
  • Extensive library of plugins.
  • Collaboration with Yjs and Liveblocks.
  • React-only.
  • Larger bundle size.
  • Smaller community with less frequent updates.

Editor.js

Editor.js logo

Editor.js is a well-established block-based rich text editor that is actively maintained with a large community. Editor.js offers many plugins (called Tools) and a modern design. The data structure consists of blocks, inlines, and tunes.

The core API has a few extra features that other editors don’t have built-in, such as tooltips. The editor itself is framework-agnostic, and there are many community-made plugins and wrappers for almost every framework, as well as backend frameworks and CMS integrations.

Drawbacks

The biggest drawback to Editor.js is the lack of any kind of realtime collaboration support, which we believe is crucial to most modern apps. There are a few PRs and some unmaintained attempts at Yjs support, but nothing that’s part of the core product. Due to its opinionated and feature-rich nature, the package size is also quite large, even without the useful plugins.

Realtime collaboration

Editor.js does not support realtime collaboration.

ProsCons
  • Feature-rich with an extensive library of plugins.
  • Many community-made integrations with various CMS and backend frameworks.
  • Larger bundle size.
  • Lack of realtime collaboration support.

CKEditor

CKEditor logo

CKEditor has an impressive feature set, and the editor itself dates back more than 20 years! The current version, CKEditor 5, is very modern and easy to use. CKEditor also features a plugin system and support for Angular, React, Vue, Next, and more. CKEditor is a solid choice as long as you are aware of the drawbacks of a GPL-2 license, which may require you to open-source derivative works. Of course, CKSource sells you a non-GPL license as well as cloud services for realtime collaboration. CKEditor’s cloud pricing is based on “editor loads”.

Drawbacks

Many of its features are behind a paywall, such as markdown, media embeds, mentions, comments, and even multi-level lists. The extensive list of paywalled features and restrictive license are a blocker to our recommendation. However, if you need a white-glove solution and are willing to pay, it may be worth looking into.

Realtime collaboration

As far as we can tell, there is no other collaboration backend available besides CKEditor’s proprietary solution.

ProsCons
  • Extremely feature-rich out-of-the-box.
  • Works with many frameworks.
  • Locked into CKEditor’s cloud service for collaboration.
  • GPL-2 license may be a blocker for some.
  • Some features are paid with load-based pricing.

TinyMCE

TinyMCE logo

Like CKEditor, TinyMCE is also over 20 years old and also under the GPL-2 license. Despite its age, it’s well supported and actively maintained. Their cloud service also prices based on editor load. TinyMCE is available for vanilla JavaScript, React, Vue, and Angular.

Drawbacks

The list of features is comparable to CKEditor, and many of TinyMCE’s plugins—such as markdown, mentions, comments, and even advanced typography—are behind the paywall. We couldn’t find a way based on the documentation to modify documents on the backend.

Realtime collaboration

As far as we can tell, there is no other collaboration backend available besides TinyMCE’s proprietary solution.

ProsCons
  • Extremely feature-rich out-of-the-box.
  • Works with many frameworks.
  • Locked into Tiny Cloud for collaboration.
  • GPL-2 license may be a blocker for some.
  • Some features are paywalled with load-based pricing.

Comparison table

EditorExtended fromFrameworkCollaborationCommentsMentionsServer-side editingLicenseStars
ProseMirrorVanillaYjsNo, but there are examplessuggestion pluginYes, prosemirror-state and prosemirror-model can be used to modify a document in NodeJs or using Liveblocks’ Node.js ProseMirror packageMIT
TiptapProseMirrorVanilla, React, Vue, SvelteLiveblocks, Tiptap Cloud, YjsZero config with Liveblocks, Tiptap available, custom possibleZero config with Liveblocks, Tiptap available, custom possiblePossible via ProseMirror or using Liveblocks’ Node.js ProseMirror packageMIT
RemirrorProseMirrorReactYjsYesYesPossible via ProseMirror or using Liveblocks’ Node.js ProseMirror packageMIT
BlockNoteProseMirror, TiptapReactYjsYes with Liveblocks or custom examplesYesPossible via ProseMirror or using Liveblocks’ Node.js ProseMirror packageMPL 2
LexicalVanilla, React, iOS, Others*Liveblocks, YjsZero config with Liveblocks, custom possibleZero config with Liveblocks, custom possiblePossible using lexical/headless or Liveblocks’ Node.js Lexical package.MIT
SlateVanilla, ReactYjsNo, but there are examplesNo, but an example exists in the repoNoMIT
PlateSlateReact OnlyHocuspocus (Yjs)YesYesYesMIT
QuillVanillaYjsNo, but there are examplesNo, but there’s a third party libraryNoBSD-3
Editor.jsVanillaNo, but some are working on it.No, but a third party library exists.No, but examples existNo, but some third party examples existApache 2
CKEditorVanilla, React, Vue, AngularYes, with CKEditor CloudYesYesYesGPL-2+
TinyMCEVanilla, React, Vue, Angular, and moreYes, with Tiny CloudYes, with Tiny cloudYesNoGPL-2+

Ready to get started?

Join thousands of companies using Liveblocks ready‑made collaborative features to drive growth in their products.

Start today for free