{"id":10765,"library":"draft-js","title":"Draft.js","description":"Draft.js is a JavaScript framework developed by Facebook for building rich text editors within React applications. It leverages an immutable data model, specifically `immutable-js`, to manage editor state, offering functional state updates and aggressive data persistence for scalable memory usage. The latest stable version is 0.11.7, released in August 2020. However, the project has since been formally archived by Facebook on GitHub in February 2023, making it read-only and indicating that it is no longer actively maintained. This means no further bug fixes, features, or security updates are expected. Key differentiators include its tight integration with React's declarative API for rendering, selection, and input behavior, and its extensible architecture allowing for a wide variety of rich text composition experiences, from basic styling to embedded media.","status":"abandoned","version":"0.11.7","language":"javascript","source_language":"en","source_url":"https://github.com/facebook/draft-js","tags":["javascript","draftjs","editor","react","richtext"],"install":[{"cmd":"npm install draft-js","lang":"bash","label":"npm"},{"cmd":"yarn add draft-js","lang":"bash","label":"yarn"},{"cmd":"pnpm add draft-js","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required for rendering the editor component.","package":"react","optional":false},{"reason":"Required for DOM interaction and rendering.","package":"react-dom","optional":false},{"reason":"Draft.js is built on `immutable-js` for managing editor state. While not a direct peer dependency, it's a fundamental underlying library.","package":"immutable","optional":false}],"imports":[{"note":"CommonJS `require` syntax is often incorrect in modern React projects that are typically ESM-first. Ensure your bundler handles it correctly.","wrong":"const Editor = require('draft-js').Editor;","symbol":"Editor","correct":"import { Editor } from 'draft-js';"},{"note":"Importing directly from `lib/` paths is generally discouraged as it's an internal implementation detail and can break between versions.","wrong":"import EditorState from 'draft-js/lib/EditorState';","symbol":"EditorState","correct":"import { EditorState } from 'draft-js';"},{"note":"Provides methods for applying changes to `ContentState`. Prefer named imports from the main package entry point.","wrong":"import { EditorState, Modifier } from 'draft-js/lib/DraftModifier';","symbol":"Modifier","correct":"import { Modifier } from 'draft-js';"},{"note":"Offers convenience methods for common rich text operations like bold, italic, and block type changes.","wrong":"const RichUtils = require('draft-js/lib/RichUtils');","symbol":"RichUtils","correct":"import { RichUtils } from 'draft-js';"}],"quickstart":{"code":"import React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Editor, EditorState, RichUtils } from 'draft-js';\nimport 'draft-js/dist/Draft.css'; // Essential for basic styling\n\nfunction MyEditor() {\n  const [editorState, setEditorState] = React.useState(\n    EditorState.createEmpty()\n  );\n\n  const editorRef = React.useRef(null);\n\n  const focusEditor = () => {\n    if (editorRef.current) {\n      editorRef.current.focus();\n    }\n  };\n\n  React.useEffect(() => {\n    focusEditor();\n  }, []);\n\n  const handleKeyCommand = (command, editorState) => {\n    const newState = RichUtils.handleKeyCommand(editorState, command);\n    if (newState) {\n      setEditorState(newState);\n      return 'handled';\n    }\n    return 'not-handled';\n  };\n\n  return (\n    <div style={{ border: '1px solid gray', minHeight: '6em', padding: '10px' }} onClick={focusEditor}>\n      <Editor\n        ref={editorRef}\n        editorState={editorState}\n        onChange={setEditorState}\n        handleKeyCommand={handleKeyCommand}\n        placeholder=\"Tell a story...\"\n      />\n    </div>\n  );\n}\n\nconst container = document.getElementById('container');\nif (container) {\n  ReactDOM.render(<MyEditor />, container);\n} else {\n  console.warn(\"Element with ID 'container' not found. Quickstart code won't render.\");\n}","lang":"javascript","description":"This example demonstrates a basic Draft.js editor using React Hooks, including state management, focusing, and handling basic key commands like bold/italic via RichUtils."},"warnings":[{"fix":"Review the official Draft.js documentation on Entity API changes and update your `Entity` creation and management logic to use the new API structure.","message":"The Entity storage API was changed significantly between v0.10.0 and v0.11.0. While v0.10.x supported both old and new APIs, v0.11.0 removed the old API entirely. Projects upgrading from versions prior to 0.10.0 must migrate their entity handling.","severity":"breaking","affected_versions":">=0.11.0"},{"fix":"For new projects, evaluate actively maintained alternatives like Lexical or Slate. For existing projects, understand the risks of using abandoned software and prepare to fork or migrate if critical issues arise.","message":"Draft.js is no longer actively maintained. The project's GitHub repository was archived in February 2023 and the last release was in August 2020. This means there will be no further bug fixes, security patches, or feature development. Consider alternatives for new projects or plan for in-house maintenance for existing ones.","severity":"gotcha","affected_versions":">=0.11.7"},{"fix":"Familiarize yourself with `immutable-js` concepts. For performance-critical applications with extensive content, profile editor behavior and consider optimizing custom components or exploring alternatives.","message":"Draft.js relies heavily on `immutable-js` for its data model. This introduces an additional dependency and a functional programming paradigm that can have a steep learning curve for developers unfamiliar with immutable data structures. Performance can also be a concern with very large documents.","severity":"gotcha","affected_versions":"All"},{"fix":"Ensure `import 'draft-js/dist/Draft.css';` (or equivalent CSS import) is present in your application's entry point or the component where the editor is used.","message":"The editor requires `draft-js/dist/Draft.css` to be included for basic styling. Without it, the editor might appear as a blank input field, have incorrect cursor positioning, or display blocks improperly.","severity":"gotcha","affected_versions":"All"},{"fix":"Avoid batching or delaying `EditorState` updates that are directly propagated to the `Editor` component. Ensure `EditorState` always updates immediately. Be aware that browser extensions can interfere, which is often beyond direct code control.","message":"Draft.js can experience issues with delayed state updates or modifications to the DOM by browser extensions/plugins. The editor expects immediate updates and renders, and delays can cause a disconnect between keystrokes and editor state, leading to broken selection or input.","severity":"gotcha","affected_versions":"All"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Ensure the ref (`editorRef.current` in Hooks or `this.editor` in classes) is checked for null/undefined before calling `focus()`. Use `React.useEffect` with an empty dependency array for initial focus or conditional rendering.","cause":"Attempting to call `editor.focus()` before the editor component's ref is properly assigned or when the component is unmounted.","error":"Cannot read properties of undefined (reading 'focus')"},{"fix":"Add `import 'draft-js/dist/Draft.css';` to your application's entry file or the component where the Draft.js Editor is used.","cause":"The essential `draft-js/dist/Draft.css` stylesheet is not loaded, resulting in missing default styles for block positioning, alignment, and cursor behavior.","error":"The Draft.js editor is blank/empty/not visible, even though it's rendered."},{"fix":"Ensure `EditorState` updates are immediate and synchronous when passed to the `Editor` component. Avoid external DOM modifications within the `contentEditable` area. Consider using `EditorState.push` for controlled changes.","cause":"This often happens with asynchronous updates to React state, leading to race conditions where the editor's internal state doesn't match the DOM, or external DOM manipulation by browser extensions.","error":"Editor state or selection becomes inconsistent or unresponsive after user input."},{"fix":"Install the necessary conversion library (e.g., `draft-js-export-html`, `draft-js-import-html`) using `npm install <package-name>` or `yarn add <package-name>`.","cause":"Attempting to use utility functions (like converting `ContentState` to HTML or Markdown) from external packages without installing them.","error":"Module not found: Error: Can't resolve 'draft-js-export-html'"}],"ecosystem":"npm"}