React Markdown Component
React-markdown is a robust and secure React component designed to render markdown strings into a React element tree. It is currently at version 10.1.0 and is actively maintained with regular minor and patch releases, and significant breaking changes occurring with major version bumps (e.g., v9, v10). A key differentiator is its commitment to security, rendering markdown safely without relying on `dangerouslySetInnerHTML`, thus preventing common XSS vulnerabilities by default. The component leverages the unified ecosystem, specifically remark for markdown parsing and rehype for HTML transformation, enabling extensive customization through a wide array of plugins. Developers can also provide their own React components to override default HTML element renderings, offering fine-grained control over the output. Unlike alternatives that might directly inject HTML or offer less flexibility, react-markdown builds a virtual DOM from a syntax tree, ensuring React efficiently updates only what has changed. It distinguishes itself from `react-remark` and `rehype-react` by being simpler for beginners, while MDX serves a different purpose for embedding JSX within markdown.
Common errors
-
Error [ERR_REQUIRE_ESM]: require() of ES Module .../node_modules/react-markdown/index.js from ... not supported.
cause `react-markdown` is an ESM-only package since v9.0.0, but your project is attempting to import it using CommonJS `require()` syntax.fixChange `const Markdown = require('react-markdown')` to `import Markdown from 'react-markdown'` and ensure your project is configured for ESM (e.g., by adding `"type": "module"` to `package.json` or using a bundler that handles ESM). -
TypeError: Cannot read properties of undefined (reading 'Children') (or similar React 18 related errors)
cause You are using `react-markdown` v9.0.0 or higher with an older version of React (e.g., React 17 or earlier).fixUpgrade your React installation to React 18 or newer, along with its corresponding `@types/react` package. `npm install react@latest react-dom@latest @types/react@latest @types/react-dom@latest`. -
Warning: Received `true` for a non-boolean attribute `className`. If this is expected, cast the value to a string. (This warning may indicate the `className` prop is being used incorrectly with `react-markdown`).
cause The `className` prop was removed from the main `Markdown` component in v10.0.0. Direct styling of the root element or specific child elements via `className` on the `Markdown` component is no longer supported.fixTo apply classes or styles to specific elements rendered by `react-markdown`, use the `components` prop to override the default HTML element renderer. For example: `<Markdown components={{ p: ({node, ...props}) => <p className="my-paragraph" {...props} /> }} />`.
Warnings
- breaking The `className` prop was removed in `react-markdown` v10.0.0. Direct application of `className` to the root Markdown component is no longer supported for styling specific elements.
- breaking `react-markdown` v9.0.0 and later require Node.js 16+ and React 18+ due to underlying dependency updates and API changes.
- breaking Starting with v9.0.0, `react-markdown` is an ESM-only package, meaning `require()` calls will no longer work.
- breaking The `transformImageUri` and `transformLinkUri` props were replaced by a single `urlTransform` prop in v9.0.0, offering a unified way to transform all URLs.
- gotcha While `react-markdown` is safe by default against XSS, using plugins like `rehype-raw` with untrusted markdown input can reintroduce security vulnerabilities by directly injecting raw HTML.
Install
-
npm install react-markdown -
yarn add react-markdown -
pnpm add react-markdown
Imports
- Markdown
const Markdown = require('react-markdown')import Markdown from 'react-markdown'
- MarkdownHooks
import MarkdownHooks from 'react-markdown'
import { MarkdownHooks } from 'react-markdown' - Options
import { Options } from 'react-markdown'import type { Options } from 'react-markdown'
Quickstart
import React from 'react'
import {createRoot} from 'react-dom/client'
import Markdown from 'react-markdown'
const markdown = '# Hi, *Pluto*!\n\nThis is a simple example of how to use `react-markdown`.\n\n- It renders CommonMark by default.\n- You can pass plugins for GFM or other features.\n\nEnjoy rendering your markdown!'
const rootElement = document.getElementById('root') || document.createElement('div');
if (!document.getElementById('root')) {
document.body.appendChild(rootElement);
}
const root = createRoot(rootElement);
root.render(<Markdown>{markdown}</Markdown>);