Diataxis: the framework that sorts every doc in a SaaS repo into one of four jobs, one per reader.
You have read bad documentation, and probably written some.
The README that opens like a friendly tutorial, drifts into commands you will never run, spends forty lines defending a database choice, then trails off into an “Architecture” section last accurate two years ago.
By line fifty nobody is reading, so anything below it can be wrong unnoticed.
A team can write a thousand lines and still serve no one, and rarely for lack of effort.
One document was asked to do four jobs at once, so each reader has to wade past the other three to reach theirs.
The docs aren’t bad because they’re short or long; they’re bad because they’re mixed.
Diataxis names those four jobs.
With the four words in hand, you can look at any document, or any paragraph, name the job it is doing, and catch the moment it fails by trying to do two.
Everyone who opens a doc arrives with exactly one of four needs, and the four pull in opposite directions: serve one well and you serve the rest worse.
The first reader is new and needs to be led down one path until something works; options only paralyze them.
The second knows the codebase and needs to finish a task now, so they want to scan, grab the answer, and leave.
The third needs one fact, like the exact columns on a table, dry and complete with no story attached.
The fourth wants to understand why a decision was made, and needs the prose and rationale the other three were skipping.
Give the first reader the completeness the third wants and you bury them; give the third the narrative the fourth needs and you strand them at 2am with one question.
A paragraph cannot face four directions at once, so good documentation splits by what the reader came to do.
Each type is defined by what the reader came to do, not by file format.
Learn them in this canonical order.
Tutorial — learning
For a stranger to the codebase. It takes them by the hand down one path to a working end state: no decisions, no alternatives; follow along and you succeed. You know this one: this course is a tutorial. In a real repo the only tutorial is the README’s “Getting started” path.
How-to — doing a task
For someone who knows the codebase and wants one thing done: “add a Server Action,” “seed a tenant for local dev,” “rotate the Stripe webhook secret.” Goal-directed, assumes competence, built to be scanned. Its home is a “Common tasks” list, or a /docs/how-to/ folder for the heavy ones.
Reference — looking up a fact
Dry, complete, structured; it describes the surface exactly as it is. The reader wants one fact and nothing around it. You have met this one: the Drizzle schema file is reference, env.ts is reference, a TSDoc comment on a public function is reference.
Explanation — understanding why
For someone who wants the rationale and trade-offs: the why behind a choice, not the steps to carry it out. Read at leisure, away from the keyboard. An ADR is explanation, and so is a note on “why we chose Server Actions over a REST layer.”
Two of those anchors name things you meet later: a TSDoc comment is the doc-block editors turn into hover text, and an ADR records one architectural choice per file.
For now, treat them as the canonical homes of reference and explanation.
Two independent questions, each with two answers, give four combinations.
The first is the reader’s mode: are they acquiring a skill they don’t have yet (study mode) or applying one they already have (work mode)?
A newcomer learning the codebase is acquiring; an engineer rotating a secret is applying.
The second is the doc’s content: is it about action, the steps of doing something, or cognition, the understanding behind them?
“Run these commands” is action; “here’s why the architecture is shaped this way” is cognition.
Cross the two and each type lands in one cell: a tutorial is acquisition plus action, a how-to application plus action, reference application plus cognition, explanation acquisition plus cognition.
Acquisition · study mode
Application · work mode
Content of the doc
Action · doing
Cognition · knowing
Tutorial
acquisition + action
take me by the hand
How-to
application + action
help me do this task
Explanation
acquisition + cognition
help me understand why
Reference
application + cognition
tell me the exact fact
The four types on two axes: reader mode across, content down.
The grid is also a diagnostic.
When a doc feels bloated and you can’t say why, it has usually straddled two quadrants, trying to teach a newcomer and answer a fact-lookup in the same breath.
Read a typical README top to bottom and it crosses all four quadrants: a tutorial (“clone, install, run”), then a how-to (“to add a feature, do X”), then reference (a table of env vars), then explanation (“we chose Postgres because…”).
Four jobs, four readers, and each reader scans past three that aren’t theirs: the engineer who wanted the test command first reads a paragraph about Postgres.
The problem isn’t length; it’s one file serving four readers at once.
Before — the novel
one document, four jobs
README.md
Tutorial
pnpm install && pnpm dev
How-to
To add a feature: …
Reference
Env vars: DATABASE_URL, STRIPE_SECRET_KEY, …
Explanation
We chose Postgres because …
→
split
After — the split
each job in its real home
README.md
Tutorial + pointers
Getting started, then links out
the other three move out
How-to
AGENTS.md · /docs/how-to/
Reference
src/db/schema.ts · env.ts
Explanation
/docs/adr/
The fix: keep the README a thin tutorial, and move reference, explanation, and how-to to the artifacts that own them.
Send each job to the artifact that owns it, and keep the README a thin tutorial that points at the rest.
In a 2026 SaaS repo the four types land on a specific set of files.
Tutorial → the README.md “Getting started” section, and only that section.
How-to → AGENTS.md’s “Common tasks”, plus a /docs/how-to/ folder for the heavyweight procedures.
Reference → the code itself: the Drizzle schema, your Zod schemas, TSDoc on public functions, the env.ts file. Here the truth and its documentation are the same bytes.
Explanation → /docs/adr/ for architectural decisions, plus the occasional inline // why comment for narrow rationale.
One caveat: Diataxis is a thinking vocabulary, not a folder mandate.
The four types tell you what a given doc is for; they are not four directories every repo must create.
Most SaaS repos need only a README.md, an AGENTS.md, and a /docs/adr/ folder, which together with the source code carry all four types.
Scaffold empty /tutorials, /how-to, /reference, and /explanation folders on day one and you have copied the shape without the substance: four directories that sit empty or fill with the wrong things.
First, tie the abstract types to the sentences a reader would actually say.
Match each reader's request to the Diataxis type that serves it.
Click an item on the left, then its match on the right. Press Check when done.
”I’ve never seen this codebase — get me to a running dev server.”
Tutorial
”I know the repo. How do I rotate the Stripe webhook secret?”
How-to
”What columns does the invoices table have?”
Reference
”Why did we pick Drizzle instead of Prisma?”
Explanation
Now run it the other way, the direction you’ll use on the job: look at a real file and name its job.
Sort each real repo artifact into the documentation job it does.
Drag each item into the bucket it belongs to, then press Check.
TutorialLearning — take me by the hand
How-toDoing — help me do this task
ReferenceFact — tell me exactly what
ExplanationWhy — help me understand
The README.md “Getting started” steps
An AGENTS.md “Common tasks” entry
/docs/how-to/deploy.md
src/db/schema.ts
env.ts
TSDoc on a Server Action
/docs/adr/0001-use-drizzle.md
A // why we avoid useEffect here comment
If the reference bucket felt automatic — schema, env, and TSDoc are all code — that pattern runs through the whole chapter.
Reference lives in the code, which gives you a reflex worth carrying everywhere: whenever you’re about to paraphrase canonical truth in a doc, a function signature, a schema’s columns, a config value’s type, stop and link to the source instead.
The reason is mechanical.
A paraphrase has nothing holding it in sync with what it describes, so the moment the code changes it is wrong, and wrong silently: no test fails, no build breaks, the doc just starts lying.
A link can’t drift.
It resolves to the source of truth itself, so it always points at the current truth.
That is what makes “keep the README thin” mechanics rather than discipline: before typing a paragraph, ask whether it could just be a link.
Each type passes a different test, and those four tests are how you check your own docs.
A tutorial passes if a new hire reaches a green checkmark in under thirty minutes without asking anyone. Bolt how-to and reference onto it “for completeness” and they stall.
A how-to passes if the reader scans and finds the answer in under a minute. A paragraph of background to reach the step means explanation has leaked in.
A reference passes if an engineer finds the exact fact without reading one thing they don’t need. “The code is self-documenting” is half true: the schema is, but a gnarly Server Action’s TSDoc is not optional.
An explanation passes if a maintainer grasps the trade-off well enough to judge whether the decision still holds under new constraints. Write it before any reference exists and you get a “philosophy” doc floating above an undocumented codebase: decoration, not documentation.
No document passes all four, because the tests pull in the same opposite directions the readers did.
The first job is knowing which one you’re aiming at.