{"id":12042,"library":"slate","title":"Slate: Customizable Rich Text Editor Framework","description":"Slate is a unopinionated and completely customizable framework for building rich text editors, providing a foundational set of primitives rather than a monolithic solution. It allows developers to create bespoke editing experiences by composing plugins and extending its core data model. Currently at version `0.124.1` (core `slate` package), it maintains an active development pace with frequent patch and minor releases across its monorepo packages (e.g., `slate-react`, `slate-history`, `slate-dom`). Key differentiators include its pluggable architecture, a robust data model representing content as a nested tree, and deep integration with React for rendering. This approach enables it to be adapted for a wide range of applications, from simple note-taking to complex document authoring systems, by avoiding prescriptive UI/UX decisions.","status":"active","version":"0.124.1","language":"javascript","source_language":"en","source_url":"git://github.com/ianstormtaylor/slate","tags":["javascript","canvas","contenteditable","custom","document","edit","editor","html","immutable","typescript"],"install":[{"cmd":"npm install slate","lang":"bash","label":"npm"},{"cmd":"yarn add slate","lang":"bash","label":"yarn"},{"cmd":"pnpm add slate","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for `slate-react`, the primary way to integrate Slate into web applications.","package":"react","optional":false},{"reason":"Required for `slate-react` for rendering the editor.","package":"react-dom","optional":false},{"reason":"Commonly used for undo/redo functionality in a Slate editor setup.","package":"slate-history","optional":true}],"imports":[{"note":"Primary function to initialize a new Slate editor instance. Modern usage strongly favors ESM imports.","wrong":"const createEditor = require('slate').createEditor;","symbol":"createEditor","correct":"import { createEditor } from 'slate';"},{"note":"These are the core components and HOC for integrating Slate into a React application. `withReact` is essential for connecting the Slate editor to React's rendering lifecycle.","wrong":"const { Slate, Editable, withReact } = require('slate-react');","symbol":"Slate, Editable, withReact","correct":"import { Slate, Editable, withReact } from 'slate-react';"},{"note":"These are fundamental TypeScript types for defining the structure of Slate content and extending the editor's capabilities. Developers must extend these in their application's `CustomTypes`.","symbol":"Descendant, Editor, Element, Text","correct":"import { Descendant, Editor, Element, Text } from 'slate';"},{"note":"Used as an editor enhancer to add undo/redo capabilities.","symbol":"withHistory","correct":"import { withHistory } from 'slate-history';"}],"quickstart":{"code":"import React, { useMemo, useState } from 'react';\nimport { createEditor, Descendant } from 'slate';\nimport { Slate, Editable, withReact, ReactEditor } from 'slate-react';\nimport { withHistory } from 'slate-history';\n\n// Define our custom editor and element types for TypeScript to enable type safety\ntype CustomEditor = ReactEditor;\ntype ParagraphElement = { type: 'paragraph'; children: CustomText[] };\ntype CustomText = { text: string; bold?: boolean; italic?: boolean };\n\ndeclare module 'slate' {\n  interface CustomTypes {\n    Editor: CustomEditor;\n    Element: ParagraphElement;\n    Text: CustomText;\n  }\n}\n\nconst initialValue: Descendant[] = [\n  {\n    type: 'paragraph',\n    children: [{ text: 'Hello, Slate!' }],\n  },\n  {\n    type: 'paragraph',\n    children: [{ text: 'This is some ' }, { text: 'bold', bold: true }, { text: ' text.' }],\n  },\n];\n\nconst MySimpleEditor = () => {\n  // Create a Slate editor object that won't change across renders.\n  // It's enhanced with React capabilities and history (undo/redo).\n  const editor = useMemo(() => withHistory(withReact(createEditor())), []);\n  const [value, setValue] = useState<Descendant[]>(initialValue);\n\n  return (\n    <Slate editor={editor} value={value} onChange={setValue}>\n      <Editable\n        placeholder=\"Start typing...\"\n        // Define a rendering function for elements\n        renderElement={props => <p {...props.attributes}>{props.children}</p>}\n        // Define a rendering function for leaf nodes (text with formatting)\n        renderLeaf={props => {\n          let children = props.children;\n          if (props.leaf.bold) children = <strong>{children}</strong>;\n          if (props.leaf.italic) children = <em>{children}</em>;\n          return <span {...props.attributes}>{children}</span>;\n        }}\n        style={{ border: '1px solid #ccc', padding: '10px', minHeight: '100px' }}\n      />\n    </Slate>\n  );\n};\n\nexport default MySimpleEditor;\n","lang":"typescript","description":"This quickstart demonstrates how to set up a basic Slate editor with React and TypeScript, including custom type definitions and simple bold text rendering. It shows the initialization of the editor with `createEditor`, `withReact`, and `withHistory`, and then renders it using the `Slate` provider and `Editable` component."},"warnings":[{"fix":"Thoroughly review release notes for each minor version upgrade. Expect to refactor code related to editor operations, data models, or plugin APIs. Consult migration guides if available.","message":"Slate's `0.x` versioning scheme means that minor versions (`0.x.y` to `0.z.w` where `x != z`) can introduce significant breaking changes to the API and internal data structures. Users should always review the changelog when updating minor versions.","severity":"breaking","affected_versions":">=0.x"},{"fix":"Update existing code to use `Location.isPath`, `Location.isPoint`, `Location.isRange`, and `Location.isSpan` where appropriate, especially in performance-critical loops or frequently called functions.","message":"The `slate@0.123.0` release introduced new, more efficient type discriminators like `Location.isPath`, `Location.isPoint`, `Location.isRange`, and `Location.isSpan`. While the older `Path.isPath`, `Point.isPoint`, etc., still exist, the new `Location` prefixed versions are recommended for better performance and consistency.","severity":"gotcha","affected_versions":">=0.123.0"},{"fix":"Always initialize your editor instance using `useMemo` to ensure it's stable across renders, as shown in the quickstart. If your editor needs to dynamically change based on props, ensure `editor` is correctly listed as a dependency in relevant `useEffect` hooks, or pass an immutable editor instance.","message":"Ensuring the `Slate` component properly handles editor updates in `slate-react` requires careful management of the editor instance. If the `editor` object itself is re-created or mutated in a way that React's `useEffect` hooks don't track, the editor might not reflect changes correctly.","severity":"gotcha","affected_versions":">=0.124.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure you have a `declare module 'slate' { interface CustomTypes { Editor: MyCustomEditor; Element: MyCustomElement; Text: MyCustomText; } }` block in a `.d.ts` file or at the top of your relevant TypeScript file, and that your custom types correctly extend the base Slate types (`ReactEditor`, `BaseElement`, `BaseText`).","cause":"Incorrectly extending Slate's built-in TypeScript types (Editor, Element, Text) or failing to declare the custom types module.","error":"Type 'MyCustomEditor' is not assignable to type 'ReactEditor'.\n  Type 'MyCustomEditor' is missing the following properties from type 'ReactEditor': markIs) and related React DOM properties."},{"fix":"Wrap your `Editable` component and any custom components utilizing Slate hooks within the `<Slate editor={editor} value={value} onChange={setValue}>` provider component.","cause":"Attempting to use `Editable` or any Slate-related hooks (`useEditor`, `useSlate`, etc.) outside of a `<Slate>` component context.","error":"Error: Editor instance not found in context. This is likely because you've used `useEditor` outside of a `<Slate>` context."},{"fix":"Add a `default` case to your `switch` statement in `renderElement` and `renderLeaf` to handle unexpected node types gracefully. Ensure all custom element types you define in `CustomTypes` are explicitly handled in `renderElement`.","cause":"Your `renderElement` or `renderLeaf` function is not correctly handling different types of nodes or is expecting properties that aren't present on the given node.","error":"Cannot read properties of undefined (reading 'children') when rendering a custom element."}],"ecosystem":"npm"}