{"id":11747,"library":"react-mde","title":"React Markdown Editor Component","description":"react-mde is a React component that provides a feature-rich Markdown editor, aiming for parity with the GitHub Markdown editor experience. It functions as a controlled component, requiring both a `value` prop for the Markdown content and an `onChange` handler for updates. A key differentiator is its extensibility; it allows developers to provide a custom `generateMarkdownPreview` function, making it agnostic to the chosen Markdown parsing library (e.g., Showdown or react-markdown). The component also supports custom icons and configurable toolbar commands. It relies on Draft.js for advanced text editing features like history management and mentions. The current stable version is 11.5.0, published approximately five years ago. Due to the lack of recent updates and noted unresolved issues, such as mobile compatibility tied to an unaddressed Draft.js problem, the project appears to be unmaintained.","status":"abandoned","version":"11.5.0","language":"javascript","source_language":"en","source_url":"https://github.com/andrerpena/react-mde","tags":["javascript","react","component","markdown","editor","text-editor","markdown-editor","typescript"],"install":[{"cmd":"npm install react-mde","lang":"bash","label":"npm"},{"cmd":"yarn add react-mde","lang":"bash","label":"yarn"},{"cmd":"pnpm add react-mde","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Peer dependency for rendering React components.","package":"react","optional":false},{"reason":"Peer dependency for rendering React components to the DOM.","package":"react-dom","optional":false},{"reason":"Core dependency for rich text editing features like history management and mentions.","package":"draft-js","optional":false},{"reason":"Commonly used optional dependency for client-side Markdown to HTML conversion in the preview pane.","package":"showdown","optional":true}],"imports":[{"note":"ReactMde is a default export.","wrong":"import { ReactMde } from 'react-mde';\nimport * as ReactMde from 'react-mde';","symbol":"ReactMde","correct":"import ReactMde from 'react-mde';"},{"note":"The `react-mde-all.css` file includes all necessary styles. Individual CSS files can be imported for granular control.","wrong":"import 'react-mde/lib/styles/css/react-mde.css';","symbol":"CSS Styles","correct":"import 'react-mde/lib/styles/css/react-mde-all.css';"},{"note":"Showdown is a popular choice for client-side Markdown parsing, often imported as a namespace.","wrong":"import Showdown from 'showdown';","symbol":"Showdown Converter (example)","correct":"import * as Showdown from 'showdown';\nconst converter = new Showdown.Converter({ tables: true, simplifiedAutoLink: true });"}],"quickstart":{"code":"import React, { useState, useCallback } from 'react';\nimport ReactMde from 'react-mde';\nimport * as Showdown from 'showdown';\nimport 'react-mde/lib/styles/css/react-mde-all.css';\n\nconst converter = new Showdown.Converter({\n  tables: true,\n  simplifiedAutoLink: true,\n  strikethrough: true,\n  tasklists: true,\n});\n\nfunction MyMarkdownEditor() {\n  const [value, setValue] = useState('**Hello world!!!**');\n  const [selectedTab, setSelectedTab] = useState<'write' | 'preview'>('write');\n\n  const generatePreview = useCallback((markdown) => {\n    return Promise.resolve(converter.makeHtml(markdown));\n  }, []);\n\n  return (\n    <div style={{ maxWidth: 800, margin: 'auto', padding: '20px' }}>\n      <ReactMde\n        value={value}\n        onChange={setValue}\n        selectedTab={selectedTab}\n        onTabChange={setSelectedTab}\n        generateMarkdownPreview={generatePreview}\n        minEditorHeight={200}\n        minPreviewHeight={200}\n      />\n    </div>\n  );\n}\n\nexport default MyMarkdownEditor;","lang":"typescript","description":"Demonstrates a basic controlled `ReactMde` component, managing Markdown content and tab selection with React hooks and integrating Showdown for preview generation."},"warnings":[{"fix":"Consider migrating to a more actively maintained Markdown editor component for long-term project health. If staying with react-mde, be prepared to fork and maintain it yourself or accept potential compatibility and security risks.","message":"The project appears to be unmaintained. The latest version (11.5.0) was published approximately five years ago, indicating a lack of ongoing support, bug fixes, or compatibility updates for newer React versions or browser changes.","severity":"breaking","affected_versions":">=11.5.0"},{"fix":"Always sanitize the HTML generated by your `generateMarkdownPreview` function, especially if dealing with untrusted user input. Integrate a dedicated HTML sanitization library (e.g., `dompurify`) or ensure your Markdown parser has built-in sanitization features enabled.","message":"React-mde does not automatically sanitize the HTML output generated for the Markdown preview. Using client-side Markdown parsers like Showdown without explicit sanitization can expose your application to Cross-Site Scripting (XSS) vulnerabilities if user-supplied content contains malicious scripts.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"For mobile experiences, consider implementing a conditional rendering strategy to replace react-mde with a standard `<textarea>` or a mobile-specific input, or use an alternative editor that explicitly supports mobile. Test thoroughly on target mobile devices.","message":"Mobile support for react-mde is noted as problematic and depends on fixes for Draft.js, which are not being actively addressed by Draft.js maintainers (Facebook). This means the editor may not function correctly or provide a good user experience on mobile devices.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Ensure you include `import 'react-mde/lib/styles/css/react-mde-all.css';` in your entry file or component where `ReactMde` is used. For more granular control, individual CSS files can be imported, but `react-mde-all.css` is generally recommended for quick setup.","message":"Styling requires importing a CSS file. If `react-mde/lib/styles/css/react-mde-all.css` is not imported, the editor will appear unstyled and potentially non-functional visually.","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":"Run `npm install react-mde showdown` (or `yarn add react-mde showdown`). Ensure the import path is `import ReactMde from 'react-mde';`.","cause":"The `react-mde` package is not installed or incorrectly imported.","error":"Cannot find module 'react-mde' or its corresponding type declarations."},{"fix":"Ensure `showdown` is installed (`npm install showdown`) and correctly imported. The `generateMarkdownPreview` function must return a `Promise<string | ReactElement>`. Example: `generateMarkdownPreview={markdown => Promise.resolve(converter.makeHtml(markdown))}`.","cause":"The `generateMarkdownPreview` prop is either missing, returns an invalid value, or the Markdown converter (e.g., Showdown) is not correctly initialized or installed.","error":"TypeError: Cannot read properties of undefined (reading 'makeHtml') or similar error related to markdown conversion."},{"fix":"Always initialize the `value` prop with a non-null/non-undefined string, typically an empty string (`''`) or initial Markdown content. Ensure `value` and `onChange` are consistently provided for controlled component behavior.","cause":"The `ReactMde` component is being used with a `value` prop that changes from `undefined` to a defined string, or vice-versa, without a corresponding `key` prop to force re-mounting.","error":"Error: A component is changing an uncontrolled input of type text to be controlled."}],"ecosystem":"npm"}