---
title: Bundle docs into a package
description: >-
  Ship agent-readable docs inside an npm tarball — AGENTS.md at the package root
  plus per-topic .md files.
group: package-docs
lastModified: '2026-05-11T20:02:32-07:00'
lastAuthor: 'github-actions[bot]'
---
# Bundle docs into a package

Use this path when **you publish a library on npm** and want version-matched docs available without a network request. Run `leadtype generate --bundle` at prepack time, include the output in your published `files`, and every install ships **`AGENTS.md` + per-topic markdown** inside `node_modules/<your-package>/`.

The website is for humans and HTTP agents. The package-bundled docs are for coding agents, IDEs, and CLI tooling that can read files from the installed dependency.

## The flow

```mermaid
`flowchart LR
src["docs/*.mdx / (your repo)"]
cli["leadtype generate --bundle / --out packages/&lt;name&gt;"]
bundle["packages/&lt;name&gt;/ / AGENTS.md / docs/*.md"]
publish["npm publish"]
install["npm install &lt;name&gt;"]
consume["node_modules/&lt;name&gt;/ / AGENTS.md → docs/*.md / version-matched offline docs"]
src --> cli
cli --> bundle
bundle --> publish
publish --> install
install --> consume`
```

## Why AGENTS.md, not llms.txt?

[`llms.txt`](https://llmstxt.org) is a **website convention** — a file at `/llms.txt` with absolute URLs that an agent fetches over HTTP. Inside an npm tarball it's the wrong shape: every link points at a hosted URL the agent may not be able to reach, and no major coding agent looks for `node_modules/<pkg>/llms.txt` anyway.

[`AGENTS.md`](https://agents.md) is the **filesystem convention** that solves this. Tools like Claude Code, OpenAI Codex, Cursor, GitHub Copilot, Aider, Devin, and others can read `AGENTS.md` when working with files on disk. An `AGENTS.md` inside `node_modules/<your-package>/` is the right shape for version-matched package docs: relative links work, no network is required, and the content matches the installed version.

leadtype emits both — `llms.txt` in [website mode](/docs/build/connect-docs-site) for HTTP-discoverable agents, and `AGENTS.md` in `--bundle` mode for offline filesystem-discoverable agents.

## Generate into the package

```bash
npx leadtype generate \
  --bundle \
  --src . \
  --out packages/my-package \
  --name "my-package" \
  --summary "Docs for my-package."
```

This writes:

```text
packages/my-package/
├── AGENTS.md
└── docs/
    ├── index.md
    ├── quickstart.md
    └── reference/
        └── cli.md
```

Every link inside `AGENTS.md` is a relative path like `./docs/quickstart.md` so the file is meaningful both at `packages/my-package/AGENTS.md` (during local dev) and at `node_modules/my-package/AGENTS.md` (after install).

`--bundle` skips `llms.txt`, `llms-full.txt`, and the search index — those are website artifacts that don't make sense offline.

## Filter to package-specific docs

A monorepo with one shared `docs/` and many packages should bundle only the slice each package owns. Use `--include` (repeatable) and `--exclude`:

```bash
npx leadtype generate \
  --bundle \
  --src . \
  --out packages/react \
  --name "@c15t/react" \
  --include "frameworks/react/**" \
  --include "shared/**" \
  --exclude "**/internal/**"
```

Filters are explicit. If the package needs shared overview pages, list them too. `--exclude` is applied after `--include`.

## Include in the published tarball

Add `AGENTS.md` and `docs` to `files` and run generation as a build or prepack step:

```json
{
  "files": ["dist", "docs", "AGENTS.md", "README.md"],
  "scripts": {
    "build": "tsup && npx leadtype generate --bundle --src ../.. --out ."
  }
}
```

If you need full control over plugin order or custom validation, run the library APIs directly from a script:

```ts
// scripts/generate-docs.ts
import { rm } from "node:fs/promises";
import { convertAllMdx } from "leadtype/convert";
import { generateAgentsMd, resolveDocsNavigation } from "leadtype/llm";
import { defaultRemarkPlugins } from "leadtype/remark";
import docsConfig from "../../../docs/docs.config";

const REPO_ROOT = `${process.cwd()}/../..`;
const PACKAGE_ROOT = process.cwd();

await rm(`${PACKAGE_ROOT}/docs`, { recursive: true, force: true });
await rm(`${PACKAGE_ROOT}/AGENTS.md`, { force: true });

await convertAllMdx({
  srcDir: `${REPO_ROOT}/docs`,
  outDir: `${PACKAGE_ROOT}/docs`,
  remarkPlugins: defaultRemarkPlugins,
});

// Fail fast on unknown groups so a bad config can't ship.
const navigation = await resolveDocsNavigation({
  srcDir: REPO_ROOT,
  groups: docsConfig.groups,
});
if (navigation.unknown.length > 0) {
  for (const { urlPath, slug } of navigation.unknown) {
    process.stderr.write(`error: ${urlPath} declares unknown group "${slug}".\n`);
  }
  process.exit(1);
}

await generateAgentsMd({
  srcDir: REPO_ROOT,
  outDir: PACKAGE_ROOT,
  product: docsConfig.product,
  groups: docsConfig.groups,
});
```

Point your build script at it: `"build": "tsup && bun run scripts/generate-docs.ts"`.

## Verify before publishing

```bash
npx leadtype generate --bundle --src . --out packages/my-package
cd packages/my-package && npm pack --dry-run
```

`npm pack --dry-run` should list:

* `AGENTS.md`
* `docs/**/*.md`

If `AGENTS.md` is missing, check `files` in `package.json`. If `.md` files are missing, check the `--include`/`--exclude` filters.

## Tell consuming projects to use the bundle

`AGENTS.md` inside your tarball is available at `node_modules/<your-package>/AGENTS.md` after install. Some agents discover dependency docs from tool use or search. The reliable pattern is to point the consuming project at the bundled docs.

Recommend this snippet in your README so consumers add it to their own root `AGENTS.md`:

```md
# <my project>

When working with the `<your-package>` library, read the bundled docs in
`node_modules/<your-package>/AGENTS.md` first — they're version-matched to
the installed package and stay accurate as the library updates.
```

This is the same pattern Next.js uses to point agents at `node_modules/next/dist/docs/`.

## When to use this

Use this when **agents should understand the package from the installed dependency itself** — coding agents that don't have web access, IDE assistants, CLI tools, or air-gapped environments.

Don't use this if your only goal is a public docs website. For that, see [Connect a docs site](/docs/build/connect-docs-site). You can use both — they read the same source MDX, just emit different shapes.

## What's next

* [CLI reference](/docs/reference/cli)
* [LLM files](/docs/reference/llm)
* [Lint in CI](/docs/build/validate-in-ci)
