---
title: How it works
description: >-
  The mental model: one MDX source, a remark pipeline, two output modes, three
  audiences.
group: get-started
lastModified: '2026-05-11T20:02:32-07:00'
lastAuthor: 'github-actions[bot]'
---
# How it works

Leadtype takes one input — a folder of MDX — and produces every shape your docs need to take. This page names every piece so the rest of the docs make sense.

## The pipeline

```mermaid
`flowchart TB
src["docs/*.mdx / title · description · group · body"]
fm["frontmatter parser"]
remark["remark plugin stack / (strip imports → flatten components)"]
groups["group resolver / (nav tree from frontmatter)"]
md["docs/*.md"]
site_idx["llms.txt · llms-full.txt / sitemap · robots · manifest / (website mode only)"]
search["search-index.json · search-content.json / (website mode only)"]
agents_md["AGENTS.md / (--bundle mode only)"]
nav["navigation manifest / (group → page)"]
src --> fm
fm --> remark
fm --> groups
remark --> md
md --> site_idx
md --> search
groups --> site_idx
groups --> agents_md
groups --> nav`
```

The remark stack is what turns interactive MDX components into agent-readable markdown. JSX gets *flattened* — a `<Callout>` becomes a blockquote, a `<Tabs>` becomes a sequence of bold headings, a `<TypeTable>` becomes a markdown table. The flattened markdown is what every other artifact consumes.

For the exact stack, see [Remark plugins](/docs/reference/remark). For the component contract, see [Components](/docs/authoring/components).

## Two output modes

`leadtype generate` has two modes that read the same source and emit different shapes:

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|Site mode (default)|leadtype generate --out public|Writes llms.txt, llms-full.txt, docs/search-index.json, docs/sitemap.xml, docs/sitemap.md, docs/robots.txt, docs/agent-readability.json, and docs/\*.md to a public/ directory your docs website serves. This is what you wire into a Vite, Next.js, Astro, or TanStack Start build.|-|Optional|
|Bundle mode|leadtype generate --bundle --out packages/foo|Writes AGENTS.md at the package root and docs/\*.md beneath it, both with relative paths. Skips llms.txt, llms-full.txt, search, sitemap, robots, and Agent Readability files — those are website-only. Designed for npm tarballs that ship docs alongside the published code.|-|Optional|

## The artifacts

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|Markdown (.md)|docs/\<path>.md|Flattened markdown for each MDX page. Both modes ship these. Served to HTTP agents via content negotiation in site mode; read directly from node\_modules in bundle mode.|-|Optional|
|AGENTS.md|\<package-root>/AGENTS.md|Bundle mode only. Offline-readable package index. Every link is a relative ./docs/\<path>.md path so the file works inside an installed npm package.|-|Optional|
|llms.txt + llms-full.txt|\<out>/llms.txt + \<out>/llms-full.txt|Site mode only. Agents fetch /llms.txt over HTTP and follow page-level markdown links first. The root /llms-full.txt file is a broad all-docs fallback when page links are not enough. Useless inside an npm tarball, so bundle mode skips this.|-|Optional|
|Search index|\<out>/docs/search-index.json + search-content.json|Site mode only. BM25-ranked inverted index over headings, titles, body, and code. Content is stored separately so the index stays small. Bundle mode skips it — agents reading from disk grep the .md files directly.|-|Optional|
|Agent Readability|\<out>/docs/sitemap.xml + \<out>/docs/sitemap.md + \<out>/docs/robots.txt + \<out>/docs/agent-readability.json|Site mode only. Docs-scoped discovery files and structured page data. Host apps merge this with blog, marketing, changelog, or product pages before serving root sitemap and robots files.|-|Optional|
|Navigation manifest|docs-nav.json (build script)|Resolved group tree mapping pages to nav locations. Built by the resolveDocsNavigation() helper so your sidebar component and your llms.txt sections agree on structure.|-|Optional|

## The three audiences

```mermaid
`flowchart LR
site_out["site mode / public/*"]
bundle_out["bundle mode / node_modules/&lt;pkg&gt;/*"]
human["Humans / (browser)"]
http_agent["HTTP agents / (fetch /llms.txt or / Accept: text/markdown)"]
search_ui["Search UI / AI answers"]
offline_agent["Coding agents / (Claude Code, Codex, / Cursor, Copilot, …)"]
site_out -- "HTML render of MDX" --> human
site_out -- "absolute URLs" --> http_agent
site_out -- "search-index.json" --> search_ui
bundle_out -- "version-matched AGENTS.md" --> offline_agent`
```

* **Humans** see the HTML your docs site renders from MDX.
* **HTTP agents** fetch `/llms.txt` over the network or use `Accept: text/markdown` content negotiation to get the converted `.md` from your docs site URL.
* **Coding agents working in a project that depends on your package** can read `node_modules/<your-package>/AGENTS.md` for version-matched offline docs. The reliable consumer pattern is to point the consuming project's root `AGENTS.md` or README at that file. From there they follow relative `./docs/<topic>.md` links.

The two flows complement each other. A package that wants to be agent-friendly publishes both: `--bundle` output inside the tarball *and* a hosted website with `llms.txt`. Different agents use different flows; you don't pick one.

## Vocabulary

A few terms you will see throughout the docs.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|flatten|verb|Convert an interactive MDX component into a portable markdown equivalent. A \<Callout> flattens to a blockquote; a \<Tabs> flattens to a stack of bold headings.|-|Optional|
|group|frontmatter field|A slug declaring which group a page belongs to. The same string drives the sidebar position, the llms.txt section, search metadata, and AGENTS.md grouping.|-|Optional|
|leaf|noun|A group that has no children. Leaves can directly contain pages in the navigation tree; non-leaf groups are summary headings only.|-|Optional|
|chunk|noun|A heading-aware slice of a page that the search index scores independently. Titles weigh 4×, headings 2×, body 1×, code 0.35×.|-|Optional|
|content negotiation|noun|Middleware or route logic that returns generated markdown when a request advertises Accept: text/markdown, uses an AI user agent, or asks for /docs/foo.md. Same content, two formats. Implement it wherever your framework intercepts requests — Next.js route handlers, Astro endpoints, Cloudflare Workers, Vite plugins, or server middleware.|-|Optional|

## What runs when

The `leadtype generate` command runs in a fixed order — each stage depends on the previous one's output:

1. **Parse frontmatter** for every `.mdx` under `docs/`.
2. **Convert** each file through the [default remark stack](/docs/reference/remark) and write `.md` to the output directory (e.g. `public/docs/` in site mode, `<package>/docs/` with `--bundle`).
3. **Resolve groups** from frontmatter, validate every page's `group:` matches a known slug.
4. In **site mode** (default): generate `llms.txt`, root `llms-full.txt`, the BM25 search index, and Agent Readability discovery files from the converted markdown.
5. With **`--bundle`**: write `AGENTS.md` at the output root with relative `./docs/<topic>.md` links. Skip `llms.txt`, `llms-full.txt`, search, sitemap, robots, and Agent Readability files — those are website-only.

If step 3 finds an unknown group, the run fails. That is by design — broken navigation is a content bug, not a render-time problem.

## Where to next

* [Quickstart](/docs/quickstart)
* [Frontmatter contract](/docs/authoring/frontmatter)
* [CLI reference](/docs/reference/cli)
