Big News: Socket raises $60M Series C at a $1B valuation to secure software supply chains for AI-driven development.Announcement
Sign In

react-render-to-markdown

Package Overview
Dependencies
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-render-to-markdown

render React components to Markdown strings for SSG-MD

latest
Source
npmnpm
Version
19.1.0
Version published
Weekly downloads
29K
8.45%
Maintainers
1
Weekly downloads
 
Created
Source

react-render-to-markdown

npm version license

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';

const markdown = await renderToMarkdownString(<h1>Hello, World!</h1>);
console.log(markdown); // # Hello, World!

Usage

Basic HTML Elements

import { renderToMarkdownString } from 'react-render-to-markdown';

await renderToMarkdownString(
  <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';

const ThemeContext = createContext('light');

const Article = () => {
  const [count] = useState(42);
  const theme = useContext(ThemeContext);
  const doubled = useMemo(() => count * 2, [count]);

  return (
    <>
      <h1>Hello World</h1>
      <p>Count: {count}, Doubled: {doubled}, Theme: {theme}</p>
    </>
  );
};

await renderToMarkdownString(
  <ThemeContext.Provider value="dark">
    <Article />
  </ThemeContext.Provider>,
);
// Output:
// # Hello World
//
// Count: 42, Doubled: 84, Theme: dark

Code Blocks

Fenced code blocks with language and title support:

await renderToMarkdownString(
  <pre data-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

  • Custom React Reconciler — Uses react-reconciler to build a lightweight tree of MarkdownNode objects from your React element tree.
  • 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.
  • 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

Keywords

react

FAQs

Package last updated on 22 May 2026

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts