API reference
The complete public API surface of
@rho/md— build-time exports, runtime exports, helpers, types.
Overview
import {
// === Build-time: Remark plugins ===
remarkPlugins, // array (collection of 7 plugins)
remarkCallout,
remarkLayout,
remarkAnnotate,
remarkTabs,
remarkStepper,
remarkTimeline,
remarkModal,
// === Build-time: Inner processor (nested DSL) ===
registerInnerPlugin,
registerAllInnerPlugins,
parseInner,
// === Runtime: Hydration ===
hydrateAll,
renderInteractBlocks,
renderTabsBlocks,
renderStepperBlocks,
renderModalBlocks,
// === Highlight.js / lowlight grammar ===
stlLanguage,
} from '@rho/md';
// === CSS ===
import '@rho/md/css';
Build-time API
remarkPlugins
Type: Array<RemarkPlugin>
An array of 7 Rho remark plugins — easiest to register all at once:
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import { remarkPlugins } from '@rho/md';
const processor = unified().use(remarkParse);
remarkPlugins.forEach((p) => processor.use(p));
Equivalent to:
processor
.use(remarkCallout)
.use(remarkLayout)
.use(remarkAnnotate)
.use(remarkTabs)
.use(remarkStepper)
.use(remarkTimeline)
.use(remarkModal);
remarkCallout / remarkLayout / remarkAnnotate / remarkTabs / remarkStepper / remarkTimeline / remarkModal
Type: RemarkPlugin
Reference each remark plugin individually. Each handles one DSL:
| Plugin | DSL | Trigger |
|---|---|---|
remarkCallout |
Callout | > [!INFO] blockquote |
remarkLayout |
Layout | ```layout grid cols=N fenced block |
remarkAnnotate |
Annotate | ```annotate fenced block |
remarkTabs |
Tabs | ```tabs fenced block |
remarkStepper |
Stepper | ```stepper fenced block |
remarkTimeline |
Timeline | ```timeline fenced block |
remarkModal |
Modal | ```modal fenced block |
Interact / Vega-Lite / SVG / Computed / Timer aren't in the remark plugin list — they're handled at hydration (the fenced
```interactblock emits a marker class at build-time; runtime takes over).
See Remark plugins.
Build-time: Inner processor
registerInnerPlugin(plugin)
Type: (plugin: RemarkPlugin) => void
Register a remark plugin with the inner processor — it will be invoked when parsing nested DSLs.
import { registerInnerPlugin, remarkCallout } from '@rho/md';
registerInnerPlugin(remarkCallout);
→ After this, > [!INFO] inside containers (layout / tabs / stepper / etc.) is recognized as a callout.
registerAllInnerPlugins()
Type: () => void
Register all 7 plugins at once. Most common:
import { registerAllInnerPlugins } from '@rho/md';
registerAllInnerPlugins();
Almost always called when integrating @rho/md — unless you explicitly know you won't use nested DSLs.
parseInner(content, options?)
Type: (content: string, options?: ParseInnerOptions) => string
Advanced API — manually call the inner processor on a chunk of nested content. Normal integration doesn't need it.
See Inner processor.
Runtime: Hydration
hydrateAll(container)
Type: (container: HTMLElement) => void
Scans the container for all Rho marker classes; turns static HTML into interactive components. The most-used hydration API:
import { hydrateAll } from '@rho/md';
const container = document.getElementById('root');
container.innerHTML = await renderRho(markdownSource);
hydrateAll(container);
Idempotent — calling multiple times only hydrates once (each block is marked, subsequent calls skip it).
Equivalent to:
renderInteractBlocks(container);
renderTabsBlocks(container);
renderStepperBlocks(container);
renderModalBlocks(container);
renderInteractBlocks(container)
Type: (container: HTMLElement) => void
Hydrate only interact blocks (slider / input / select / toggle / button / template / computed / timer / svg / vega-lite).
Useful for fine-grained hydration timing — e.g., lazy-loading expensive charts:
container.innerHTML = html;
renderTabsBlocks(container); // Hydrate static structure immediately
// ... when user scrolls to chart ...
renderInteractBlocks(container);
renderTabsBlocks(container) / renderStepperBlocks(container) / renderModalBlocks(container)
Same signature. Each only hydrates its corresponding container type.
Layout / Callout / Annotate / Timeline are purely static — no hydration needed; HTML is final.
See Hydration utilities.
Highlight.js / lowlight grammar
stlLanguage
Type: (hljs: HLJSApi) => Language
The STL language grammar — for highlight.js or lowlight:
highlight.js
import hljs from 'highlight.js';
import { stlLanguage } from '@rho/md';
hljs.registerLanguage('stl', stlLanguage);
// After this, ```stl code blocks get 6-color highlighting automatically
lowlight (server-side / build-time)
import { common } from 'lowlight';
import { stlLanguage } from '@rho/md';
import rehypeHighlight from 'rehype-highlight';
unified()
// ... markdown pipeline ...
.use(rehypeHighlight, {
plainText: ['mermaid', 'vega-lite', 'vega', 'interact', 'tabs', 'stepper', 'timeline', 'modal', 'layout', 'annotate'],
languages: { ...common, stl: stlLanguage },
});
The plainText: [...] array is important — tells rehype-highlight not to colorize Rho's fenced block lang labels (avoids double processing).
See STL syntax highlighting (writer side).
CSS
import '@rho/md/css'
Imports Rho's built-in CSS. Includes:
- All DSL styles (callout / layout / tabs / stepper / etc.)
- CSS variables for theming
.markdown-bodycontainer class (GitHub-compatible convention)- Light + dark theme support
import '@rho/md/css';
Or:
<link rel="stylesheet" href="path/to/@rho/md/css/stl-md.css">
CSS variables (theming)
.markdown-body {
--bg-color: #ffffff;
--text-color: #1a1a2e;
--code-bg: #f8f8f8;
--border-color: #e5e7eb;
--accent-blue: #2563eb;
--accent-red: #dc2626;
--accent-green: #16a34a;
--accent-yellow: #ca8a04;
--accent-purple: #9333ea;
--accent-gray: #6b7280;
}
.markdown-body[data-theme="dark"] {
--bg-color: #0f1115;
--text-color: #e8ecf1;
/* ... */
}
See CSS theming.
TypeScript types
Public types
import type {
// Plugin types
RemarkPlugin, // Standard unified plugin signature
ProcessorOptions, // Integration-layer options
// Hydration types
HydrationOptions, // Optional config for hydrate calls
HydrationResult, // Hydrate return info
// Inner processor
InnerPluginOptions,
} from '@rho/md';
Custom hydrate hooks
import type { HydrationOptions } from '@rho/md';
const options: HydrationOptions = {
onBlockHydrated: (block, type) => {
console.log(`Hydrated ${type} block`, block);
},
errorBoundary: (block, error) => {
console.error('Hydration failed:', error);
block.innerHTML = '<p>Render error</p>';
},
};
hydrateAll(container, options);
Complete integration reference
import { unified } from 'unified';
import remarkParse from 'remark-parse';
import remarkGfm from 'remark-gfm';
import remarkRehype from 'remark-rehype';
import rehypeStringify from 'rehype-stringify';
import rehypeHighlight from 'rehype-highlight';
import { common } from 'lowlight';
import {
registerAllInnerPlugins,
remarkPlugins,
hydrateAll,
stlLanguage,
} from '@rho/md';
import '@rho/md/css';
// === Build-time setup ===
registerAllInnerPlugins();
const processor = unified()
.use(remarkParse)
.use(remarkGfm);
remarkPlugins.forEach((p) => processor.use(p));
processor
.use(remarkRehype, { allowDangerousHtml: true })
.use(rehypeHighlight, {
plainText: ['interact', 'tabs', 'stepper', 'timeline', 'modal', 'layout', 'annotate'],
languages: { ...common, stl: stlLanguage },
})
.use(rehypeStringify, { allowDangerousHtml: true });
// === Render ===
async function renderRho(markdown: string): Promise<string> {
const result = await processor.process(markdown);
return String(result);
}
// === Browser hydration ===
function mount(container: HTMLElement, html: string) {
container.innerHTML = html;
hydrateAll(container);
}
// === Usage ===
const html = await renderRho('# Hello\n\n> [!INFO]\n> Test');
mount(document.getElementById('root')!, html);
Non-public / internal API
⚠️ The following are not public API — don't depend on them:
- Anything named
_internal* - Deep imports inside
dist/(e.g.,@rho/md/dist/internal/foo) - Methods not documented on this page
The public stable API is only what's listed above.
See also
- Quick start — 5-minute integration
- Remark plugins — build-time plugin details
- Hydration utilities — runtime hydration details
- CSS theming — style customization
- Inner processor — nested DSL mechanism