β¨ 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-markdown
or
npm install @m2d/react-markdown
or
yarn add @m2d/react-markdown
By 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.current
is 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-markdown
performs 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-beta
charts - 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 β.docx
unified
β 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