{"id":11859,"library":"react-simple-wysiwyg","title":"React Simple WYSIWYG Editor","description":"react-simple-wysiwyg is a lightweight and performant React component for creating basic WYSIWYG rich text editing experiences. Currently at version 3.4.1, it focuses on providing essential editing functionality without the extensive features and overhead of more complex editors like Slate.js, Tiptap, CKEditor, or TinyMCE. Its key differentiators include a small bundle size (~9kb, ~4kb gzipped), ease of configuration, and extensibility for simple custom buttons. The library explicitly states it does not sanitize HTML, provide advanced features like table or image editors, or alter HTML generated by the browser, requiring developers to handle these aspects externally (e.g., using `sanitize-html` for sanitization). While it utilizes the deprecated `document.execCommand` API, it justifies this by noting the lack of a modern alternative and its continued use by many popular WYSIWYG editors. The project appears to be actively maintained, with recent updates and open issues on GitHub.","status":"active","version":"3.4.1","language":"javascript","source_language":"en","source_url":"https://github.com/megahertz/react-simple-wysiwyg","tags":["javascript","react","wysiwyg","editor","rich text","typescript"],"install":[{"cmd":"npm install react-simple-wysiwyg","lang":"bash","label":"npm"},{"cmd":"yarn add react-simple-wysiwyg","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-simple-wysiwyg","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency for all React applications using this component.","package":"react","optional":false}],"imports":[{"note":"The primary WYSIWYG component is exported as a default module.","wrong":"import { Editor } from 'react-simple-wysiwyg'; // Editor is the default export, not named.","symbol":"Editor","correct":"import Editor from 'react-simple-wysiwyg';"},{"note":"Used for composing custom toolbars with specific buttons.","wrong":"import Toolbar from 'react-simple-wysiwyg'; // Toolbar is a named export.","symbol":"Toolbar","correct":"import { Toolbar } from 'react-simple-wysiwyg';"},{"note":"Example of a pre-built toolbar button component. Other buttons like `BtnItalic` are also named exports.","wrong":"const { BtnBold } = require('react-simple-wysiwyg'); // This package is ESM-first and ships TypeScript types. Prefer ESM imports.","symbol":"BtnBold","correct":"import { BtnBold } from 'react-simple-wysiwyg';"},{"note":"A utility function for programmatically creating custom toolbar buttons with `document.execCommand`.","symbol":"createButton","correct":"import { createButton } from 'react-simple-wysiwyg';"}],"quickstart":{"code":"import { useState } from 'react';\nimport Editor from 'react-simple-wysiwyg';\n\nfunction MyRichTextEditor() {\n  const [htmlContent, setHtmlContent] = useState('Write your <b>rich text</b> here!');\n\n  // The onChange event provides an event object with e.target.value containing the HTML string.\n  function handleChange(e: { target: { value: string } }) {\n    setHtmlContent(e.target.value);\n  }\n\n  return (\n    <div style={{ maxWidth: '800px', margin: '20px auto', padding: '15px', border: '1px solid #ddd', borderRadius: '8px' }}>\n      <h2>My Simple Editor</h2>\n      <Editor \n        value={htmlContent}\n        onChange={handleChange}\n        containerProps={{ style: { marginTop: '15px', border: '1px solid #ccc', borderRadius: '4px' } }}\n        placeholder=\"Start typing...\"\n      />\n      <p style={{ marginTop: '20px', fontSize: '0.9em', color: '#666' }}>\n        Current HTML Output (for demonstration):\n      </p>\n      <pre style={{ background: '#f8f8f8', padding: '10px', borderRadius: '4px', overflowX: 'auto' }}>\n        {htmlContent}\n      </pre>\n    </div>\n  );\n}\n\n// To render this in a typical React application:\n// import React from 'react';\n// import ReactDOM from 'react-dom/client';\n// const root = ReactDOM.createRoot(document.getElementById('root')!);\n// root.render(<React.StrictMode><MyRichTextEditor /></React.StrictMode>);\n","lang":"typescript","description":"This quickstart demonstrates how to set up `react-simple-wysiwyg` as a controlled component within a React functional component, managing its HTML content using React's `useState` hook. It also shows basic styling and output display."},"warnings":[{"fix":"Be aware of this API's status. There is no direct fix provided by the library, as it's an upstream browser API issue. For applications requiring future-proof or more advanced editor capabilities, consider alternatives built on different technologies (e.g., ProseMirror, Lexical).","message":"The underlying `document.execCommand` API, which `react-simple-wysiwyg` heavily relies on for rich text operations, is deprecated. While currently functional across most browsers, its long-term support and future behavior are uncertain, and it lacks a modern, standardized replacement.","severity":"deprecated","affected_versions":">=1.0.0"},{"fix":"Integrate a robust HTML sanitization library (such as `sanitize-html`) into your application's data flow. Apply sanitization to any HTML content retrieved from the editor's `onChange` event before displaying it or persisting it to a database.","message":"This editor explicitly DOES NOT sanitize HTML input. User-provided content, especially if sourced from untrusted inputs, must be sanitized externally (e.g., using `sanitize-html`) before being rendered or stored, to prevent Cross-Site Scripting (XSS) vulnerabilities.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Evaluate your application's rich text requirements. If advanced features are crucial, explore more feature-rich WYSIWYG editors. If `react-simple-wysiwyg`'s core functionality is sufficient, custom solutions for specific missing features might be integrated, but understand the library's design limitations.","message":"The editor does not include advanced features like table editing, image uploading/embedding, spell check, or complex media integration. It focuses on basic text formatting.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"If clean and consistent HTML output is a critical requirement, you may need to implement a post-processing step to normalize or clean the HTML string received from the editor's `onChange` event, or opt for an editor that offers more explicit control over HTML generation.","message":"By default, the editor does not modify or normalize the raw HTML generated by the browser's `contenteditable` element. This can sometimes result in 'dirty' or inconsistent HTML output depending on user interactions and browser specifics.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Change the import statement from `import { Editor } from 'react-simple-wysiwyg';` to `import Editor from 'react-simple-wysiwyg';`","cause":"Attempting to use `Editor` as a named import when it is the default export of the package.","error":"TypeError: Editor is not a function"},{"fix":"Ensure the `value` prop is always provided and managed by React state, even if it's an empty string initially. For example, use `const [html, setHtml] = useState('');` to initialize the content as an empty string.","cause":"The `value` prop provided to the `Editor` component changes between `undefined` and a string, typically because the initial state is not set or is conditionally applied.","error":"A component is changing an uncontrolled input to be controlled. This is likely caused by the value changing from undefined to a defined value, which should not happen. Decide between using a controlled or uncontrolled input element for the lifetime of the component."},{"fix":"Verify that all toolbar-related components are correctly imported as named exports (e.g., `import { Toolbar, BtnBold } from 'react-simple-wysiwyg';`) and are rendered as children of the `<Toolbar>` component within the `<Editor>`.","cause":"This error often occurs when toolbar button components (e.g., `BtnBold`, `BtnItalic`) are not imported as named exports or are used incorrectly outside the `<Toolbar>` component.","error":"Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. Check the render method of `YourComponent`."}],"ecosystem":"npm"}