Skip to content

Repository files navigation

react-render-to-markdown

npm versionlicense

Render React components to Markdown strings — like renderToString in react-dom, but outputs Markdown instead of HTML.

Built on top of react-reconciler, this library creates a custom React renderer that traverses the React element tree and produces well-formatted Markdown. It follows SSR-like behavior: useEffect, useLayoutEffect, and useInsertionEffect are suppressed (as no-ops), while useState, useMemo, useRef, useContext, and other synchronous hooks work as expected.

Installation

The major version of react-render-to-markdown follows the React version. Install the one that matches your project:

# React 19
npm install react-render-to-markdown@19
# React 18
npm install react-render-to-markdown@18

Quick Start

import{renderToMarkdownString}from'react-render-to-markdown';constmarkdown=awaitrenderToMarkdownString(<h1>Hello, World!</h1>);console.log(markdown);// # Hello, World!

Usage

Basic HTML Elements

import{renderToMarkdownString}from'react-render-to-markdown';awaitrenderToMarkdownString(<div><strong>foo</strong><span>bar</span></div>,);// Output: '**foo**bar'

React Components & Hooks

Synchronous hooks (useState, useMemo, useRef, useContext, etc.) work as expected. Client-side effects (useEffect, useLayoutEffect) are automatically suppressed:

import{createContext,useContext,useMemo,useState}from'react';import{renderToMarkdownString}from'react-render-to-markdown';constThemeContext=createContext('light');constArticle=()=>{const[count]=useState(42);consttheme=useContext(ThemeContext);constdoubled=useMemo(()=>count*2,[count]);return(<><h1>Hello World</h1><p>Count: {count}, Doubled: {doubled}, Theme: {theme}</p></>);};awaitrenderToMarkdownString(<ThemeContext.Providervalue="dark"><Article/></ThemeContext.Provider>,);// Output:// # Hello World//// Count: 42, Doubled: 84, Theme: dark

Code Blocks

Fenced code blocks with language and title support:

awaitrenderToMarkdownString(<predata-lang="ts"data-title="rspress.config.ts"><code>{'const a = 1;\n'}</code></pre>,);// Output:// ```ts title=rspress.config.ts// const a = 1;// ```

For languages that may contain triple backticks (like markdown, mdx, md), four backticks (``````) are automatically used as delimiters.

Supported Elements

HTML ElementMarkdown Output
<h1><h6>####### headings
<p>Paragraph with trailing newlines
<strong>, <b>**bold**
<em>, <i>*italic*
<code>`inline code`
<pre> + <code>Fenced code block (```)
<a href="">[text](url)
<img>![alt](src)
<ul>, <ol>, <li>Unordered / ordered lists
<blockquote>> blockquote
<br>Line break
<hr>--- horizontal rule
<style>Ignored
<table>, <thead>, <tbody>, <tr>, <th>, <td>GFM table

Any unrecognized elements (e.g. <div>, <span>, <section>) render their children as-is, acting as transparent wrappers.

How It Works

  1. Custom React Reconciler — Uses react-reconciler to build a lightweight tree of MarkdownNode objects from your React element tree.
  2. SSR-like Hook Behavior — Client-side effects (useEffect, useLayoutEffect, useInsertionEffect) are intercepted and turned into no-ops, matching React's Fizz server renderer behavior. This ensures browser-only code (e.g. document, window) in effects never runs.
  3. Tree-to-Markdown Serialization — The MarkdownNode tree is serialized to a Markdown string via a recursive toMarkdown function.

Requirements

{
"react": ">=19.0.0",
"react-reconciler": "^0.33.0"
}

Note: React 19 or above is required. The effect-interception mechanism relies on React 19's internal hooks dispatcher (__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE.H).

Used By

  • Rspress SSG-MD — Rspress uses this library to power its SSG-MD (Static Site Generation to Markdown) feature. SSG-MD renders documentation pages as Markdown files instead of HTML, generating llms.txt and llms-full.txt for Generative Engine Optimization (GEO), enabling better accessibility for AI agents and large language models.

License

MIT

About

SSR (jsx-to-markdown) render React to Markdown strings — like `renderToString` in react-dom, but outputs Markdown instead of HTML

Topics

Resources

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages