Slate.js is a highly customizable platform for creating rich-text editors, also known as WYSIWYG editors. It enables you to create powerful, intuitive editors similar to those you’ve probably used in Medium, Dropbox Paper, or Google Docs. These are quickly becoming standard features for many web apps, and tools like Slate make them easier to implement, ensuring your program won’t get bogged down in complexity.
Although Slate is still in beta at the time of writing, it’s natural to ask whether it has the potential to replace more mature platforms like Quill and Draft.js. The short answer is that it’s far too early to tell, but here are a few facts to support why it could.
Building a rich-text editor for your React application has not been easy. As applications grow in size, a more productive and support-rich tool is necessary. With frameworks like Quill, developers must go through substantial hacks to fix performance issues. But Slate.js was designed to make things easier with the following features:
Other React-based rich-text editors like Quill and Draft offer plugins that provide users with additional capabilities. Slate, on the other hand, recognizes plugins as first-class entities; the basic editing functionality is even designed as a distinct plugin. That means you can completely alter the editing experience, allowing you to develop complex editors like Medium or Dropbox without having to contend with the library’s standard assumptions.
The DOM serves as the foundation for Slate’s data model. The document is a hierarchical tree that employs selects and ranges and exposes all of the usual event handlers. This implies that sophisticated features such as tables and nested block quotations are possible. Slate can perform pretty much whatever you can do in the DOM.
Slate’s document model, like the DOM itself, is a layered, recursive tree. Depending on your use case, you can incorporate complicated components like tables and nested block quotations, as we noted above, or you can keep things simple by merely employing a single level of hierarchy.
The Slate editor is stateless, utilizing immutable data structures via React and Immutable.js, making it much easier to reason about code and write plugins. For comparison’s sake, Quill handles its own changes, for example, and does not allow users to prevent edits. Quill cannot prevent the change, but it will override the content anytime the value varies from the existing state.
Slate’s core logic makes no assumptions about the structure of the data you’ll be changing, so there are no assumptions baked into the library that will catch you off guard when you need to move beyond the most basic use cases. This can cause serious performance issues when working with Quill and Draft.js.
With a plugin-first design and a schema-less core, the line between “core” and “custom” is much more apparent, which means the core experience doesn’t become bogged down in edge cases.
Slate texts are edited with “changes,” which are meant to be high-level and straightforward to create and understand, allowing custom functionality to be as expressive as possible. This dramatically improves your ability to reason about your code.
Slate’s data format is intended to allow collaborative editing to be built on top, so developers don’t have to rethink everything if you decide to make your editor collaborative.
Now let’s see Slate in action by building a simple rich-text editor. To get started, we need to create a new React project; we’ll use Create React App for that. Run the command below:
npx create-react-app rich-text-editor
You can make a cup of coffee while the necessary packages are installed. When the installation is complete, install the three required packages for our Slate implementation with the command below:
npm i --save slate slate-react slate-history
Then, start the application:
npm start
Next, open the App.js
component and import our installed packages:
import React, { useMemo, useState } from 'react' import { createEditor } from 'slate' import { Slate, Editable, withReact } from 'slate-react'
The next step is to create a new Editor
object. We will use the useEditor
hook to make our editor stable across renders. Then, we’ll create a state to handle the input in our editor with a paragraph and some dummy text:
const editor = useMemo(() => withReact(createEditor()), []) const [value, setValue] = useState([ { type: 'paragraph', children: [{ text: 'I am a Slate rich editor.' }], }, ])
Now, let’s keep track of our Slate editor, its plugins, its value, its selection, and all changes made to the editor by rendering the Slate context provider. Then, render the <Editable>
component inside our React context.
The <Editable>
component behaves similarly to the contentEditable
component in React. It will render an editable rich-text document for the nearest editor
context whenever it is rendered. Modify the render method with the code below:
return ( <Slate editor={editor} value={value} onChange={newValue => setValue(newValue)} > <Editable /> </Slate> )
Now that you have your text editor, test out the application on localhost:3000
in your favorite browser.
Slate was created to address the challenges developers might encounter when building large-scale applications with Quill and Draft.js. It was designed to transform the document’s creation by making adjustments, which is necessary for developing advanced behaviors. That has often proved overly complicated with Quill or Draft.
Quill, no doubt, is a drop-in editor; you can get started without changing anything. If you get beyond the most basic use cases, however, you may encounter certain performance issues, which have become a recognized defect.
Slate, on the other hand, was designed to facilitate actual productivity by providing you the flexibility to do whatever you choose. Slate offers sophisticated integrations with Markdown, Google Docs, and Medium out of the box to enable for seamless collaboration with teammates.
It allows you to perform complex operations like adding tables, and inserting images and bulleted lists into those tables. Slate.js makes serialization to HTML, Markdown, and other formats possible. Simple tasks like converting a document to HTML or Markdown is made a lot easier with less boilerplate code.
With all that said, it’s definitely worth giving Slate.js a try.
To be honest, this may not be the case. Slate.js is still in beta, which means the stable version is yet to be released. Your app might crash, or some features might not work properly.
Again, despite their imperfections, Quill and Draft.js have been in production for a long time now. And as much as we might wish otherwise, there is no such thing as perfection when it comes to programming languages. On top of that, it’s not easy for an org to change its system to something entirely new within a short period.
Ultimately, Slate has not been rigorously used for production-grade applications, and it hasn’t been proven to handle those ambiguous tasks that expose Quill and Draft as inefficient.
Maybe in a year or so, we’ll start hearing from companies and developers about their experience with Slate — how they’ve overcome the known flaws in Quill and Draft. Perhaps the community behind it will modify it to the point where it’s a truly viable solution. Will it replace Quill and Draft? We can’t tell for now.
There’s no doubt that frontends are getting more complex. As you add new JavaScript libraries and other dependencies to your app, you’ll need more visibility to ensure your users don’t run into unknown issues.
LogRocket is a frontend application monitoring solution that lets you replay JavaScript errors as if they happened in your own browser so you can react to bugs more effectively.
LogRocket works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app’s performance, reporting metrics like client CPU load, client memory usage, and more.
Build confidently — start monitoring for free.
Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowSOLID principles help us keep code flexible. In this article, we’ll examine all of those principles and their implementation using JavaScript.
JavaScript’s Date API has many limitations. Explore alternative libraries like Moment.js, date-fns, and the new Temporal API.
Explore use cases for using npm vs. npx such as long-term dependency management or temporary tasks and running packages on the fly.
Validating and auditing AI-generated code reduces code errors and ensures that code is compliant.