Important
Active development and maintenance of @m2d/react-markdown has moved to the unified md2docx monorepo.
- π Monorepo: github.com/md2docx/md2docx
- π Package Source:
packages/react-markdown - π Documentation: md2docx.js.org/docs/react-markdown
- π¬ Issues & Pull Requests: Please submit all new issues, feedback, and PRs in the md2docx issue tracker.
This standalone repository is now archived and retained for historical reference only. Releases and npm updates continue from the monorepo.
β¨ A modern, SSR-compatible Markdown renderer for React with full MDAST/HAST access β built for customization, performance, and document generation - docx/pdf.
@m2d/react-markdown goes beyond traditional React Markdown libraries by focusing on:
- β Server-side rendering (SSR) without hooks
- β Full JSX children support (not just strings)
- β Access to raw MDAST & HAST trees
- β
Drop-in plugin support via Unified (
remark,rehype, etc.) - β Custom component overrides per tag
- β
Integration with tools like
mdast2docx
Compared to react-markdown, this library offers:
| Feature | @m2d/react-markdown β
|
react-markdown β |
|---|---|---|
| Full JSX support (not just strings) | β | β |
| SSR-safe (no hooks) | β | β |
| Client Side component with memoization | β | β |
MDAST + HAST access via astRef |
β | β |
| Component-level overrides | β | β |
| Unified plugin support | β | β |
| Tiny bundle (minzipped) | ~35 kB | ~45 kB |
| Built-in DOCX-friendly AST output | β | β |
pnpm add @m2d/react-markdownor
npm install @m2d/react-markdownor
yarn add @m2d/react-markdownBy default, this package is SSR-safe and has no client-specific hooks.
import { Md } from "@m2d/react-markdown";import { Md } from "@m2d/react-markdown/client";This version supports client-side behavior with memoization and dynamic JSX rendering.
import { Md } from "@m2d/react-markdown/client";
import { toDocx } from "mdast2docx";
import { useRef } from "react";
const astRef = useRef([]);
export default function Page() {
return (
<>
<Md astRef={astRef}>{`# Hello\n\nThis is **Markdown**.`}</Md>
<button
onClick={() => {
const doc = toDocx(astRef.current[0].mdast);
// Save or download doc
}}>
Export to DOCX
</button>
</>
);
}Note for Server Component use you can replace useRef with custom ref object
const astRef = {current: undefined} as AstRef
Unlike most markdown renderers, @m2d/react-markdown supports arbitrary JSX as children:
import { Mdx } from "@m2d/react-markdown/server";
// ...
<Mdx>
<article>{"# Markdown Heading\n\nSome **rich** content."}</article>
</Mdx>;
astRef.currentis an array β one per Markdown string β each with{ mdast, hast }. The default<Md>export accepts only string children for better optimization.
import { Md } from "@m2d/react-markdown";
import { Unwrap, Omit } from "@m2d/react-markdown/server";
<Md
components={{
em: Unwrap,
blockquote: Omit,
code: props => <CodeBlock {...props} />,
}}>
{`*em is unwrapped*\n\n> blockquote is removed`}
</Md>;Use the built-in helpers:
Unwrapβ renders only childrenOmitβ removes element and content entirelyCodeBlock- it is your custom component
Use any remark or rehype plugin:
<Md remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeSlug, rehypeAutolinkHeadings]}>
{markdown}
</Md>type astRef = {
current: { mdast: Root; hast: HastRoot }[];
};Useful for:
- π DOCX export (
mdast2docx) - π§ͺ AST testing or analysis
- π οΈ Custom tree manipulation
TL;DR:
@m2d/react-markdownperforms competitively withreact-markdown, especially on medium and large documents.
Benchmarks include:
- Multiple markdown fixture types (short, long, complex, deeply nested)
- Plugin configurations like
remark-gfm,remark-math,rehype-raw - Visual comparisons using interactive Mermaid
xychart-betacharts - Ops/sec, Β±%, and future memory profiling
We're proposing a major change to the internal astRef structure to better support MDX-style custom components and rendering flexibility:
Key goals:
- Allow
<Md>to embed child components like JSX/MDX - Simplify recursive rendering model
- Improve performance and reduce abstraction overhead
- π Merge JSX +
<Md>segments into unified AST - π§ͺ Structural test utilities
- π§βπ« Next.js + DOCX example
mdast2docxβ Convert MDAST β.docxunifiedβ Syntax tree ecosystemreact-markdownβ Popular alternative (less customizable)
We are deeply grateful to the open-source community whose work made this project possible.
- π± react-markdown β For pioneering a React-based Markdown renderer. This library builds on its ideas while extending flexibility and SSR-readiness.
- π unified β The brilliant engine powering our markdown-to-AST transformations.
- β¨ remark and rehype β For their modular ecosystems that make parsing and rendering delightful.
- π§Ύ mdast2docx β Our sister project that inspired the MDAST-first architecture of this library.
π To the maintainers, contributors, and communities behind these projects β thank you for your generosity, vision, and dedication to making the web better for everyone.
Licensed under the MPL-2.0.
π‘ Want to support this project? Sponsor or check out our courses!
Built with β€οΈ by Mayank Kumar Chaudhari
