mdx-renderer
v0.1.1
Published
A modern, SSR-friendly React Markdown renderer that preserves the MDAST tree for reuse (e.g., mdast2docx), supports full JSX children, unified plugins, and component overrides.
Maintainers
Keywords
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-markdownor
npm install @m2d/react-markdownor
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.currentis 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
- [x] 📚 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.
