---
title: txtfirst
desc: A proposal for websites where the markdown file is the page and the HTML is only a rendering of it. Readable by agents by default, readable by people as a consequence.
order: 1
---

# txtfirst

**You are reading a rendering. The page is the markdown file behind it.**

Every URL on this site answers in two shapes from a single source. Ask for it as a
human and you get minimal HTML. Ask for it as a machine and you get the file itself.

```
curl https://txtfirst.com/spec                      # HTML for a browser
curl -H "Accept: text/markdown" https://txtfirst.com/spec   # the source
curl https://txtfirst.com/spec.md                   # the source, no headers needed
```

No build step produced two versions of this text. There is one file. The HTML is
generated from it at build time and thrown away on the next build.

## Check your own site first

```
curl -s https://txtfirst.com/cli/index.js > txtfirst.js
node txtfirst.js check yourdomain.com
```

Nothing to install beyond Node, no account, nothing sent anywhere. The checker is one
file with no dependencies, served from this site, and you can read it before you run it.
It reports whether your origin answers a plainly identified program at all, and then
whether it meets the four requirements on [spec](/spec). The same check runs from the
form at the top of this page if you would rather not open a terminal.

Most sites fail the first question before reaching the second, which is the finding this
whole site exists to report.

## The claim

The web was written for a reader that renders. It is now read, at scale, by a reader
that parses. Those two readers want opposite things, and for thirty years only one of
them got a format designed on purpose.

txtfirst says: write the document once, in the format the parser wants, and render it
down for the human. Not the other way around. Markdown first, HTML second.

## Why this is not just a nicer llms.txt

`llms.txt` is a map you maintain by hand next to the real site. It drifts, because
nothing breaks when it does. txtfirst has no second copy to drift: the file the agent
reads is the file the page is made of. If the page is wrong, the markdown is wrong,
and you fix it in one place.

## What it is worth, measured

On 4 September 2026 we asked twenty five hotel and travel homepages for their front
page, using an honestly identified HTTP client. Eight answered with readable content.
Seventeen returned 403, 429, a timeout, or a page with no text in it.

Across the eight that answered, the median page was **641 KB of HTML**, the median
text payload was **7.7 KB**, and the median ratio between them was **78 to 1**. Those
are three separate medians and no single site holds all three. One site, riu.com,
sent 5,822 KB to deliver 0.8 KB.

> The first problem is not that machine readers are served badly.
> It is that most of the web does not answer them at all.

Method, per-site results and the raw JSON are on [measure](/measure). The numbers on
this page come from that run and nothing else.

## What it costs you to adopt

One middleware function and a content directory. The reference implementation on
[implement](/implement) is forty five lines of JavaScript, and the same logic is shown
for Cloudflare Pages, Vercel, nginx and Apache. You keep your existing HTML site if
you want. txtfirst is additive.

## Who runs this

Three publishing sites serve their **article pages** this way in production, from one
shared patch, and each passes fourteen live checks. Their home pages do not, and score
three of eight, which is what the checker will tell you if you point it at them. That
gap is real and it is left visible here rather than described as full adoption.

The verification samples one article per site, not every article. The patch itself is
published as a script rather than as instructions, at `/adopt/`, because a specification
with one implementation is a blog post.

What this site itself is asked for, by shape and by client, is generated from its own
logs every day at [reads](/reads). It is small and young and says so.

## Start here

- [spec](/spec), the four requirements, version 0.1
- [why](/why), the argument, including where it does not hold
- [measure](/measure), the September 2026 readability study
- [implement](/implement), copy and paste it

txtfirst is a proposal, not a product. Everything here is CC0. Take it, fork it,
rename it, ship it without credit.
