Reference

Options

Options for Sätteri's entry points. CompileOptions is shared by markdownToHtml and mdxToJs, which additionally accepts the MDX options below.

CompileOptions

OptionTypeNotes
mdastPluginsMdastPluginInput[]MDAST plugins, or factories that return one. See Plugins.
hastPluginsHastPluginInput[]HAST plugins, or factories.
featuresFeaturesParser extensions. See Features.
fileURLURLThe document's URL, surfaced to plugins as ctx.fileURL.
dataDataInitial data bag.

fileURL

fileURL must be a URL, not a string — pass an existing file URL (such as Astro's fileURL), or convert a filesystem path with Node's pathToFileURL:

import { pathToFileURL } from "node:url";

markdownToHtml(source, { fileURL: pathToFileURL("docs/intro.md") });

Plugins read it back as ctx.fileURL (a URL, or undefined when omitted).

data

data seeds the document-level data bag before any plugin runs. It is the same object plugins mutate via ctx.data and the caller reads back as result.data, so values flow both into and out of a compile:

const data = { title: "Original" };
const result = markdownToHtml(source, { mdastPlugins: [rewriteTitle], data });

result.data === data; // true — the seeded object is returned, not a copy

It is used by reference and mutated in place, so pass a throwaway object per compile rather than a shared one. Omit it and each compile gets a fresh {}. The bag lives entirely on the JS side, so any value is allowed (functions, class instances, Map/Set), and references survive the mdast→hast boundary. See the data bag for the plugin side and DataMap typing.

MDX options

mdxToJs accepts everything in CompileOptions plus the MDX-only fields below (also exported on their own as MdxOnlyOptions).

optimizeStatic

Collapses contiguous static subtrees into a single pre-rendered HTML string, cutting the number of JSX element calls in the output. Dynamic content (components, {expressions}) is left as normal JSX.

// Astro-style: wraps static HTML in <Fragment set:html="…">
mdxToJs(source, {
  optimizeStatic: { component: "Fragment", prop: "set:html" },
});

// React-style: wraps in <div dangerouslySetInnerHTML={{ __html: "…" }}>
mdxToJs(source, {
  optimizeStatic: { component: "div", prop: "dangerouslySetInnerHTML", wrapPropValue: true },
});
FieldTypeNotes
componentstringElement/component the static HTML is wrapped in.
propstringProp the HTML string is passed on.
wrapPropValuebooleanWhen true, wrap the value as {{ __html: "…" }}. Default: false.
ignoreElementsstring[]Tag names to keep as JSX calls instead of collapsing.

Elements that can be overridden at runtime via export const components are kept as JSX automatically, so component overrides still apply.

This optimization was originally developed by Bjorn Lu for Astro.

JSX output

The remaining MDX options control the generated JavaScript and are named after the standard @mdx-js/mdx compiler options (Sätteri's MDX compiler is a separate implementation — see Divergences):

OptionTypeDefaultNotes
jsxbooleanfalseKeep JSX instead of compiling it to function calls.
jsxRuntime"automatic" | "classic""automatic"JSX runtime.
jsxImportSourcestring"react"Where the automatic runtime is imported from (e.g. "preact").
providerImportSourcestringWhere the component provider is imported from.
developmentbooleanfalseDevelopment mode (adds debugging info).
pragmastring"React.createElement"Classic-runtime JSX pragma.
pragmaFragstring"React.Fragment"Classic-runtime fragment pragma.
pragmaImportSourcestring"react"Where the classic pragma is imported from.
outputFormat"program" | "function-body""program"program emits an ES module; function-body emits a body for new Function() / evaluate.
elementAttributeNameCase"react" | "html""react"Casing for attributes on rehype-produced elements.
stylePropertyNameCase"dom" | "css""dom"Casing for keys in parsed style objects.