The llms-txt generator writes an llms.txt file: a
Markdown index of your docs that links to each page with a one-line
description, so language models and AI tools can find their way around. Add it
when you publish your docs on the web.
This page also covers llms-full.txt (llms-txt-full), which
puts the Markdown of every page in one file.
Target: llms-txt · Package: @doc-kit/generator-react · Reads: API entries · Writes: llms.txt
The links in llms.txt are absolute URLs, so set baseURL to where your docs
are published. There is no flag for it, so set it in your configuration file:
export default { global: { baseURL: 'https://example.com', }, };
npm install --save-dev @doc-kit/cli @doc-kit/generator-react npx doc-kit generate -t llms-txt -i "docs/**/*.md" -o out
For a project named my-lib with docs/index.md and docs/guide/usage.md,
this writes:
# my-lib Documentation > API documentation for my-lib. Below are the sections of the API documentation. Look out especially towards the links that point towards guidance/introduction to the structure of this documentation. ## API Documentations - [Usage](https://example.com/guide/usage.md): How to call my-lib from your code. - [My library](https://example.com/index.md): A small library for working with strings.
Without a baseURL, the links keep a literal {baseURL} (for example
{baseURL}/guide/usage.md), and nothing warns you about it.
Options go in the llms-txt section of the
configuration file:
import { join } from 'node:path'; export default { 'llms-txt': { templatePath: join(import.meta.dirname, 'llms-template.txt'), pageURL: '{baseURL}/docs{path}.md', }, };
stringllms.txt starts with (see
The template). A relative path resolves against the
directory you run doc-kit from. Default: the bundled template.txt.string{path} is the page's
path, without its extension and starting with a slash. Default:
'{baseURL}{path}.md'.stringllms.txt to. Without one, nothing
is written. Default: from global.output (--output).Like every generator section, it can also override a global option, such as
baseURL or project, for this generator alone.
llms.txt has one line for each top-level (#) heading in your sources, as
- [Heading](URL): Description:
- Heading is the heading's text. A page without a
#heading isn't listed, and a page with several gets a line for each. - URL is
pageURLfilled in for the page.{path}is the source file's path relative to the base of the input glob: with-i "docs/**/*.md",docs/guide/usage.mdbecomes/guide/usage. - Description is the page's
llm_descriptionwhen it has one. Otherwise it's the first paragraph between the heading and the next heading, on one line: inline code, bold and italics keep their Markdown, and links become plain text. Without such a paragraph, it's empty.
If your opening paragraph doesn't make a good summary on its own, write one for
models with the
llm_description directive,
right after the heading it describes:
# Usage <!-- llm_description=How to call my-lib from your code. -->
Section pages aren't
listed: llms.txt links to the full pages.
llms.txt is the template's text followed directly by the list of links, so
end the template with a newline. This is the default:
# {project} Documentation > API documentation for {project}. Below are the sections of the API documentation. Look out especially towards the links that point towards guidance/introduction to the structure of this documentation. ## API Documentations
The format at llmstxt.org expects a # title with
your project's name, then a > summary, then ## sections of links. A
template of your own can describe your project better and add links of its own
above the generated list.
Placeholders take the value of that option from the generator's configuration, which includes every global option:
| Placeholder | Value |
|---|---|
{project} | project: the name in your package.json, unless you set it |
{version} | version (--version): the Node.js version running doc-kit, unless you set your project's version |
{repository} | repository, as owner/name |
{baseURL} | baseURL |
{ref} | ref (--git-ref): HEAD unless you set it |
A placeholder without a value is left as written. To use a fallback instead,
write {name|fallback}, where the fallback is a single word (letters, digits
and underscores). The same placeholders work in pageURL, along with
{path}.
The default pageURL links to a .md file at each page's path
(/guide/usage.md next to /guide/usage.html), as llmstxt.org proposes,
since Markdown is easier for language models to read than HTML. doc-kit
doesn't write those files, so copy your sources into the output. With the
website, its pathsToCopy option
does it:
export default { target: ['html', 'llms-txt'], global: { input: ['docs/**/*.md'], output: 'out', baseURL: 'https://example.com', }, html: { // Copies the contents of docs/ into out/ pathsToCopy: ['public', { docs: '.' }], }, };
Setting pathsToCopy replaces its default list (assets, public and
static), so keep the ones you use, as public is kept here. doc-kit's own
site builds its llms.txt this way.
If you don't serve Markdown, link to the HTML pages instead with
pageURL: '{baseURL}{path}.html'.
The llms-txt-full generator writes the Markdown of every page into one
llms-full.txt file, each page after its URL, so a language model can read
all of your docs in a single request. Pair it with llms.txt, which only
links to each page.
Target: llms-txt-full · Package: @doc-kit/generator-react · Reads: API entries · Writes: llms-full.txt
Set global.baseURL as for llms.txt, since each page's URL starts
with it, then run:
npx doc-kit generate -t llms-txt -t llms-txt-full -i "docs/**/*.md" -o out
Options go in the llms-txt-full section of the configuration file:
string{path} is the
page's extensionless path, starting with a slash (/fs), and any other
option of the generator, global ones included, can be used too, such as
{baseURL} or {project}. It's set apart from llms-txt.pageURL, which
has the same default. Default: '{baseURL}{path}.md'.stringllms-full.txt to. Without one,
nothing is written. Default: from global.output (--output).ObjectArrayremark-stringify settings, syntax
extensions), not the content: their transforms don't run.The default URLs point at each page's Markdown file, which none of the
built-in generators write: copy your sources into the output, as in
Serving pages as Markdown, or set pageURL to
'{baseURL}{path}.html' to point at the website's pages.
Every page read from your sources, one after another. Each starts with a url
block between --- lines, built from pageURL, followed by the page's
Markdown. For this page and a path.md next to it:
# File system <!-- YAML added: v1.0.0 --> The `fs` module reads and writes files. Paths can be built with [`path.join()`][join]. ### `fs.readFile(path)` - `path` {string|URL} The file to read. - Returns: {Promise<Buffer>} [join]: ./path.md#pathjoinparts
llms-full.txt holds:
--- url: https://docs.example.com/fs.md --- # File system The `fs` module reads and writes files. Paths can be built with [`path.join()`](./path.html#pathjoinparts). ### `fs.readFile(path)` * `path` {string | URL} The file to read. * Returns: {Promise<Buffer>} --- url: https://docs.example.com/path.md --- # Path ### `path.join(...parts)` Joins path segments.
The Markdown is rebuilt from the API entries, not copied from your files, so it differs from the sources in a few ways:
- Links to
.mdfiles point to the.htmlpages. - Reference-style links become inline links, and their definitions are dropped.
- Formatting is normalized: bullet lists and emphasis use
*, strong text uses**, and a page without a heading starts with an empty#. <!-- YAML -->comments are left out.- Type annotations are rewritten with spaces around
|({string|URL}becomes{string | URL}). MDX pages keep their JSX.