Documentation

Remark plugins

Remark plugins

The remark stack is what turns interactive MDX into agent-readable markdown. Imports get stripped first, placeholders get resolved, then each named component is flattened into a markdown equivalent. Order matters.

The default stack

Rendering diagram...

defaultRemarkPlugins runs the stack in this order:

  1. remarkRemoveImports — strip MDX import and export statements.
  2. remarkRemoveJsxComments — strip {/* ... */} JSX comments.
  3. remarkResolveDocPlaceholders — replace {framework} and similar placeholders in URLs.
  4. remarkAudienceToMarkdown — include <Audience target="agent"> and remove <Audience target="human">.
  5. remarkSectionToMarkdown — flatten <Section> containers.
  6. remarkCalloutToMarkdown<Callout> → blockquote.
  7. remarkCardsToMarkdown<Cards> → bulleted link list.
  8. remarkDetailsToMarkdown — flatten <Details> blocks.
  9. remarkMermaidToMarkdown<Mermaid> → fenced ```mermaid block.
  10. remarkCommandTabsToMarkdown<CommandTabs> → markdown table.
  11. remarkStepsToMarkdown<Steps> → ordered list.
  12. remarkTabsToMarkdown<Tabs> → bold heading per tab.
  13. remarkTypeTableToMarkdown<TypeTable> and <ExtractedTypeTable> → markdown table.
  14. remarkAccordionToMarkdown<Accordion> → flattened sections (open/closed state ignored).
  15. remarkTopicSwitcherToMarkdown<TopicSwitcher> → labeled link list.
  16. remarkFileTreeToMarkdown<FileTree> → fenced text tree.
  17. remarkPromptToMarkdown<Prompt> → fenced ```prompt block.
  18. remarkExampleToMarkdown<Example> → fenced code block plus body.

Why order matters

Imports must go before placeholder resolution, because some placeholders read from imported modules. Placeholder resolution must go before component flatteners, because flatteners assume URLs are final strings, not template literals. The component flatteners run last so each one sees a clean tree.

Don't reorder casually. If you need a custom plugin to run before a flattener (for example, to transform a custom component into one of the contracted names), insert it after remarkResolveDocPlaceholders and before the flattener you want to feed.

Optional plugins

remarkInclude

Add this when the source docs use include tags or partial composition:

Place it before the default stack so included content expands before any flattener sees it.

Use src or text content to point at a shared markdown, MDX, or code file:

Markdown and MDX files are parsed and spliced into the current page. Frontmatter from the included file is stripped. Non-markdown files are included as fenced code; pass lang when the extension is not enough:

To reuse one section from a larger partial, append #section-id and wrap the reusable block in a lowercase HTML section element:

Section extraction currently matches lowercase <section id="..."> only. A capitalized MDX component such as <Section id="session-flow"> is flattened later by remarkSectionToMarkdown, but it is not an include anchor.

Relative paths resolve from the including file first. You can also pass base paths to the plugin for shared partial roots:

Nested includes are supported. The plugin keeps the included file's directory as baseDir for nested relative paths, so a partial can include files next to itself.

leadtype generate and leadtype lint run remarkInclude automatically. Custom conversion scripts must add it explicitly.

remarkTypeTableToMarkdown (with basePath)

<ExtractedTypeTable> reads a TypeScript file at conversion time. When the file path is relative, the plugin needs a basePath to resolve from. Override the default plugin entry to pass options:

In your MDX, point at a local TypeScript file by path and the type by name:

At conversion time, the plugin reads the file, finds the named type, and emits a markdown table with one row per property. The rendered output is what ships in the converted .md and root llms-full.txt — no JSX, no client-side rendering needed.

Plugin selection rules

  • Use defaultRemarkPlugins for any agent-facing or LLM output.
  • Add remarkInclude when docs are composed from shared fragments.
  • Use individual plugins only when you intentionally want to omit a flattener (e.g. you don't use <TypeTable> and want to skip its processing cost).
  • If output looks wrong, read the converted .md first. The fix is almost never reordering — it's usually a custom plugin between two existing ones.