@uiw/react-markdown-preview vs react-markdown vs react-markdown-editor-lite
Rendering and Editing Markdown in React Applications
@uiw/react-markdown-previewreact-markdownreact-markdown-editor-liteSimilar Packages:

Rendering and Editing Markdown in React Applications

@uiw/react-markdown-preview, react-markdown, and react-markdown-editor-lite are React-focused libraries for handling Markdown content, but they serve distinct roles. react-markdown is a lightweight, security-first renderer that converts Markdown strings into React elements using a syntax tree. @uiw/react-markdown-preview builds on top of react-markdown to provide a ready-to-use preview component with built-in syntax highlighting and common extensions like tables and task lists. react-markdown-editor-lite is a full-featured WYSIWYG Markdown editor that includes both an editing pane and a live preview, targeting users who need an integrated authoring experience.

Npm Package Weekly Downloads Trend

3 Years

Github Stars Ranking

Stat Detail

Package
Downloads
Stars
Size
Issues
Publish
License
@uiw/react-markdown-preview03443.69 MB396 hours agoMIT
react-markdown015,58752.6 kB3a year agoMIT
react-markdown-editor-lite01,125494 kB542 months agoMIT

Rendering vs Preview vs Editing: Choosing the Right Markdown Tool in React

When working with Markdown in React apps, developers often face a key decision: do you just need to render safe HTML from Markdown, show a polished preview, or provide a full editing experience? The three packages — react-markdown, @uiw/react-markdown-preview, and react-markdown-editor-lite — each solve one of these problems, but with very different trade-offs in scope, security, and bundle impact. Let’s break them down.

📄 Core Purpose: What Each Package Actually Does

react-markdown: Pure, Secure Rendering

This library focuses exclusively on converting Markdown strings into React elements. It uses the remark ecosystem under the hood but avoids dangerouslySetInnerHTML, making it inherently resistant to XSS attacks. You pass it a Markdown string, and it outputs a tree of React components.

import ReactMarkdown from 'react-markdown';

function App() {
  const markdown = '# Hello\nThis is **bold**.';
  return <ReactMarkdown>{markdown}</ReactMarkdown>;
}

It does not include syntax highlighting, table styling, or task list support by default — you add those via plugins or custom components.

@uiw/react-markdown-preview: Batteries-Included Preview

Built directly on react-markdown, this package provides a ready-to-use preview component with sensible defaults for common Markdown extensions. It enables GitHub-flavored Markdown (GFM), adds Prism.js-based syntax highlighting, and styles tables and task lists out of the box.

import MarkdownPreview from '@uiw/react-markdown-preview';

function App() {
  const markdown = '```js\nconsole.log("hello");\n```\n\n- [x] Task done';
  return <MarkdownPreview source={markdown} />;
}

Note the source prop instead of children — this is a small but important API difference from react-markdown.

react-markdown-editor-lite: Full WYSIWYG Editor

This is not just a renderer — it’s a complete Markdown editor with dual panes: one for writing, one for live preview. It includes a toolbar, image upload hooks, and undo/redo functionality. Think of it as a lightweight alternative to Draft.js or TipTap, but Markdown-specific.

import MdEditor from 'react-markdown-editor-lite';
import 'react-markdown-editor-lite/lib/index.css';

function App() {
  const handleEditorChange = ({ text }) => {
    console.log(text);
  };

  return (
    <MdEditor
      value="# Edit me"
      style={{ height: '500px' }}
      onChange={handleEditorChange}
    />
  );
}

You must import its CSS file separately, which is typical for component libraries with complex UI.

🔒 Security Model: How They Handle Untrusted Input

All three packages aim to prevent XSS, but their approaches differ.

react-markdown is the most secure by design. Since it never uses innerHTML, even malicious input like <script>alert(1)</script> is rendered as plain text. You can further lock it down by restricting allowed HTML tags via the allowedElements prop.

// react-markdown: Explicitly block all HTML
<ReactMarkdown allowedElements={[]} unwrapDisallowed={true}>
  {userInput}
</ReactMarkdown>

@uiw/react-markdown-preview inherits this safety because it wraps react-markdown. However, because it enables GFM by default (which includes limited HTML like <br>), you should still treat input cautiously. It doesn’t expose the full react-markdown props by default, so tightening security requires using the components or remarkPlugins props directly.

// @uiw/react-markdown-preview: Disable raw HTML
import gfm from 'remark-gfm';

<MarkdownPreview
  source={userInput}
  remarkPlugins={[[gfm, { singleTilde: false }]]}
  skipHtml={true}
/>

react-markdown-editor-lite assumes the content is being authored by a trusted user (e.g., an admin), so it focuses less on sanitization. While it doesn’t execute scripts during preview, it doesn’t sanitize output by default. If you accept editor output from untrusted users, you must sanitize it server-side or with a library like DOMPurify before storing or re-rendering.

⚙️ Customization: Swapping Renderers and Adding Features

Need to render links with react-router’s <Link>? Or style code blocks differently? Here’s how each package handles customization.

react-markdown gives you full control via the components prop:

import { Link } from 'react-router-dom';

<ReactMarkdown
  components={{
    a: ({ node, ...props }) => <Link to={props.href} {...props} />
  }}
>
  {markdown}
</ReactMarkdown>

@uiw/react-markdown-preview also supports components, but you lose some of its built-in styling if you override elements like code or pre without preserving Prism classes:

<MarkdownPreview
  source={markdown}
  components={{
    code({ node, inline, className, children, ...props }) {
      if (inline) return <code {...props}>{children}</code>;
      return (
        <pre className={className} {...props}>
          <code>{children}</code>
        </pre>
      );
    }
  }}
/>

react-markdown-editor-lite allows preview customization through the view prop, but it’s more limited. You typically replace the entire preview renderer:

<MdEditor
  value={markdown}
  view={{
    menu: true,
    md: true,
    html: true,
    fullScreen: false,
    hideMenu: false
  }}
  // To customize preview, you'd need to fork or use dangerouslySetInnerHTML
/>

For deep preview customization in the editor, you’re better off using react-markdown inside a custom preview pane.

🖼️ Syntax Highlighting: Setup and Control

react-markdown requires manual setup:

import ReactMarkdown from 'react-markdown';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { dark } from 'react-syntax-highlighter/dist/esm/styles/prism';

<ReactMarkdown
  components={{
    code({ node, inline, className, children, ...props }) {
      const match = /language-(\w+)/.exec(className || '');
      return !inline && match ? (
        <SyntaxHighlighter
          style={dark}
          language={match[1]}
          PreTag="div"
          {...props}
        >
          {String(children).replace(/\n$/, '')}
        </SyntaxHighlighter>
      ) : (
        <code className={className} {...props}>
          {children}
        </code>
      );
    }
  }}
>
  {markdown}
</ReactMarkdown>

@uiw/react-markdown-preview includes Prism automatically. Just ensure you import its CSS:

import '@uiw/react-markdown-preview/lib/styles/github.css';

<MarkdownPreview source={markdown} />

react-markdown-editor-lite uses highlight.js by default and bundles its own themes. You can switch themes via props but can’t easily swap the highlighter engine.

<MdEditor
  value={markdown}
  config={{
    view: { menu: true, md: true, html: true },
    imageUrl: '/upload'
  }}
  style={{ height: '400px' }}
/>

🧩 Real-World Decision Guide

Use Case 1: User Comments Section

You’re building a forum where users post Markdown comments. Security and simplicity are key.

  • Best choice: react-markdown
  • Why? Built-in XSS protection, minimal bundle, and you can disable HTML entirely.

Use Case 2: Documentation Viewer

You need to display styled, syntax-highlighted docs (like READMEs) with tables and task lists.

  • Best choice: @uiw/react-markdown-preview
  • Why? Zero-config GFM + syntax highlighting with GitHub-like styling.

Use Case 3: Blog Admin Dashboard

Authors need to write and preview posts in a single interface with image uploads.

  • Best choice: react-markdown-editor-lite
  • Why? Integrated editor, toolbar, and live preview reduce the need to build your own.

🚫 When Not to Use Each

  • Avoid react-markdown-editor-lite for read-only scenarios — it ships editor logic, toolbar assets, and state management you won’t use.
  • Avoid @uiw/react-markdown-preview if you need to deeply customize parsing (e.g., custom directives) — you’ll fight its opinionated defaults.
  • Avoid bare react-markdown if you want syntax highlighting or GFM without wiring up plugins — you’ll spend time reinventing what @uiw provides out of the box.

💡 Final Recommendation

Think about your user’s role:

  • Consumers (reading content)? → @uiw/react-markdown-preview for rich previews, or react-markdown for maximum control.
  • Creators (writing content)? → react-markdown-editor-lite for a complete editing environment.

And always remember: if the Markdown comes from an untrusted source, lean on react-markdown’s security model — never trust client-side sanitization alone.

How to Choose: @uiw/react-markdown-preview vs react-markdown vs react-markdown-editor-lite

  • @uiw/react-markdown-preview:

    Choose @uiw/react-markdown-preview when you need a zero-config Markdown preview component with syntax highlighting, GitHub-flavored Markdown support (tables, task lists), and minimal setup. It’s ideal for documentation viewers, comment previews, or any read-only display where you want rich rendering without building your own pipeline. Avoid it if you require fine-grained control over the parsing or rendering pipeline, as it abstracts away the underlying react-markdown configuration.

  • react-markdown:

    Choose react-markdown when you need maximum control, security, and composability in rendering Markdown. It sanitizes content by default, supports custom components for every node type, and integrates cleanly with remark plugins. This package is best for applications where Markdown is user-provided (e.g., forums, CMS backends) and you must enforce strict XSS protection or customize rendering logic per element type.

  • react-markdown-editor-lite:

    Choose react-markdown-editor-lite when your application requires a full Markdown authoring interface with live preview, toolbar, and image upload support. It’s designed for content creators who need an intuitive editor similar to GitHub’s or Stack Overflow’s. Avoid it if you only need rendering (not editing), as it bundles unnecessary UI and state management overhead for read-only use cases.

README for @uiw/react-markdown-preview

Using my app is also a way to support me:
Scap: Screenshot & Markup Edit Screen Test Deskmark Keyzer Vidwall Hub VidCrop Vidwall Mousio Hint Mousio Musicer Audioer FileSentinel FocusCursor Videoer KeyClicker DayBar Iconed Menuist Paste Quick Quick RSS Web Serve Copybook Generator DevTutor for SwiftUI RegexMate Time Passage Iconize Folder Textsound Saver Create Custom Symbols DevHub Resume Revise Palette Genius Symbol Scribe

React Markdown Preview

Buy me a coffee Follow On X Build and Deploy Downloads Coverage Status npm version npm unpkg Repo Dependents

React component preview markdown text in web browser. The minimal amount of CSS to replicate the GitHub Markdown style. The current document website is converted using this react component.

Features

  • 🌒 Support dark-mode/night-mode. @v4
  • 🙆🏼‍♂️ GitHub style: The markdown content is rendered as close to the way it's rendered on GitHub as possible.
  • 🏋🏾‍♂️ Support GFM (autolink literals, footnotes, strikethrough, tables, tasklists).
  • 🍭 Support automatic code block highlight.
  • 🐝 Support for defining styles via comment.
  • ⛳️ Support for GFM footnotes
  • ⛳️ Support for Github Alert

Quick Start

$ npm install @uiw/react-markdown-preview --save

Usage Example

Open in CodeSandbox

import React from 'react';
import MarkdownPreview from '@uiw/react-markdown-preview';

const source = `
## MarkdownPreview

> todo: React component preview markdown text.
`;

export default function Demo() {
  return (
    <MarkdownPreview source={source} style={{ padding: 16 }} />
  )
}

Disable Header links

import React from 'react';
import MarkdownPreview from '@uiw/react-markdown-preview';

const source = `
## MarkdownPreview

## Header 2

### Header 3
`;

export default function Demo() {
  return (
    <MarkdownPreview
      source={source}
      style={{ padding: 16 }}
      rehypeRewrite={(node, index, parent) => {
        if (node.tagName === "a" && parent && /^h(1|2|3|4|5|6)/.test(parent.tagName)) {
          parent.children = parent.children.slice(1)
        }
      }}
    />
  );
}

highlight line

syntax: ```jsx {1,4-5}

import React from 'react';
import MarkdownPreview from '@uiw/react-markdown-preview';

const source = `
\`\`\`js {2}
function () {
  console.log('hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello')
}
\`\`\`
\`\`\`js {2}
function () {
  console.log('hello ')
}
\`\`\`
`;

export default function Demo() {
  return (
    <MarkdownPreview
      source={source}
      style={{ padding: 16 }}
      rehypeRewrite={(node, index, parent) => {
        if (node.tagName === "a" && parent && /^h(1|2|3|4|5|6)/.test(parent.tagName)) {
          parent.children = parent.children.slice(1)
        }
      }}
    />
  );
}

Show Line Numbers

syntax: ```jsx showLineNumbers {1,4-5}

import React from 'react';
import MarkdownPreview from '@uiw/react-markdown-preview';

const source = `
\`\`\`js showLineNumbers
function () {
  console.log('hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello')
}
\`\`\`
\`\`\`js showLineNumbers {2}
function () {
  console.log('hello ')
}
\`\`\`
`;

export default function Demo() {
  return (
    <MarkdownPreview
      source={source}
      style={{ padding: 16 }}
      rehypeRewrite={(node, index, parent) => {
        if (node.tagName === "a" && parent && /^h(1|2|3|4|5|6)/.test(parent.tagName)) {
          parent.children = parent.children.slice(1)
        }
      }}
    />
  );
}

Code Highlight

import React from 'react';
import MarkdownPreview from '@uiw/react-markdown-preview';

const source = `
\`\`\`js
function () {
  console.log('hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello')
}
\`\`\`
\`\`\`js
function () {
  console.log('hello ')
}
\`\`\`
`;

export default function Demo() {
  return (
    <MarkdownPreview source={source} style={{ padding: 16 }} />
  );
}

Common Code Highlight

Use @uiw/react-markdown-preview/common to keep syntax highlighting enabled with the rehype-prism-plus/common language subset. This is a middle ground between the default all-language build and nohighlight.

import React from 'react';
import MarkdownPreview from '@uiw/react-markdown-preview/common';

const source = `
\`\`\`js
function greet(name) {
  console.log('hello', name);
}
\`\`\`
`;

export default function Demo() {
  return (
    <MarkdownPreview source={source} style={{ padding: 16 }} />
  );
}

Remove Code Highlight

The following example can help you exclude code highlighting code from being included in the bundle. @uiw/react-markdown-preview/nohighlight component does not contain the rehype-prism-plus code highlighting package, showLineNumbers and highlight line functions will no longer work. (#586)

import React from 'react';
import MarkdownPreview from '@uiw/react-markdown-preview/nohighlight';

const source = `
\`\`\`js
function () {
  console.log('hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello hello')
}
\`\`\`
\`\`\`js
function () {
  console.log('hello ')
}
\`\`\`
`;

export default function Demo() {
  return (
    <MarkdownPreview
      source={source}
      style={{ padding: 16 }}
      rehypeRewrite={(node, index, parent) => {
        if (node.tagName === "a" && parent && /^h(1|2|3|4|5|6)/.test(parent.tagName)) {
          parent.children = parent.children.slice(1)
        }
      }}
    />
  );
}

Ignore

Ignore content display via HTML comments, Shown in GitHub readme, excluded in HTML.

import React from 'react';
import MarkdownPreview from '@uiw/react-markdown-preview';

const source = `
<!--rehype:ignore:start-->
Content ignored
<!--rehype:ignore:end-->
Some content is ignored, please check the source code
`;

export default function Demo() {
  return (
    <MarkdownPreview
      source={source}
      style={{ padding: 16 }}
      rehypeRewrite={(node, index, parent) => {
        if (node.tagName === "a" && parent && /^h(1|2|3|4|5|6)/.test(parent.tagName)) {
          parent.children = parent.children.slice(1)
        }
      }}
    />
  );
}
<!--rehype:ignore:start-->Ignored content<!--rehype:ignore:end-->

Support Custom KaTeX Preview

KaTeX is a fast, easy-to-use JavaScript library for TeX math rendering on the web, We perform math rendering through KaTeX.

npm install katex
import React from 'react';
import MarkdownPreview from '@uiw/react-markdown-preview';
import { getCodeString } from 'rehype-rewrite';
import katex from 'katex';
import 'katex/dist/katex.css';

const source = `This is to display the 
\`\$\$\c = \\pm\\sqrt{a^2 + b^2}\$\$\`
 in one line

\`\`\`KaTeX
c = \\pm\\sqrt{a^2 + b^2}
\`\`\`
`;

export default function Demo() {
  const [value, setValue] = React.useState(source);
  return (
    <MarkdownPreview
      source={source}
      style={{ padding: 16 }}
      components={{
        code: ({ children = [], className, ...props }) => {
          if (typeof children === 'string' && /^\$\$(.*)\$\$/.test(children)) {
            const html = katex.renderToString(children.replace(/^\$\$(.*)\$\$/, '$1'), {
              throwOnError: false,
            });
            return <code dangerouslySetInnerHTML={{ __html: html }} style={{ background: 'transparent' }} />;
          }
          const code = props.node && props.node.children ? getCodeString(props.node.children) : children;
          if (
            typeof code === 'string' &&
            typeof className === 'string' &&
            /^language-katex/.test(className.toLocaleLowerCase())
          ) {
            const html = katex.renderToString(code, {
              throwOnError: false,
            });
            return <code style={{ fontSize: '150%' }} dangerouslySetInnerHTML={{ __html: html }} />;
          }
          return <code className={String(className)}>{children}</code>;
        },
      }}
    />
  );
}

Support Custom Mermaid Preview

Using mermaid to generation of diagram and flowchart from text in a similar manner as markdown

Open in CodeSandbox

import React, { useState, useRef, useEffect, Fragment, useCallback } from "react";
import MarkdownPreview from '@uiw/react-markdown-preview';
import { getCodeString } from 'rehype-rewrite';
import mermaid from "mermaid";

const randomid = () => parseInt(String(Math.random() * 1e15), 10).toString(36);
const Code = ({ inline, children = [], className, ...props }) => {
  const demoid = useRef(`dome${randomid()}`);
  const [container, setContainer] = useState(null);
  const isMermaid = className && /^language-mermaid/.test(className.toLocaleLowerCase());
  const code = props.node && props.node.children ? getCodeString(props.node.children) : children[0] || '';

  const reRender = async () => {
    if (container && isMermaid) {
      try {
        const str = await mermaid.render(demoid.current, code);
        container.innerHTML = str.svg;
      } catch (error) {
        container.innerHTML = error;
      }
    }
  }

  useEffect(() => {
    reRender()
  }, [container, isMermaid, code, demoid]);

  const refElement = useCallback((node) => {
    if (node !== null) {
      setContainer(node);
    }
  }, []);

  if (isMermaid) {
    return (
      <Fragment>
        <code id={demoid.current} style={{ display: "none" }} />
        <code ref={refElement} data-name="mermaid" />
      </Fragment>
    );
  }
  return <code>{children}</code>;
};
const source = `The following are some examples of the diagrams, charts and graphs that can be made using Mermaid and the Markdown-inspired text specific to it. 

\`\`\`mermaid
graph TD
A[Hard] -->|Text| B(Round)
B --> C{Decision}
C -->|One| D[Result 1]
C -->|Two| E[Result 2]
\`\`\`

\`\`\`mermaid
sequenceDiagram
Alice->>John: Hello John, how are you?
loop Healthcheck
    John->>John: Fight against hypochondria
end
Note right of John: Rational thoughts!
John-->>Alice: Great!
John->>Bob: How about you?
Bob-->>John: Jolly good!
\`\`\`
`;
// const source = `
// \`\`\`mermaid
// graph TD;
//     A-->B;
//     A-->C;
//     B-->D;
//     C-->D;
// \`\`\`
// `;

export default function Demo() {
  return (
    <MarkdownPreview
      source={source}
      style={{ padding: 16 }}
      components={{
        code: Code
      }}
    />
  );
}

Security

Please note markdown needs to be sanitized if you do not completely trust your authors. Otherwise, your app is vulnerable to XSS. This can be achieved by adding rehype-sanitize as a plugin.

import React from 'react';
import rehypeSanitize from "rehype-sanitize";
import MarkdownPreview from '@uiw/react-markdown-preview';

const source = `
## MarkdownPreview

**Hello world!!!** <IFRAME SRC=\"javascript:javascript:alert(window.origin);\"></IFRAME>

<!-- test --> 123

<!-- test --> 456 <!-- test -->
`;

const rehypePlugins = [rehypeSanitize];
export default function Demo() {
  return (
    <MarkdownPreview source={source} rehypePlugins={rehypePlugins} style={{ padding: 16 }} />
  )
}

Options Props

import { ReactMarkdownProps } from 'react-markdown';
import { RehypeRewriteOptions } from 'rehype-rewrite';

type MarkdownPreviewProps = {
  prefixCls?: string;
  className?: string;
  source?: string;
  disableCopy?: boolean;
  style?: React.CSSProperties;
  pluginsFilter?: (type: 'rehype' | 'remark', plugin: PluggableList) => PluggableList;
  wrapperElement?: React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & {
    'data-color-mode'?: 'light' | 'dark';
  };
  onScroll?: (e: React.UIEvent<HTMLDivElement>) => void;
  onMouseOver?: (e: React.MouseEvent<HTMLDivElement>) => void;
  rehypeRewrite?: RehypeRewriteOptions['rewrite'];
} & ReactMarkdownProps;
  • source (string, default: '')
    Markdown to parse
  • className (string?)
    Wrap the markdown in a div with this class name

This ReactMarkdownProps details. Upgrade react-markdown v9

  • children (string, default: '')
    Markdown to parse
  • className (string?)
    Wrap the markdown in a div with this class name
  • skipHtml (boolean, default: false -> true )
    Ignore HTML in Markdown completely
  • allowElement ((element, index, parent) => boolean?, optional)
    Function called to check if an element is allowed (when truthy) or not. allowedElements / disallowedElements is used first!
  • remarkPlugins (Array.<Plugin>, default: [])
    List of remark plugins to use. See the next section for examples on how to pass options
  • rehypePlugins (Array.<Plugin>, default: [])
    List of rehype plugins to use. See the next section for examples on how to pass options

[!NOTE]

Upgrade react-markdown v8 to v9

Add urlTransform

The transformImageUri and transformLinkUri were removed. Having two functions is a bit much, particularly because there are more URLs you might want to change (or which might be unsafe so we make them safe). And their name and APIs were a bit weird. You can use the new urlTransform prop instead to change all your URLs.

Remove linkTarget

The linkTarget option was removed; you should likely not set targets. If you want to, use rehype-external-links.

Remove includeElementIndex

The includeElementIndex option was removed, so index is never passed to components. Write a plugin to pass index:

Show example of plugin
import {visit} from 'unist-util-visit'

function rehypePluginAddingIndex() {
  /**
   * @param {import('hast').Root} tree
   * @returns {undefined}
   */
  return function (tree) {
    visit(tree, function (node, index) {
      if (node.type === 'element' && typeof index === 'number') {
        node.properties.index = index
      }
    })
  }
}

Remove rawSourcePos

The rawSourcePos option was removed, so sourcePos is never passed to components. All components are passed node, so you can get node.position from them.

Remove sourcePos

The sourcePos option was removed, so data-sourcepos is never passed to elements. Write a plugin to pass index:

Show example of plugin
import {stringifyPosition} from 'unist-util-stringify-position'
import {visit} from 'unist-util-visit'

function rehypePluginAddingIndex() {
  /**
   * @param {import('hast').Root} tree
   * @returns {undefined}
   */
  return function (tree) {
    visit(tree, function (node) {
      if (node.type === 'element') {
        node.properties.dataSourcepos = stringifyPosition(node.position)
      }
    })
  }
}

Remove extra props passed to certain components

When overwriting components, these props are no longer passed:

  • inline on code — create a plugin or use pre for the block
  • level on h1, h2, h3, h4, h5, h6 — check node.tagName instead
  • checked on li — check task-list-item class or check props.children
  • index on li — create a plugin
  • ordered on li — create a plugin or check the parent
  • depth on ol, ul — create a plugin
  • ordered on ol, ul — check node.tagName instead
  • isHeader on td, th — check node.tagName instead
  • isHeader on tr — create a plugin or check children

Markdown Features

Supports for CSS Style

Use HTML comments <!--rehype:xxx--> to let Markdown support style customization.

## Title
<!--rehype:style=display: flex; height: 230px; align-items: center; justify-content: center; font-size: 38px;-->

Markdown Supports **Style**<!--rehype:style=color: red;-->

Support for GFM footnotes

Here is a simple footnote[^1]. With some additional text after it.

[^1]: My reference.

Ignore content display

# Hello World

<!--rehype:ignore:start-->Hello World<!--rehype:ignore:end-->

Good!

Output:

<h1>Hello World</h1>

<p>Good!</p>

Support for Github Alerts

import React from 'react';
import MarkdownPreview from '@uiw/react-markdown-preview';

const source = `> 
> 
> [!NOTE]
> Useful information that users should know, even when skimming content.

> [!TIP]
> Helpful advice for doing things better or more easily.

> [!IMPORTANT]
> Key information users need to know to achieve their goal.

> [!WARNING]
> Urgent info that needs immediate user attention to avoid problems.

> [!CAUTION]
> Advises about risks or negative outcomes of certain actions.


`;

export default function Demo() {
  return (
    <MarkdownPreview source={source} style={{ padding: 16 }} />
  )
}

Support dark-mode/night-mode

By default, the dark-mode is automatically switched according to the system. If you need to switch manually, just set the data-color-mode="dark" parameter for body.

<html data-color-mode="dark">
document.documentElement.setAttribute('data-color-mode', 'dark')
document.documentElement.setAttribute('data-color-mode', 'light')

Inherit custom color variables by adding .wmde-markdown-var selector.

const Demo = () => {
  return (
    <div>
      <div className="wmde-markdown-var"> </div>
      <MarkdownPreview source="Hello World!" />
    </div>
  )
}

Set the light theme.

<MarkdownPreview
  source="Hello World!"
  wrapperElement={{
+    "data-color-mode": "light"
  }}
/>

Development

Runs the project in development mode.

# Step 1, run first,
# listen to the component compile and output the .js file
# listen for compilation output type .d.ts file
# listen to the component compile and output the .css file
npm run start
# Step 2, development mode, listen to compile preview website instance
npm run doc

Builds the app for production to the build folder.

npm run build

The build is minified and the filenames include the hashes. Your app is ready to be deployed!

Alternatives

If you need more features-rich Markdown Editor, you can use @uiwjs/react-markdown-editor

Contributors

As always, thanks to our amazing contributors!

Made with action-contributors.

License

Licensed under the MIT License.