Package Exports
- mdx-render
 - mdx-render/client
 - mdx-render/dist/client
 - mdx-render/dist/server
 - mdx-render/dist/server/omit
 - mdx-render/dist/server/unwrap
 - mdx-render/dist/test-utils
 - mdx-render/dist/utils
 - mdx-render/omit
 - mdx-render/server
 - mdx-render/test-utils
 - mdx-render/unwrap
 - mdx-render/utils
 
Readme
MDX Renderer [@m2d/react-markdown] 
โจ A modern, SSR-compatible Markdown renderer for React with full MDAST/HAST access โ built for customization, performance, and document generation - docx/pdf.
๐ฅ Why @m2d/react-markdown?
@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 | โ | โ | 
๐ฆ Installation
pnpm add @m2d/react-markdownor
npm install @m2d/react-markdownor
yarn add @m2d/react-markdown๐ Server vs Client
By default, this package is SSR-safe and has no client-specific hooks.
โ Server (default):
import { Md } from "@m2d/react-markdown";๐ Client (for dynamic reactivity/memoization):
import { Md } from "@m2d/react-markdown/client";This version supports client-side behavior with memoization and dynamic JSX rendering.
โก Example: Rendering + Exporting DOCX
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
๐ง JSX-Aware Parsing
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.
๐จ Component Overrides
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
๐ Plugin Support (Unified)
Use any remark or rehype plugin:
<Md remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeSlug, rehypeAutolinkHeadings]}>
  {markdown}
</Md>๐ Accessing MDAST + HAST
type astRef = {
  current: { mdast: Root; hast: HastRoot }[];
};Useful for:
- ๐ DOCX export (
mdast2docx) - ๐งช AST testing or analysis
 - ๐ ๏ธ Custom tree manipulation
 
๐ Performance
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
 
๐ฌ Upcoming Changes โ Seeking Feedback
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
 
๐งญ Roadmap
-  ๐ Merge JSX + 
<Md>segments into unified AST - ๐งช Structural test utilities
 - ๐งโ๐ซ Next.js + DOCX example
 
๐ Related Projects
mdast2docxโ Convert MDAST โ.docxunifiedโ Syntax tree ecosystemreact-markdownโ Popular alternative (less customizable)
๐ Acknowledgements
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.
๐ License
Licensed under the MPL-2.0.
๐ก Want to support this project? Sponsor or check out our courses!
Built with โค๏ธ by Mayank Kumar Chaudhari