Your introduction to Diataxis, the framework that sorts every doc in a SaaS repo into one of four jobs so each reader finds what they came for.
You have read bad documentation. You have probably written some too. The README that opens like a friendly tutorial, drifts into a list of commands you’ll never run, then spends forty lines justifying a database choice, then trails off into a half-finished “Architecture” section that was last accurate two years ago. By line fifty nobody is reading. Lines fifty-one through four hundred are wrong, and no one knows, because no one got there.
This is the gap between “we have docs” and “we have docs anybody actually uses.” A team can produce a thousand lines of documentation and still leave every reader unserved, and the reason is almost never effort. The real reason is that one document was asked to do four different jobs at once, so a reader who showed up for one of those jobs has to wade past the other three to find their part. The docs aren’t bad because they’re short or long. They’re bad because they’re mixed.
Diataxis is the vocabulary that names those four jobs. It is a four-word framework, and once you have the four words, the rest of this chapter becomes a single question asked four times: which artifact in the repo owns which job? You have already lived inside three of the four types without naming them. This course is one of them, and the repo you have been building is held together by another. By the end of this lesson you will be able to look at any document, or any paragraph inside one, and say which of the four jobs it is doing, and catch the moment it fails because it is quietly trying to do two.
To see why, start with the reader rather than the document. Whenever someone opens a doc, they arrive with exactly one of four needs, and those four needs interfere with each other. Optimizing a paragraph for one of them makes it worse for the other three. This is not a failure of writing skill; it is structural, and it is the whole reason the framework exists.
Picture the four readers. The first is brand new to the codebase and needs to be taken by the hand down one path until something works. They don’t want options or completeness, because options are paralyzing when you don’t yet know what any of them mean. The second already knows the codebase and needs to accomplish one specific task right now; they want to scan, find the one answer, and leave, so narrative prose is friction to them. The third needs to look up a single fact, like the exact columns on a table, and wants it dry and complete with no story attached. The fourth wants to understand why a decision was made, and for that they need exactly the prose and rationale the other three were trying to skip.
Now watch them collide. Hand the first reader the completeness the third one wants and you have buried them. Hand the third reader the narrative the fourth one needs and you have slowed them to a crawl at 2am when they had one question. The needs don’t just differ; they pull in opposite directions, and a single paragraph cannot face four directions at once. That is why good documentation splits by what the reader came to do, and it is the idea the four definitions rest on.
Here are the four. Read each one by its reader rather than its file format, because the type is defined by what the reader came to do, never by where the bytes live. The order below is the canonical one, so it is worth learning in this 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, success guaranteed if they follow along. You already know this one intimately, because this course is a tutorial. In a SaaS repo the only tutorial is the README’s “Getting started” path, if it has one, and nothing else.
How-to — doing a task
For someone who already knows the codebase and wants to accomplish one specific thing: “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, structurally organized; it describes the surface exactly as it is, with no interpretation. The reader wants one fact and nothing around it. You have met this one too: the Drizzle schema file is reference, env.ts is reference, and a TSDoc comment on a public function is reference.
Explanation — understanding why
For someone who wants the background, the rationale, and the trade-offs: the why behind a choice rather than the steps to do a task. 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.”
A few of those anchors lean on names you will meet properly later. A TSDoc comment is the doc-block that editors turn into hover text, and you will write them in the next chapter. An ADR is a one-decision-per-file record of an architectural choice, and it gets its own lesson later in this chapter. For now, treat them simply as the canonical homes of reference and explanation.
Notice what these four definitions have in common: every one is phrased in terms of the reader’s intent. A tutorial is not “a markdown file with numbered steps.” A tutorial is the doc a stranger follows to a first success. The format follows from the job, not the other way around.
So why exactly four, and not three or five? Because two independent questions, each with two answers, produce four combinations, and Diataxis is built on exactly those two questions.
The first question is about the reader’s mode: are they acquiring a skill they don’t yet have (study mode), or applying a skill they already have (work mode)? A newcomer learning the codebase is acquiring. An engineer rotating a secret is applying. The second question is about the doc’s content: is it about action, the practical steps of doing something, or about cognition, the theoretical knowledge and understanding behind it? “Run these commands” is action. “Here’s why the architecture is shaped this way” is cognition.
Two questions, two answers each, and the four document types fall straight out of the grid. A tutorial is acquisition plus action: you’re learning, by doing. A how-to is application plus action: you’re working, by doing. Reference is application plus cognition: you’re working, by knowing a fact. Explanation is acquisition plus cognition: you’re learning, by understanding. The following diagram places all four on those two axes.
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
Four readers, four quadrants. A doc that lands on the diagonal between two cells is the doc nobody finishes.
The grid also gives you a practical diagnostic. When a document feels bloated and unfocused and you can’t say why, it has almost always straddled two quadrants. The tension between, say, tutorial and reference is what you feel when a doc tries to teach a newcomer and answer a fact-lookup in the same breath. Once you can see the grid, you can name what went wrong.
Now turn the framework on the document you have seen fail most often: the README. Walk a typical one from top to bottom and watch it cross every quadrant in turn.
It opens as a tutorial, “clone this, install that, run this,” aimed at the newcomer. Then it slides into how-to: “to add a feature, do X, then Y.” Then it hardens into reference: a table of environment variables and their types. Then it drifts into explanation: “we chose Postgres because…” Four sections, four quadrants, four different readers, and every one of them has to scan past three jobs that aren’t theirs to reach the one that is. The newcomer hits the env-var table and stalls. The engineer who just wanted the test command reads a paragraph about Postgres. The doc isn’t too long; it’s four documents wearing one trenchcoat. The following diagram shows the same README two ways: as the mixed version, and split into its proper homes.
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/
Same content, two layouts. On the left, one document doing four jobs; on the right, each job sent to the artifact that owns it — which is the shape the rest of this chapter builds.
The right answer is the one the right side of that diagram shows: instead of writing one document that does four jobs, route each job to its own home. Keep the README a thin tutorial-and-pointer doc. Send reference down into the schema file and the TSDoc, where it can’t go stale. Send explanation to ADRs. Send how-to to AGENTS.md or a /docs/how-to/ folder. The README that survives is the one that does one job and points at the rest.
That routing isn’t abstract. In a 2026 SaaS repo the four types land on a small, specific set of files, and each of the next three lessons in this chapter takes one row of this map and builds it out properly.
Tutorial → the README.md “Getting started” section, and only that section. The next lesson builds the thin README.
How-to → AGENTS.md’s “Common tasks”, plus a /docs/how-to/ folder for the heavyweight procedures. The AGENTS.md lesson later in this chapter covers this.
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. The ADR lesson later in this chapter covers this.
One caveat matters more than the rest, and it is the one beginners get wrong first: Diataxis is a thinking vocabulary, not a folder mandate. The four types are how you decide what a given doc is for. They are not four directories every repo must create. Most SaaS repos need a README.md, an AGENTS.md, and a /docs/adr/ folder, and nothing else. Those few files, plus the source code itself, carry all four types between them. A team that scaffolds empty /tutorials, /how-to, /reference, and /explanation folders on day one hasn’t applied the framework; it has copied the shape without the substance, and now it owns four directories that will sit empty or, worse, fill with the wrong things.
Before moving on, tie the abstract types to concrete reader sentences. In the drill below, match each reader’s intent, phrased the way they’d actually say it, to the Diataxis type that serves them.
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, which is the direction you’ll actually use on the job. Here are real artifacts from a SaaS repo. Drop each one into the documentation job it does. The core skill is exactly this: look at a 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 sorting the reference bucket felt automatic, with schema, env, and TSDoc all being code, hold onto that observation. It runs through the whole chapter.
Look again at where reference lives: in the code. That fact leads to the one reflex that ties this whole chapter together, and it’s small enough to carry in your head.
Whenever you’re about to paraphrase canonical truth in a doc, whether a function signature, a schema’s column list, or a config value’s type, stop and link to the source instead.
The reason is mechanical, not stylistic. A paraphrase has nothing holding it in sync with the thing it describes. The moment the code changes, the paraphrase is wrong, and it is wrong silently: no test fails, no build breaks, the doc just quietly starts lying. A link can’t fail that way. It resolves to the source of truth itself, so it is correct by construction; when the code changes, the link still points at the current truth. This is what turns the rest of the chapter’s rules from good intentions into mechanics. “Keep the README thin” and “let the source be the doc” aren’t discipline you have to remember; they fall out of asking, before you type a paragraph, could this just be a link? The next lesson takes this same reflex and turns it into the README’s design.
One last thing makes the framework operational instead of merely tidy: each type passes a different test. Knowing the four tests is how you check your own docs.
A tutorial passes if a new hire follows it to a green checkmark in under thirty minutes without asking anyone. The trap here is the urge to be comprehensive: bolt how-to and reference onto the tutorial “for completeness” and the newcomer stalls. A doc that tries to pass all four tests passes none.
A how-to passes if the reader doing the task scans and finds the answer in under a minute. If they have to read a paragraph of background to reach the step, you have leaked explanation into it.
A reference passes if an engineer debugging at 2am finds the exact fact without reading one thing they don’t need. The line that “the code is self-documenting” is half true and half dangerous here. The schema genuinely is self-documenting, but a gnarly Server Action’s TSDoc is not optional; “self-documenting” justifies skipping reference only for code that really is trivial.
An explanation passes if a future maintainer grasps the trade-off well enough to decide whether the decision still holds under new constraints. The failure mode is writing explanation before any reference exists, because a “philosophy” doc floating above an undocumented codebase is decoration, not documentation.
Notice that no single document could pass all four tests at once, because the tests pull in the same opposite directions the readers did. So “good docs” isn’t one bar to clear. It is four separate bars, and the first job is knowing which one you’re aiming at.
There are four readers and four jobs, and each doc should do one of them. Before you write a paragraph, ask which of the four the reader came for, whether learning, doing a task, looking up a fact, or understanding why, and write for that one reader only. When you catch yourself about to copy a fact that lives somewhere canonical, link to it instead of paraphrasing it. The four types are a vocabulary for deciding what a doc is for; they are not four folders to create.
The next lesson takes the first artifact on the map, the README, and builds it as a deliberately thin tutorial-and-pointer document: the first concrete payoff of everything you just named.