Package Exports
- mdx-renderer
- mdx-renderer/dist/server
- mdx-renderer/dist/server/omit
- mdx-renderer/dist/server/unwrap
- mdx-renderer/dist/test-utils
- mdx-renderer/omit
- mdx-renderer/server
- mdx-renderer/test-utils
- mdx-renderer/unwrap
Readme
MDX Renderer [@m2d/react-markdown] 
โจ A modern, JSX-compatible, SSR-ready Markdown renderer for React โ with full access to MDAST & HAST trees for tools like
mdast2docx
.
๐ฅ Why mdx-render?
mdx-render
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
๐ Installation
pnpm add @m2d/react-markdown
or
npm install @m2d/react-markdown
or
yarn add @m2d/react-markdown
โก Quick Example
import { Md } from "mdx-render";
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);
// Export DOCX, or save
}}>
Export to DOCX
</button>
</>
);
}
๐ง JSX-Aware Parsing
Unlike other libraries, this renderer supports JSX as children, which means you can nest Markdown inside arbitrary components:
<Md>
<section>{`# Title\n\nContent.`}</section>
</Md>
Note:
astRef.current
is an array โ one entry per Markdown segment. Each entry contains{ mdast, hast }
for fine-grained control.
โจ Component Overrides
Override default HTML rendering with your own components:
<Md
components={{
code: (props) => <CodeWithHighlights {...props} />
em: Unwrap, // Renders <em> content without tags
blockquote: Omit, // Removes <blockquote> completely
}}>
{`*This will be unwrapped*\n\n> This will be removed!`}
</Md>
Use the built-in helpers:
Unwrap
โ renders children, ignores tag & props.Omit
โ removes the element and its content entirely.
๐งฉ Plugin Support
Use any remark
or rehype
plugins with full flexibility:
<Md remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeSlug, rehypeAutolinkHeadings]}>
{markdown}
</Md>
๐ฆ astRef: MDAST + HAST Access
type astRef = {
current: { mdast: Root; hast: HastRoot }[];
};
Each markdown block is processed independently to allow full JSX flexibility.
You can access all parsed trees via astRef.current
, ideal for:
- DOCX/PDF generation (
mdast2docx
) - Markdown linting or analytics
- AST-aware transformations
๐งญ Roadmap
- ๐ Merge surrounding JSX +
<Md>
blocks into unified MDAST/HAST - ๐งช Add test utilities for structural validation
- ๐ Provide Next.js examples with DOCX export
๐ Related Projects
- mdast2docx โ Convert MDAST to Word (.docx)
- unifiedjs โ Syntax tree processing toolkit
- react-markdown โ A simpler but less flexible Markdown renderer
License
This library is licensed under the MPL-2.0 open-source license.
Please enroll in our courses or sponsor our work.
with ๐ by Mayank Kumar Chaudhari