namespace
markdown
namespace markdown
Markdown related APIs.
Parses and renders markdown with four output modes:
html()— render to an HTML stringansi()— render to an ANSI-colored string for terminalsrender()— render with custom callbacks for each elementreact()— parse to React-compatible JSX elements
Supports GFM extensions (tables, strikethrough, task lists, autolinks) and component overrides to replace default HTML tags with custom components.
// Render markdown to HTML
const html = Bun.markdown.html("# Hello **world**");
// "<h1>Hello <strong>world</strong></h1>\n"
// Render with custom callbacks
const ansi = Bun.markdown.render("# Hello **world**", {
heading: (children, { level }) => `\x1b[1m${children}\x1b[0m\n`,
strong: (children) => `\x1b[1m${children}\x1b[22m`,
paragraph: (children) => children + "\n",
});
// Render as a React component
function Markdown({ text }: { text: string }) {
return Bun.markdown.react(text);
}
// With component overrides
const element = Bun.markdown.react("# Hello", { h1: MyHeadingComponent });interface AnsiTheme
Theme for ANSI terminal rendering.
- colors?: boolean
Emit ANSI color + styling escape sequences. When
false, the renderer falls back to plain ASCII chrome (no box drawing, no emoji, no escape codes). - columns?: number
Line width used for word-wrapping paragraphs and headings and for the horizontal rule. Pass
0to disable wrapping. - hyperlinks?: boolean
Emit OSC 8 hyperlinks (clickable links in modern terminals). When
false, links render astext (url). - kittyGraphics?: boolean
Inline images using the Kitty Graphics Protocol when the
srcresolves to a local file on disk. Falls through to the text alt for remote URLs. Supported by Kitty, WezTerm, and Ghostty. - light?: boolean
True when the terminal background is light. Affects the color palette chosen for inline code backgrounds. Defaults to detecting from the
COLORFGBGenvironment variable.
interface ChildrenProps
interface CodeBlockProps
interface ComponentOverrides
Component overrides for
react().Replace default HTML tags with custom React components. Each override receives the same props the default element would get.
function Code({ language, children }: { language?: string; children: React.ReactNode }) { return <pre data-language={language}><code>{children}</code></pre>; } Bun.markdown.react(text, { pre: Code });interface HeadingProps
interface ImageProps
interface ListItemProps
interface Options
Options for configuring the markdown parser.
By default, GFM extensions (tables, strikethrough, task lists) are enabled.
- autolinks?: boolean | { email: boolean; url: boolean; www: boolean }
Enable autolinks. Pass
trueto enable all autolink types (URL, WWW, email), or an object to enable individually.// Enable all autolinks { autolinks: true } // Enable only URL and email autolinks { autolinks: { url: true, email: true } } - headings?: boolean | { autolink: boolean; ids: boolean }
Configure heading IDs and autolink headings. Pass
trueto enable both heading IDs and autolink headings, or an object to configure individually.// Enable both heading IDs and autolink headings { headings: true } // Enable only heading IDs { headings: { ids: true } } - tagFilter?: boolean
Enable the GFM tag filter, which replaces
<with<for disallowed HTML tags (e.g.<script>,<style>,<iframe>). Default:false. - underline?: boolean
Enable underline syntax (
__text__renders as<u>instead of<strong>). Default:false.
interface OrderedListProps
interface ReactOptions
Options for
react()— parser options and element symbol configuration.- autolinks?: boolean | { email: boolean; url: boolean; www: boolean }
Enable autolinks. Pass
trueto enable all autolink types (URL, WWW, email), or an object to enable individually.// Enable all autolinks { autolinks: true } // Enable only URL and email autolinks { autolinks: { url: true, email: true } } - headings?: boolean | { autolink: boolean; ids: boolean }
Configure heading IDs and autolink headings. Pass
trueto enable both heading IDs and autolink headings, or an object to configure individually.// Enable both heading IDs and autolink headings { headings: true } // Enable only heading IDs { headings: { ids: true } } - reactVersion?: 18 | 19
Which
$$typeofsymbol to use on the generated elements.19(default):Symbol.for('react.transitional.element')18:Symbol.for('react.element')— use this for React 18 and older
- tagFilter?: boolean
Enable the GFM tag filter, which replaces
<with<for disallowed HTML tags (e.g.<script>,<style>,<iframe>). Default:false. - underline?: boolean
Enable underline syntax (
__text__renders as<u>instead of<strong>). Default:false.
interface RenderCallbacks
Callbacks for
render(). Each callback receives the accumulated children as a string and optional metadata, and returns a string.Return
nullorundefinedto omit the element from the output. If no callback is registered for an element, its children pass through unchanged.- code?: (children: string, meta?: CodeBlockMeta) => undefined | null | string
Code block.
meta.languageis the info-string (e.g."js"). Only passed for fenced code blocks with a language. - heading?: (children: string, meta: HeadingMeta) => undefined | null | string
Heading (level 1–6).
idis set whenheadings: { ids: true }is enabled. - listItem?: (children: string, meta: ListItemMeta) => undefined | null | string
List item.
metaalways includes{index, depth, ordered}.meta.startis set for ordered lists;meta.checkedis set for task list items.
- type Component<P = {}> = string | (props: P) => any | new (props: P) => any
A component that accepts props
P: a function, class, or HTML tag name. - input: string | ArrayBufferLike | TypedArray<ArrayBufferLike> | DataView<ArrayBufferLike>,): string;
Render markdown to an ANSI-colored terminal string.
Supports headings, lists, tables, inline styles, syntax-highlighted code blocks, links, images, and blockquotes. By default, enables all GFM extensions plus wikilinks, underline, and LaTeX math.
@param inputThe markdown string or buffer to render
@param themeOptional theme overrides
@returnsAn ANSI-colored string
const out = Bun.markdown.ansi("# Hello\n\n**bold** and *italic*\n"); process.stdout.write(out); // Plain text, no escape codes const plain = Bun.markdown.ansi("# Hello", { colors: false }); // Enable clickable OSC 8 hyperlinks const linked = Bun.markdown.ansi("[docs](https://bun.com)", { hyperlinks: true, }); // Inline images via Kitty Graphics Protocol const withImg = Bun.markdown.ansi("", { kittyGraphics: true, }); // Custom width const wrapped = Bun.markdown.ansi(longText, { columns: 60 }); - input: string | ArrayBufferLike | TypedArray<ArrayBufferLike> | DataView<ArrayBufferLike>,): string;
Render markdown to an HTML string.
@param inputThe markdown string or buffer to render
@param optionsParser options
@returnsAn HTML string
const html = Bun.markdown.html("# Hello **world**"); // "<h1>Hello <strong>world</strong></h1>\n" // With options const html = Bun.markdown.html("## Hello", { headings: { ids: true } }); // '<h2 id="hello">Hello</h2>\n' - input: string | ArrayBufferLike | TypedArray<ArrayBufferLike> | DataView<ArrayBufferLike>,): unknown;
Render markdown to React JSX elements.
Returns a React Fragment containing the parsed markdown as children. Can be returned directly from a component or passed to
renderToString().Override any HTML element with a custom component by passing it in the second argument, keyed by tag name. Custom components receive the same props the default elements would (e.g.
hreffor links,languagefor code blocks).Parser options (including
reactVersion) are passed as a separate third argument. UsesSymbol.for('react.transitional.element')by default (React 19). PassreactVersion: 18for React 18 and older.@param inputThe markdown string or buffer to parse
@param componentsComponent overrides keyed by HTML tag name
@param optionsParser options and element symbol configuration
@returnsA React Fragment element containing the parsed markdown
// Use directly as a component return value function Markdown({ text }: { text: string }) { return Bun.markdown.react(text); } // Server-side rendering import { renderToString } from "react-dom/server"; const html = renderToString(Bun.markdown.react("# Hello **world**")); // Custom components receive element props function Code({ language, children }: { language?: string; children: React.ReactNode }) { return <pre data-language={language}><code>{children}</code></pre>; } function Link({ href, children }: { href: string; children: React.ReactNode }) { return <a href={href} target="_blank">{children}</a>; } const el = Bun.markdown.react(text, { pre: Code, a: Link }); // For React 18 and older const el18 = Bun.markdown.react(text, undefined, { reactVersion: 18 }); - input: string | ArrayBufferLike | TypedArray<ArrayBufferLike> | DataView<ArrayBufferLike>,): string;
Render markdown with custom JavaScript callbacks for each element.
Each callback receives the accumulated children as a string and optional metadata, and returns a string. Return
nullorundefinedto omit an element. If no callback is registered, children pass through unchanged.Parser options are passed as a separate third argument.
@param inputThe markdown string to render
@param callbacksCallbacks for each element type
@param optionsParser options
@returnsThe accumulated string output
// Custom HTML with classes const html = Bun.markdown.render("# Title\n\nHello **world**", { heading: (children, { level }) => `<h${level} class="title">${children}</h${level}>`, paragraph: (children) => `<p>${children}</p>`, strong: (children) => `<b>${children}</b>`, }); // ANSI terminal output const ansi = Bun.markdown.render("# Hello\n\n**bold**", { heading: (children) => `\x1b[1;4m${children}\x1b[0m\n`, paragraph: (children) => children + "\n", strong: (children) => `\x1b[1m${children}\x1b[22m`, }); // With parser options as third argument const text = Bun.markdown.render("Visit www.example.com", { link: (children, { href }) => `[${children}](${href})`, paragraph: (children) => children, }, { autolinks: true });