comparison · 2026
AHTML vs llms.txttwo layers of the agentic web
tldr
AHTML is the canonical machine-readable snapshot of a site for AI agents — typed schema, deterministic chunk IDs, byte ranges, citation anchors, action dispatch. llms.txt is the human-readable index of important URLs and notes for LLM crawlers. They sit at different layers — and the @ahtmljs/next plugin emits both from a single extractor.
install
npm install @ahtmljs/next # Next.js plugin npm install @ahtmljs/vite # Vite / SvelteKit / SolidStart / Astro npm install @ahtmljs/agent # client SDK npm install @ahtmljs/langchain # RAG loader npm install @ahtmljs/schema # types + JSON Schema + validator
side by side
| Feature | AHTML | llms.txt |
|---|---|---|
| Layer | Canonical machine-readable snapshot | Human-readable site index |
| Audience | Agents that act on a site | LLM crawlers / discovery bots |
| Format | Typed schema (JSON or compact text) | Plain Markdown |
| Schema | Versioned JSON Schema + TS types | Convention only |
| Chunk identity | Deterministic IDs + byte ranges | None |
| Citation anchors | Per chunk, preserved through pipelines | None |
| Action dispatch | Yes — typed actions for agents | No |
| Cache validation | ETag | HTTP defaults |
| Discovery URL | /.well-known/ahtml.json | /llms.txt and /llms-full.txt |
| Plugin | @ahtmljs/next, @ahtmljs/vite | Same plugin emits llms.txt too |
| Client SDK | @ahtmljs/agent (typed, safety-gated) | None — fetch + parse |
| RAG loader | @ahtmljs/langchain (citation-preserving) | Generic Markdown loader |
example
// next.config.mjs
import { withAhtml } from "@ahtmljs/next";
export default withAhtml({}); // emits MCP + OpenAPI + JSON-LD + llms.txt + AHTML
// agent side
import { AhtmlClient } from "@ahtmljs/agent";
const client = new AhtmlClient({ origin: "https://dibbayajyoti.com" });
const snapshot = await client.fetch(); // ETag-cached
await client.dispatch("contact", { dryRun: true });when to use what
Use llms.txt when you want the easiest possible signal to LLM crawlers — a Markdown index of pages they should look at. Cheap to ship, almost no investment.
Use AHTML when agents will actually read or act on your site — RAG ingestion that needs stable chunk identity, dispatching typed actions, exact prompt cost prediction, dry-run safety gates.
Use both, ideally — the @ahtmljs/next plugin emits llms.txt, MCP, OpenAPI, JSON-LD, and AHTML from one config line.
faq
Is AHTML a replacement for llms.txt?
No — they sit at different layers. llms.txt is the human-readable index. AHTML is the canonical machine-readable snapshot. Agents use llms.txt to discover and AHTML to act.
Do I have to choose one?
No. @ahtmljs/next and @ahtmljs/vite emit both from a single extractor — plus MCP, OpenAPI, and JSON-LD.
Where is the AHTML snapshot served?
/.well-known/ahtml.json. The plugin auto-discovers App Router and Pages Router routes (or Vite framework routes).
How is this different from RAG-ready Markdown?
Document.chunks ships deterministic IDs and byte ranges — embeddings stay stable across deploys. Markdown gives you text but not stable chunk identity, anchors, or a typed action schema.
try ahtml
Browse the npm scope → or read the source on GitHub.
Live AHTML snapshot from this site: /.well-known/ahtml.json. Questions or want help integrating? Get in touch.
related
Other comparisons: Diffcore vs jsondiffpatch · Klinder-OSS vs PostHog · all projects
Thanks for reading. Love your work, keep it up!