MCPcopy
hub / github.com/remarkjs/react-markdown

github.com/remarkjs/react-markdown @10.1.0 sqlite

repository ↗ · DeepWiki ↗ · release 10.1.0 ↗
31 symbols 70 edges 4 files 12 documented · 39%
README

react-markdown

[![Build][badge-build-image]][badge-build-url] [![Coverage][badge-coverage-image]][badge-coverage-url] [![Downloads][badge-downloads-image]][badge-downloads-url] [![Size][badge-size-image]][badge-size-url]

React component to render markdown.

Feature highlights

  • [x] [safe][section-security] by default (no dangerouslySetInnerHTML or XSS attacks)
  • [x] [components][section-components] (pass your own component to use instead of <h2> for ## hi)
  • [x] [plugins][section-plugins] (many plugins you can pick and choose from)
  • [x] [compliant][section-syntax] (100% to CommonMark, 100% to GFM with a plugin)

Contents

What is this?

This package is a [React][] component that can be given a string of markdown that it’ll safely render to React elements. You can pass plugins to change how markdown is transformed and pass components that will be used instead of normal HTML elements.

  • to learn markdown, see this [cheatsheet and tutorial][commonmark-help]
  • to try out react-markdown, see [our demo][github-io-react-markdown]

When should I use this?

There are other ways to use markdown in React out there so why use this one? The three main reasons are that they often rely on dangerouslySetInnerHTML, have bugs with how they handle markdown, or don’t let you swap elements for components. react-markdown builds a virtual DOM, so React only replaces what changed, from a syntax tree. That’s supported because we use [unified][github-unified], specifically [remark][github-remark] for markdown and [rehype][github-rehype] for HTML, which are popular tools to transform content with plugins.

This package focusses on making it easy for beginners to safely use markdown in React. When you’re familiar with unified, you can use a modern hooks based alternative [react-remark][github-react-remark] or [rehype-react][github-rehype-react] manually. If you instead want to use JavaScript and JSX inside markdown files, use [MDX][github-mdx].

Install

This package is [ESM only][esm]. In Node.js (version 16+), install with [npm][npm-install]:

npm install react-markdown

In Deno with [esm.sh][esmsh]:

import Markdown from 'https://esm.sh/react-markdown@10'

In browsers with [esm.sh][esmsh]:

<script type="module">
  import Markdown from 'https://esm.sh/react-markdown@10?bundle'
</script>

Use

A basic hello world:

import React from 'react'
import {createRoot} from 'react-dom/client'
import Markdown from 'react-markdown'

const markdown = '# Hi, *Pluto*!'

createRoot(document.body).render(<Markdown>{markdown}</Markdown>)

Show equivalent JSX

<h1>
  Hi, <em>Pluto</em>!
</h1>

Here is an example that shows how to use a plugin ([remark-gfm][github-remark-gfm], which adds support for footnotes, strikethrough, tables, tasklists and URLs directly):

import React from 'react'
import {createRoot} from 'react-dom/client'
import Markdown from 'react-markdown'
import remarkGfm from 'remark-gfm'

const markdown = `Just a link: www.nasa.gov.`

createRoot(document.body).render(
  <Markdown remarkPlugins={[remarkGfm]}>{markdown}</Markdown>
)

Show equivalent JSX




  Just a link: <a href="http://www.nasa.gov">www.nasa.gov</a>.



API

This package exports the identifiers [MarkdownAsync][api-markdown-async], [MarkdownHooks][api-markdown-hooks], and [defaultUrlTransform][api-default-url-transform]. The default export is [Markdown][api-markdown].

It also exports the additional [TypeScript][] types [AllowElement][api-allow-element], [Components][api-components], [ExtraProps][api-extra-props], [HooksOptions][api-hooks-options], [Options][api-options], and [UrlTransform][api-url-transform].

Markdown

Component to render markdown.

This is a synchronous component. When using async plugins, see [MarkdownAsync][api-markdown-async] or [MarkdownHooks][api-markdown-hooks].

Parameters
  • options ([Options][api-options]) — props
Returns

React element (ReactElement).

MarkdownAsync

Component to render markdown with support for async plugins through async/await.

Components returning promises are supported on the server. For async support on the client, see [MarkdownHooks][api-markdown-hooks].

Parameters
  • options ([Options][api-options]) — props
Returns

Promise to a React element (Promise<ReactElement>).

MarkdownHooks

Component to render markdown with support for async plugins through hooks.

This uses useEffect and useState hooks. Hooks run on the client and do not immediately render something. For async support on the server, see [MarkdownAsync][api-markdown-async].

Parameters
  • options ([Options][api-options]) — props
Returns

React node (ReactNode).

defaultUrlTransform(url)

Make a URL safe.

Parameters
  • url (string) — URL
Returns

Safe URL (string).

AllowElement

Filter elements (TypeScript type).

Parameters
  • node ([Element from hast][github-hast-element]) — element to check
  • index (number | undefined) — index of element in parent
  • parent ([Node from hast][github-hast-nodes]) — parent of element
Returns

Whether to allow element (boolean, optional).

Components

Map tag names to components (TypeScript type).

Type
import type {ExtraProps} from 'react-markdown'
import type {ComponentProps, ElementType} from 'react'

type Components = {
  [Key in Extract<ElementType, string>]?: ElementType<ComponentProps<Key> & ExtraProps>
}

ExtraProps

Extra fields we pass to components (TypeScript type).

Fields
  • node ([Element from hast][github-hast-element], optional) — original node

HooksOptions

Configuration for [MarkdownHooks][api-markdown-hooks] (TypeScript type); extends the regular [Options][api-options] with a fallback prop.

Extends

[Options][api-options].

Fields
  • fallback (ReactNode, optional) — content to render while the processor processing the markdown

Options

Configuration (TypeScript type).

Fields
  • allowElement ([AllowElement][api-allow-element], optional) — filter elements; allowedElements / disallowedElements is used first
  • allowedElements (Array<string>, default: all tag names) — tag names to allow; cannot combine w/ disallowedElements
  • children (string, optional) — markdown
  • components ([Components][api-components], optional) — map tag names to components
  • disallowedElements (Array<string>, default: []) — tag names to disallow; cannot combine w/ allowedElements
  • rehypePlugins (Array<Plugin>, optional) — list of [rehype plugins][github-rehype-plugins] to use
  • remarkPlugins (Array<Plugin>, optional) — list of [remark plugins][github-remark-plugins] to use
  • remarkRehypeOptions ([Options from remark-rehype][github-remark-rehype-options], optional) — options to pass through to remark-rehype
  • skipHtml (boolean, default: false) — ignore HTML in markdown completely
  • unwrapDisallowed (boolean, default: false) — extract (unwrap) what’s in disallowed elements; normally when say strong is not allowed, it and it’s children are dropped, with unwrapDisallowed the element itself is replaced by its children
  • urlTransform ([UrlTransform][api-url-transform], default: [defaultUrlTransform][api-default-url-transform]) — change URLs

UrlTransform

Transform URLs (TypeScript type).

Parameters
  • url (string) — URL
  • key (string, example: 'href') — property name
  • node ([Element from hast][github-hast-element]) — element to check
Returns

Transformed URL (string, optional).

Examples

Use a plugin

This example shows how to use a remark plugin. In this case, [remark-gfm][github-remark-gfm], which adds support for strikethrough, tables, tasklists and URLs directly:

import React from 'react'
import {createRoot} from 'react-dom/client'
import Markdown from 'react-markdown'
import remarkGfm from 'remark-gfm'

const markdown = `A paragraph with *emphasis* and **strong importance**.

> A block quote with ~strikethrough~ and a URL: https://reactjs.org.

* Lists
* [ ] todo
* [x] done

A table:

| a | b |
| - | - |
`

createRoot(document.body).render(
  <Markdown remarkPlugins={[remarkGfm]}>{markdown}</Markdown>
)

Show equivalent JSX

<>



    A paragraph with <em>emphasis</em> and <strong>strong importance</strong>.



  <blockquote>



      A block quote with <del>strikethrough</del> and a URL:{' '}
      <a href="https://reactjs.org">https://reactjs.org</a>.



  </blockquote>
  <ul className="contains-task-list">
    <li>Lists</li>
    <li className="task-list-item">
      <input type="checkbox" disabled /> todo
    </li>
    <li className="task-list-item">
      <input type="checkbox" disabled checked /> done
    </li>
  </ul>


A table:


  <table>
    <thead>
      <tr>
        <th>a</th>
        <th>b</th>
      </tr>
    </thead>
  </table>
</>

Use a plugin with options

This example shows how to use a plugin and give it options. To do that, use an array with the plugin at the first place, and the options second. [remark-gfm][github-remark-gfm] has an option to allow only double tildes for strikethrough:

import React from 'react'
import {createRoot} from 'react-dom/client'
import Markdown from 'react-markdown'
import remarkGfm from 'remark-gfm'

const markdown = 'This ~is not~ strikethrough, but ~~this is~~!'

createRoot(document.body).render(
  <Markdown remarkPlugins={[[remarkGfm, {singleTilde: false}]]}>
    {markdown}
  </Markdown>
)

Show equivalent JSX




  This ~is not~ strikethrough, but <del>this is</del>!



Use custom components (syntax highlight)

This example shows how you can overwrite the normal handling of an element by passing a component. In this case, we apply syntax highlighting with the seriously super amazing [react-syntax-highlighter][github-react-syntax-highlighter] by [@conorhastings][github-conorhastings]:

import React from 'react'
import {createRoot} from 'react-dom/client'
import Markdown from 'react-markdown'
import {Prism as SyntaxHighlighter} from 'react-syntax-highlighter'
import {dark} from 'react-syntax-highlighter/dist/esm/styles/prism'

// Did you know you can use tildes instead of backticks for code in markdown? ✨
const markdown = `Here is some JavaScript code:

~~~js
console.log('It works!')
~~~
`

createRoot(document.body).render(
  <Markdown
    children={markdown}
    components={{
      code(props) {
        const {children, className, node, ...rest} = props
        const match = /language-(\w+)/.exec(className || '')
        return match ? (
          <SyntaxHighlighter
            {...rest}
            PreTag="div"
            children={String(children).replace(/\n$/, '')}
            language={match[1]}
            style={dark}
          />
        ) : (
          <code {...rest} className={className}>
            {children}
          </code>
        )
      }
    }}
  />
)

Show equivalent JSX

<>


Here is some JavaScript code:


  <pre>
    <SyntaxHighlighter language="js" style={dark} PreTag="div" children="console.log('It works!')" />
  </pre>
</>

Use remark and rehype plugins (math)

This example shows how a syntax extension (through [remark-math][github-remark-math]) is used to support math in markdown, and a transform plugin ([rehype-katex][github-rehype-katex]) to render that math.

import React from 'react'
import {createRoot} from 'react-dom/client'
import Markdown from 'react-markdown'
import rehypeKatex from 'rehype-katex'
import remarkMath from 'remark-math'
import 'katex/dist/katex.min.css' // `rehype-katex` does not import the CSS for you

const markdown = `The lift coefficient ($C_L$) is a dimensionless coefficient.`

createRoot(document.body).render(
  <Markdown remarkPlugins={[remarkMath]} rehypePlugins={[rehypeKatex]}>
    {markdown}
  </Markdown>
)

Show equivalent JSX

```js

The lift coefficient ( <span className="katex-mathml

Core symbols most depended-on inside this repo

deferPlugin
called by 6
test.jsx
createProcessor
called by 3
lib/index.js
createFile
called by 3
lib/index.js
post
called by 3
lib/index.js
resolve
called by 2
test.jsx
transform
called by 2
lib/index.js
createLoader
called by 1
script/load-jsx.js
p
called by 0
test.jsx

Shape

Function 27
Class 2
Method 2

Languages

TypeScript100%

Modules by API surface

test.jsx19 symbols
lib/index.js8 symbols
script/load-jsx.js4 symbols

Dependencies from manifests, versioned

@testing-library/react16.0.0 · 1×
@types/hast3.0.0 · 1×
@types/mdast4.0.0 · 1×
@types/node22.0.0 · 1×
@types/react19.0.0 · 1×
@types/react-dom19.0.0 · 1×
c810.0.0 · 1×
concat-stream2.0.0 · 1×
devlop1.0.0 · 1×
esbuild0.25.0 · 1×
eslint-plugin-react7.0.0 · 1×
global-jsdom26.0.0 · 1×

For agents

$ claude mcp add react-markdown \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact