
Docs Writing
- 671 installs
- 74 repo stars
- Updated August 5, 2026
- mblode/agent-skills
docs-writing is a Claude Code skill that writes and audits technical documentation using the Diataxis framework and Stripe-level clarity standards for developers who need scannable READMEs, API docs, tutorials, and how-t
About
docs-writing is a documentation skill from mblode/agent-skills that applies 52 rules across 9 categories covering voice, structure, clarity, code examples, formatting, navigation, scanability, content hygiene, and review. The skill follows the Diataxis framework to classify content as tutorials, how-to guides, reference, or explanation, and enforces Stripe-style clarity for developer-facing prose. Developers reach for docs-writing when drafting new documentation, documenting APIs, writing tutorials, auditing an existing README or docs site, or asking to review or improve documentation quality. The skill explicitly defers README-from-scratch creation to readme-creator, AGENTS.md and CLAUDE.md work to agents-md, and marketing copy to copywriting.
- 52 rules organized across 9 categories including voice, structure, clarity, code examples, formatting, navigation, scana
- Supports both writing new documentation and auditing existing READMEs, API references, tutorials, and how-to guides
- Mode dispatch automatically chooses Audit workflow or Writing workflow based on user request
- Delivers Diataxis-aligned docs with runnable code examples and improved scanability
- Hard gate: always run audit workflow before finalizing improvements or fixes
Docs Writing by the numbers
- 671 all-time installs (skills.sh)
- +32 installs in the week ending Aug 4, 2026 (Skillselion tracking)
- Ranked #335 of 1,879 Documentation skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/mblode/agent-skills --skill docs-writingAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 671 |
|---|---|
| repo stars | ★ 74 |
| Last updated | August 5, 2026 |
| Repository | mblode/agent-skills ↗ |
How do you audit technical docs for clarity?
Produce clear, consistent, and scannable technical documentation that follows the Diataxis framework and Stripe-level clarity standards.
Who is it for?
Developers and technical writers who maintain READMEs, API references, tutorials, or internal docs sites and want Diataxis-aligned, Stripe-quality prose.
Skip if: Teams that need marketing landing-page copy, auto-generated README scaffolding from scratch, or AGENTS.md and CLAUDE.md authoring workflows.
When should I use this skill?
The user asks to write, review, improve, or audit technical documentation, API docs, tutorials, how-to guides, or a README.
What you get
Diataxis-classified documentation drafts, audited README sections, and a structured review against 52 clarity and formatting rules.
- Audited documentation
- Diataxis-classified doc drafts
- Structured clarity review
By the numbers
- Bundles 52 documentation rules across 9 categories
- Covers 9 documentation quality categories including voice, structure, and navigation
Files
Documentation Writing
- IS: writing and auditing technical documentation quality across Diataxis doc types, voice, structure, clarity, runnable code examples, formatting, navigation, and content hygiene. Applies to docs sites, API references, tutorials, how-to guides, and existing READMEs.
- IS NOT: creating a README from scratch (use
readme-creator), AGENTS.md or CLAUDE.md agent instructions (useagents-md), or marketing and landing-page copy (usecopywriting).
Mode dispatch
- Reviewing existing docs? → Audit workflow.
- Writing new docs or rewriting a page? → Writing workflow.
- Asked to "improve" or "fix" docs? → Audit workflow first, then apply the fixes yourself instead of reporting them.
Audit workflow
Copy and track this checklist:
Docs audit progress:
- [ ] Step 1: Scope to changed files only, unless a full sweep was requested
- [ ] Step 2: Classify each doc (tutorial, how-to, reference, explanation) and audience
- [ ] Step 3: Run CRITICAL categories (voice-, structure-)
- [ ] Step 4: Run HIGH categories (clarity-, code-)
- [ ] Step 5: Run remaining in-scope categories (format-, nav-, scan-, hygiene-, review-)
- [ ] Step 6: Report findings per the output contract, ordered by severityDoc type gates which rules apply, so classify before loading rules. Load rule files by category prefix (rules/voice-*.md, then rules/structure-*.md, ...) only for categories in scope. After applying fixes, rerun the rules that produced findings before finalizing.
Writing workflow
Copy and track this checklist:
Docs writing progress:
- [ ] Step 1: Pick one Diataxis type per file (tutorial, how-to, reference, explanation) and name the audience
- [ ] Step 2: Read the defaults bundles (voice-defaults, clarity-defaults, scan-defaults) plus structure rules for the doc type
- [ ] Step 3: Draft with bottom line up front, quick start for getting-started docs, runnable examples for every concept
- [ ] Step 4: Self-audit against CRITICAL and HIGH categories; fix findings
- [ ] Step 5: Verify by running every code example, resolving every link, and confirming parameter names against the implementationStep 5 is the exit criterion: a doc ships only after its examples run and its links resolve, not when it "reads well".
Rule categories by priority
| Priority | Category | Impact | Prefix | Rules |
|---|---|---|---|---|
| 1 | Voice & Tone | CRITICAL | voice- | 4 |
| 2 | Structure & Organization | CRITICAL | structure- | 10 |
| 3 | Clarity & Language | HIGH | clarity- | 6 |
| 4 | Code Examples | HIGH | code- | 7 |
| 5 | Formatting & Syntax | MEDIUM-HIGH | format- | 8 |
| 6 | Navigation & Linking | MEDIUM-HIGH | nav- | 6 |
| 7 | Scanability & Readability | MEDIUM | scan- | 2 |
| 8 | Content Hygiene | MEDIUM | hygiene- | 6 |
| 9 | Review & Testing | LOW-MEDIUM | review- | 3 |
For the full rule list per category, read rules/_sections.md. The *-defaults.md files (voice, clarity, scan, review) are multi-check bundles. Each codifies 3-5 baseline checks for its category.
Output contract (audit mode)
## Documentation Audit Findings
### path/to/file.md
- [CRITICAL] `voice-defaults`: Passive voice obscures who performs the action.
- Fix: Rewrite "The configuration is loaded by the server" as "The server loads the configuration."
### path/to/clean-file.md
- ✓ pass- Group findings by file; order by severity within each file.
- Use
file:linewhen line numbers are available. - Every finding names the rule, states the issue, and proposes a concrete fix. A finding without a fix is not reportable.
- Include clean files as
✓ passso the author knows they were checked.
Gotchas
- Doc-type misclassification is the top false-positive source:
structure-quick-startapplies only to getting-started docs and READMEs, andscan-three-column-apionly to API references. Flagging a missing quick start on an explanation page tells the author to break Diataxis. - The
*-defaults.mdbundles contain 3-5 checks each, so cite the specific failing check ("voice-defaults: passive voice"), not just the filename, or the author can't locate the issue among the bundle. - Don't load all 52 rule files up front; that floods context before scope is known. Load by prefix for in-scope categories only.
- Don't report MEDIUM/LOW polish above CRITICAL/HIGH findings; authors fix what they see first, and a serial-comma nit can bury a structure problem.
- Don't rewrite content you were asked to review; report and propose fixes unless the user asked for edits or said "improve/fix".
- Don't audit files that weren't changed unless a full sweep was explicitly requested; unscoped findings drown the real ones.
Related skills
readme-creator: creating a README from scratch; this skill audits and improves existing READMEs.agents-md: AGENTS.md/CLAUDE.md agent instruction files (execution-first standards, not reader-facing docs).copywriting: marketing, landing-page, and product copy.blodemd: scaffolding and deploying MDX docs sites; this skill governs the content quality inside them.
Sections
Defines all 9 categories, their ordering, impact levels, and rules. The section ID (in parentheses) is the filename prefix used to group rules. 52 rules total.
---
1. Voice & Tone (voice)
Impact: CRITICAL Description: Consistent reader-centric voice is the foundation of trustworthy documentation. 4 rules: voice defaults (active voice, contractions, second person, professional tone, reader-centric framing), no jargon, no anthropomorphism, requirements language.
2. Structure & Organization (structure)
Impact: CRITICAL Description: Well-structured documentation lets readers find and follow information. 10 rules: Diataxis one-type-per-file, bottom line up front, conditions before instructions, heading followed by overview, hierarchical headings, next steps, numbered lists vs bullets, one idea per section, clear procedures, quick start for getting-started docs.
3. Clarity & Language (clarity)
Impact: HIGH Description: Clear language removes barriers between readers and information. 6 rules: clarity defaults (plain language, cut filler, be specific, global audience, short paragraphs), serial comma, no Latin abbreviations, no nominalizations, meaningful names, one idea per sentence.
4. Code Examples (code)
Impact: HIGH Description: Real, runnable examples are the most valuable part of technical documentation. 7 rules: runnable examples (with why-not-what comments), code-to-context ratio, isolated-to-full layering, multiple languages, error descriptions, named functions, descriptive variables.
5. Formatting & Syntax (format)
Impact: MEDIUM-HIGH Description: Consistent formatting makes documentation predictable and professional. 8 rules: sentence case headings, bold UI elements and code font for commands, descriptive link text, image alt text, lowercase filenames, parallel lists, periods inside quotes, semantic HTML.
6. Navigation & Linking (nav)
Impact: MEDIUM-HIGH Description: Connected documentation is discoverable documentation. 6 rules: every doc linked from at least one other doc, breadcrumb context, don't repeat content covered elsewhere, layered content depth, relative paths, searchable headings.
7. Scanability & Readability (scan)
Impact: MEDIUM Description: Readers scan before they read. 2 rules: scan defaults (front-load key information, white space between groups, diagrams and tables over prose, varied sentence rhythm), three-column API reference layout.
8. Content Hygiene (hygiene)
Impact: MEDIUM Description: Documentation rots faster than code. 6 rules: delete outdated content, dedicated docs directory, experimental-feature labels, no temporal content (status reports, dated plans), retcon labels for rewritten history, update metadata on edit.
9. Review & Testing (review)
Impact: LOW-MEDIUM Description: Documentation that works for the author may not work for the reader. 3 rules: review defaults (fresh-reader test, read aloud and cut, verify against implementation), verify links, readability score.
Rule Title Here
Brief explanation of the rule and why it matters for documentation quality, readability, or discoverability.
Incorrect (description of what's wrong):
Bad documentation example showing the problem.Correct (description of what's right):
Good documentation example showing the solution.Reference: Link to documentation or resource
<!-- Conventions:
- Filename: <prefix>-<slug>.md where <prefix> matches a section in _sections.md
- impact: must match the section's impact level (CRITICAL, HIGH, MEDIUM-HIGH, MEDIUM, LOW-MEDIUM)
- H2 title matches the frontmatter title
- The Incorrect/Correct parentheticals name the specific failure/fix, not just "bad"/"good"
- Use ````markdown fences (four backticks) when the example itself contains code fences
- Adding or removing a rule: update the count in _sections.md, the SKILL.md priority table, and the SKILL.md description
-->
Clarity defaults checklist
Claude follows these by default. This checklist codifies them as the project standard:
- [ ] Plain language -- use "use" not "utilize," "start" not "initiate," "help" not "facilitate."
- [ ] Cut filler -- remove "very," "really," "just," "basically," "actually," "simply," "in order to."
- [ ] Be specific -- quantify claims; replace "fast," "easy," "powerful" with numbers or concrete examples.
- [ ] Global audience -- standard US English, no idioms, sports metaphors, or cultural references.
- [ ] Short paragraphs -- max 4 sentences per paragraph for web content. One-sentence paragraphs are fine for emphasis.
Incorrect (vague, wordy, uses idioms and filler):
It is important to note that you should basically just utilize the
dashboard to facilitate deployment. The API is really fast and very
powerful. Once you get the hang of it, you'll hit the ground running.
Tokens expire after 24 hours. You can configure expiry. When a token
expires, the client must request a new one. The refresh endpoint
handles this automatically.Correct (plain, specific, literal, scannable):
Use the dashboard to start your deployment. The API responds in under
50ms and handles 10,000 concurrent requests.
Tokens expire after 24 hours by default. You can configure the expiry
time in the dashboard.
When a token expires, the client requests a new one. The refresh token
endpoint handles this automatically.Reference: Federal Plain Language Guidelines
Use realistic names in examples, never foo/bar/x/data
Placeholder names force readers to mentally substitute real values. Use names that reflect the actual domain: userId, orderTotal, configPath.
Incorrect (abstract placeholders add cognitive load):
const x = getData(foo);
const result = process(x, bar);Correct (domain names make the example self-documenting):
const response = fetchUserProfile(userId);
const invoice = generateInvoice(response, billingPlan);See also: code-descriptive-variables.md for code-specific naming in standalone examples.
Reference: Google Technical Writing: Clear sentences
Write out Latin abbreviations
Use "for example" not "e.g.," "that is" not "i.e.," "and so on" not "etc." Latin abbreviations trip up screen readers and non-native English speakers.
Incorrect (Latin abbreviations assume familiarity):
Supports multiple formats, e.g., JSON, XML, etc. The config
file (i.e., the main settings file) must be valid YAML.Correct (written-out forms are universally clear):
Supports multiple formats, for example, JSON and XML. The config
file (that is, the main settings file) must be valid YAML.Reference: Google Developer Documentation Style Guide: Abbreviations
Use verbs, not noun forms of verbs
Nominalizations bury the action in a noun. "Make a decision" becomes "decide." "Perform an analysis" becomes "analyze." "Give consideration to" becomes "consider."
Incorrect (nominalized verbs hide the action):
The system performs validation of the input and makes a
determination of the output format. After completion of the
installation, perform a verification of the configuration.Correct (strong verbs communicate directly):
The system validates the input and determines the output format.
After installing, verify the configuration.Reference: Federal Plain Language Guidelines: Use strong verbs
One idea per sentence, max 25 words
Long compound sentences lose readers. Split at conjunctions. If a sentence has more than one "and" or "but," it needs splitting.
Incorrect (compound sentence buries multiple ideas):
The system processes the request and validates the input and then
generates a response, which is sent back to the client and logged
for debugging purposes.Correct (each sentence carries one idea):
The system processes the request and validates the input. It
generates a response, sends it to the client, and logs it for
debugging.Always use the serial comma
Place a comma before the final "and" or "or" in a list of three or more items. This prevents ambiguity.
Incorrect (missing serial comma creates ambiguity):
The CLI supports create, update and delete commands. You can
export to JSON, XML and CSV.Correct (serial comma removes ambiguity):
The CLI supports create, update, and delete commands. You can
export to JSON, XML, and CSV.Reference: Microsoft Writing Style Guide: Commas
Match code-to-text ratio to document type
Tutorials need more explanation (~40% code). API references are mostly code (~90% code). Don't drown tutorials in code or bury references in prose.
Incorrect (tutorial is 90% code with no explanation):
````markdown
const app = express();
app.use(express.json());
app.post("/webhook", (req, res) => {
if (req.body.type === "payment.completed") handlePayment(req.body);
res.sendStatus(200);
});````
Correct (tutorial explains each step before showing code):
````markdown First, set up an Express server to receive POST requests:
const app = express();
app.use(express.json());Next, create a route that handles incoming events by type:
app.post("/webhook", (req, res) => {
if (req.body.type === "payment.completed") handlePayment(req.body);
res.sendStatus(200);
});````
Reference: Divio Documentation System
Use descriptive variable names in examples
Variable names teach readers what the code does. Use subscriptionId, paymentIntent, customerEmail -- never x, y, data, temp, result.
Incorrect (generic names force readers to track mental mappings):
const d = await get(id);
const r = transform(d, opts);
console.log(r.status);Correct (descriptive names make the code self-documenting):
const invoice = await getInvoice(invoiceId);
const receipt = formatReceipt(invoice, displayOptions);
console.log(receipt.status);See also: clarity-meaningful-names.md for naming in prose examples and explanatory text.
Reference: Google Technical Writing: Naming variables
Document errors with codes, meanings, and fixes
Don't just list error codes. Show the error message, explain what caused it, and tell the reader how to fix it. Developers reach for error docs when stuck -- help them get unstuck.
Incorrect (error code with no actionable guidance):
| Code | Description |
|------|-------------|
| 403 | Forbidden |
| 429 | Rate limited |Correct (each error includes cause and fix):
### 403 Forbidden
Your API key doesn't have permission for this endpoint. Check
that your key has the `billing:read` scope in the
[API dashboard](https://dashboard.acme.com/keys).
### 429 Too Many Requests
You exceeded 100 requests per minute. Add exponential backoff
to your retry logic or request a rate limit increase in the
[API dashboard](https://dashboard.acme.com/limits).Layer examples from focused snippet to full context
Show the key function first, then where it fits in the file. Let readers build understanding incrementally instead of dumping the entire file upfront.
Incorrect (full file where the relevant part is 3 lines):
````markdown
import express from "express";
import { db } from "./db.js";
import { validateAuth } from "./auth.js";
const app = express();
app.use(express.json());
app.post("/webhooks", validateAuth, async (req, res) => {
await db.events.insert(req.body);
res.sendStatus(200);
});
app.listen(3000);````
Correct (focused handler first, link to full context):
````markdown The webhook handler validates auth, stores the event, and returns 200:
app.post("/webhooks", validateAuth, async (req, res) => {
await db.events.insert(req.body);
res.sendStatus(200);
});See the full server setup for middleware and startup configuration. ````
Reference: Divio Documentation System: Tutorials
Provide examples in multiple languages when applicable
If your API supports multiple languages, show examples in at least the 2-3 most common ones. Use tabbed code blocks or clearly labeled sections. Don't force Python on a Node.js developer.
Incorrect (only one language for a multi-language SDK):
````markdown
import acme
client = acme.Client(api_key="sk_live_abc123")
user = client.users.create(name="Ada Lovelace")````
Correct (multiple languages let readers use their stack):
````markdown
import acme
client = acme.Client(api_key="sk_live_abc123")
user = client.users.create(name="Ada Lovelace")import Acme from "acme";
const client = new Acme({ apiKey: "sk_live_abc123" });
const user = await client.users.create({ name: "Ada Lovelace" });curl -X POST https://api.acme.com/users \
-H "Authorization: Bearer sk_live_abc123" \
-d '{"name": "Ada Lovelace"}'````
Reference: Stripe API Documentation
Break complex operations into named functions
Readers should skim function names and understand the flow. Extract named functions instead of inline logic so the top-level code reads like pseudocode.
Incorrect (nested inline logic hides the flow):
app.post("/orders", async (req, res) => {
if (!req.body.items || req.body.items.length === 0) {
return res.status(400).json({ error: "No items" });
}
const total = req.body.items.reduce((sum, i) => sum + i.price, 0);
const charge = await stripe.charges.create({ amount: total });
await sendEmail(req.body.email, { orderId: charge.id });
res.json({ orderId: charge.id });
});Correct (named functions make the flow scannable):
app.post("/orders", async (req, res) => {
validateOrderItems(req.body.items);
const total = calculateOrderTotal(req.body.items);
const charge = await processPayment(total);
await sendConfirmation(req.body.email, charge.id);
res.json({ orderId: charge.id });
});Reference: Google Technical Writing: Code samples
Every concept needs a copy-paste-ready example
Readers learn by doing, not reading. Every concept, function, or API endpoint must include a complete, runnable example with imports and expected output in a comment. When adding comments in code examples, explain WHY (reasoning, constraints, non-obvious decisions), not WHAT the code already shows.
Incorrect (describes behavior without showing it):
The `createUser` function accepts a name and email, validates
the input, and returns the new user object.Correct (complete example readers can copy and run):
````markdown
import { createUser } from "@acme/sdk";
const user = await createUser({
name: "Ada Lovelace",
email: "ada@example.com",
});
// => { id: "usr_abc123", name: "Ada Lovelace", email: "ada@example.com" }````
Reference: Google Technical Writing: Code samples
Bold for UI elements, code font for technical terms
Use bold for UI elements the reader interacts with (buttons, menu items, page names, tabs). Use code font for filenames, commands, parameters, functions, and API elements. Mixing these up makes docs harder to scan.
Incorrect (no visual distinction between UI and code):
Click the Submit button and check the config.yaml file. Go to the
Settings page and update the timeout parameter.Correct (bold for UI, code font for technical terms):
Click **Submit** and check the `config.yaml` file. Go to the
**Settings** page and update the `timeout` parameter.Reference: Microsoft Style Guide: Formatting text in instructions
Use descriptive link text, never "click here"
Link text must describe the destination and make sense out of context. Screen readers list links by text alone -- "click here" and "learn more" are meaningless in a list of 20 links.
Incorrect (vague link text):
To configure authentication, [click here](auth.md).
For more information, [see this page](rate-limits.md).Correct (descriptive link text):
See [Configure authentication](auth.md) for setup steps.
Review the [rate limit thresholds](rate-limits.md) before going live.Reference: W3C: Link text and purpose
Write descriptive alt text for all images
Every image needs alt text that conveys the information the image provides. Describe what the image shows, not what it is. Empty alt text or generic labels like "screenshot" leave screen reader users with no context.
Incorrect (missing or generic alt text):

Correct (alt text describes the content):

Reference: W3C: Alt text decision tree
Use lowercase hyphenated filenames for all assets
Lowercase filenames with hyphens avoid case-sensitivity bugs across operating systems. macOS and Windows are case-insensitive by default; Linux is case-sensitive. Mixed conventions cause broken links that only surface in deployment.
Incorrect (mixed case, underscores, or spaces):
Getting_Started_Guide.md
SetupInstructions.md
API Reference.mdCorrect (lowercase with hyphens):
getting-started.md
setup-instructions.md
api-reference.mdReference: Google developer documentation style guide: Filenames
Keep list items parallel in structure
Every item in a list must follow the same grammatical pattern. If one item starts with a verb, all items start with verbs; if one is a noun phrase, all are noun phrases -- mixed structures force the reader to re-parse each item.
Incorrect (mixed grammatical patterns):
- Configure the database
- Authentication setup
- You need to deploy the application
- MonitoringCorrect (all items start with imperative verbs):
- Configure the database
- Set up authentication
- Deploy the application
- Enable monitoringReference: Google developer documentation style guide: Lists
Periods and commas go inside quotation marks
Follow US English conventions: place periods and commas inside closing quotation marks. Place colons and semicolons outside. For code strings where punctuation accuracy matters, use code font instead of quotation marks to avoid ambiguity.
Incorrect (period outside closing quote):
The status shows "active". Set the mode to "production",
then restart the service.Correct (period and comma inside closing quote):
The status shows "active." Set the mode to "production,"
then restart the service.Reference: Microsoft Style Guide: Quotation marks
Use semantic HTML for content structure
Use the correct HTML element for the content type: headings for sections, lists for groups, tables for tabular data, <code> for inline code. Generic <div> and <span> elements carry no meaning for screen readers or search engines.
Incorrect (divs used for structure):
<div class="heading">Prerequisites</div>
<div class="list-item">Node.js 18+</div>
<div class="list-item">PostgreSQL 15+</div>Correct (semantic elements match content type):
<h2>Prerequisites</h2>
<ul>
<li>Node.js 18+</li>
<li>PostgreSQL 15+</li>
</ul>Reference: MDN: Semantics
Use sentence case for headings and titles
Capitalize only the first word and proper nouns in headings. Sentence case is easier to read and maintain than title case -- there's no ambiguity about which words to capitalize.
Incorrect (title case capitalizes every major word):
## Configure Your Application Settings
## Getting Started With the API GatewayCorrect (sentence case capitalizes only first word and proper nouns):
## Configure your application settings
## Getting started with the API GatewayReference: Google developer documentation style guide: Capitalization
Delete outdated docs, don't leave them to rot
Outdated documentation is worse than no documentation -- it actively misleads. Delete docs for removed features. Update docs when behavior changes. If historical context is needed, use a collapsed <details> section rather than leaving stale content inline.
Incorrect (doc for a removed feature still in navigation):
## XML export
Use the `/export/xml` endpoint to generate an XML report.
<!-- This endpoint was removed in v3.0 -->Correct (doc deleted, migration note added where needed):
<!-- xml-export.md deleted -->
<!-- All links updated to point to the JSON export doc -->
## JSON export
Use the `/export/json` endpoint. XML export was removed in v3.0.
For migration details, see [v3.0 changelog](changelog.md#v30).Reference: Google developer documentation: Maintaining documentation
All documentation lives in the docs/ directory
Documentation scattered across the repo is undiscoverable. Keep all docs in docs/ (or the project's equivalent). READMEs in subdirectories are the exception -- they describe that specific directory.
Incorrect (docs scattered across the repo):
wiki/setup.md
notes/architecture.md
guides/deployment.md
src/utils/HOWTO.mdCorrect (all docs in one directory with subdirectories by type):
docs/tutorials/getting-started.md
docs/reference/api.md
docs/howto/deploy-to-production.md
README.md
src/utils/README.mdReference: Diataxis: Documentation system
Mark experimental features with a visible note
If a feature is experimental or in preview, add a callout immediately after the intro paragraph. Readers must know before they invest time building on an unstable API or feature.
Incorrect (experimental feature documented without any warning):
## Batch processing endpoint
Send up to 1000 items in a single request using the
`/api/batch` endpoint.Correct (clear experimental callout before details):
## Batch processing endpoint
Send up to 1000 items in a single request using the
`/api/batch` endpoint.
> **Note:** This feature is in preview and may change without
> notice. Do not use in production.Reference: Google developer documentation: Deprecation and experimental notices
No status reports, meeting notes, or dated plans in docs
Documentation must be evergreen. Status reports, test results, meeting notes, and plans with dates belong in issues, PRs, or project management tools -- not in docs that readers expect to be current.
Incorrect (temporal content mixed into docs):
## Migration status
As of Q3 2025, the team is migrating to the new API. The
remaining endpoints will be ported by end of sprint 14.Correct (evergreen content with links to tracking):
## Migrate to v2
The v2 API replaces the v1 API. For migration steps, see
[Migrate to v2](migrate-v2.md). Track migration progress in
[issue #482](https://github.com/example/repo/issues/482).Reference: Google developer documentation: Timeless documentation
Mark planned docs with [PLANNED] markers
Document-driven development sometimes means writing docs before code exists. Mark all planned or unimplemented content with [PLANNED] so readers don't mistake it for current behavior. Remove markers once the feature is implemented.
Incorrect (planned feature documented as if it exists):
## Batch processing endpoint
Send up to 1000 items in a single request using the
`/api/batch` endpoint.Correct (clearly marked as planned with tracking link):
## [PLANNED] Batch processing endpoint
This endpoint will support batch operations for up to 1000
items per request. Implementation is tracked in
[#1234](https://github.com/example/repo/issues/1234).Reference: Write the Docs: Document-driven development
Include last-updated date or version
Readers need to know if docs are current. Include a "Last updated" date or the product version the doc applies to. This helps readers assess whether the information is still accurate before they invest time.
Incorrect (no indication of freshness):
## Configure authentication
Set the `AUTH_PROVIDER` environment variable to your identity
provider's URL.Correct (version or date signals freshness):
---
last_updated: 2026-01-15
applies_to: v3.2+
---
## Configure authentication
Set the `AUTH_PROVIDER` environment variable to your identity
provider's URL.Reference: Microsoft Style Guide: Content freshness
Establish page location with an opening link or breadcrumb
Readers arrive at docs pages from search, deep links, and bookmarks -- not always from the top. Each page must help readers understand where they are in the docs hierarchy without requiring them to navigate there manually.
Incorrect (no indication of section or hierarchy):
# Token rotation
Rotate tokens every 90 days to reduce the impact of leaked
credentials...Correct (opening sentence establishes context):
# Token rotation
This guide is part of the [Authentication](index.md) series.
Rotate tokens every 90 days to reduce the impact of leaked
credentials. For initial token setup, see
[Create API tokens](create-tokens.md).Reference: Nielsen Norman Group: Breadcrumbs
Link to existing docs instead of re-explaining
If a concept is already explained in another document, link to it. Don't re-explain it. Duplicate explanations drift apart over time -- one gets updated while the other goes stale, and readers can't tell which is authoritative.
Incorrect (re-explains webhook setup in every guide):
## Send notifications
To configure webhooks, create a JSON payload with the event type,
target URL, and authentication header. Set the retry policy to
exponential backoff with a maximum of 5 attempts...Correct (links to the canonical explanation):
## Send notifications
Configure a webhook to receive event callbacks. For setup
details, see [Configure webhooks](../reference/webhooks.md).Reference: Diataxis: Reference documentation
Every doc must be linked from at least one other doc
An unlinked document is an undiscoverable document. Every file in the docs directory must be reachable from at least one other file -- typically through an index, sidebar, or parent page. Orphaned pages accumulate and rot.
Incorrect (new page with no inbound links):
<!-- advanced-config.md exists but no other page links to it -->
# Advanced configuration
These settings control cluster behavior...Correct (parent page links to the new page):
<!-- In getting-started.md -->
For cluster tuning options, see [Advanced configuration](advanced-config.md).Reference: Google developer documentation style guide: Links
Layer content depth with links for different skill levels
Provide a summary for quick readers and link to deeper explanations for those who need them. Experienced readers skip the links; beginners click through. This keeps pages focused without leaving anyone behind.
Incorrect (either too shallow or too deep):
## Authentication
Use API keys.## Authentication
API keys are cryptographic strings that identify the calling
application. They use HMAC-SHA256 to sign requests. The key
derivation function applies PBKDF2 with 100,000 iterations...Correct (summary with link to deeper content):
## Authentication
Requests are authenticated with API keys passed in the
`Authorization` header. For details on key rotation and
scoping, see [API key management](api-keys.md).Reference: Nielsen Norman Group: Progressive disclosure
Use relative paths for internal doc links
Use relative paths for links between documentation files. Absolute paths break when docs are hosted at different base URLs or built into subfolders.
Incorrect (absolute path with vague link text):
See [here](/docs/reference/api.md) for more info.Correct (relative path with descriptive context):
See [API authentication methods](../reference/api.md#authentication) for token setup.Reference: MDN: Absolute vs. relative URLs
Write headings that match what readers search for
Use the words readers actually type when looking for this information. Include the feature name or action in the heading so the heading also describes what the section contains. Generic headings like "Common issues" or "More info" don't match any search query and force readers to scan the body to determine relevance.
Incorrect (generic headings):
## Common issues
## More information
## OverviewCorrect (specific, searchable headings):
## Troubleshoot authentication errors
## Configure rate limits
## Deploy to productionReference: Google developer documentation style guide: Headings
Review defaults
Apply these checks before publishing any documentation:
- Test with a fresh reader -- have someone unfamiliar with the feature follow the doc from scratch and note where they get stuck
- Read aloud and cut anything that makes you stumble -- aim to remove 20% of the words on each editing pass
- Verify docs match the current implementation -- run every code example, check parameter names, and confirm default values against the actual software
Incorrect (unreviewed first draft with stale content):
In order to be able to configure the application, you will
need to first make sure that you have created a configuration
file. Run the CLI with the `--verbose` flag to enable logging.Correct (edited, verified, and reader-tested):
Create a configuration file in the project root.
Run the CLI with the `--debug` flag to enable logging.Reference: Write the Docs: Documentation review guide
Target Flesch-Kincaid grade 8-10 for general audiences
Use readability tools (Hemingway Editor, Flesch-Kincaid calculators) to check grade level. Grade 8-10 works for most technical audiences. Developer docs aimed at experts can go higher, but clarity always wins over complexity.
Incorrect (grade 16 -- academic paper level):
The implementation necessitates the utilization of
authentication mechanisms that facilitate the verification of
user credentials prior to the authorization of resource access
within the system's operational parameters.Correct (grade 9 -- clear and accessible):
The system checks user credentials before granting access to
resources. Set up authentication using one of the supported
providers listed below.Reference: Hemingway Editor: Readability tool
Verify all links point to valid destinations
Broken links destroy trust. After any doc change, verify that all outbound links still resolve. Check both internal doc links and external URLs. Automate this check in CI when possible.
Incorrect (renamed doc without updating inbound links):
For setup instructions, see [Getting started](setup.md).
<!-- setup.md was renamed to getting-started.md -->Correct (links verified after every rename or restructure):
For setup instructions, see
[Getting started](getting-started.md).
<!-- CI runs markdown-link-check on every PR -->Reference: markdown-link-check: Link validation tool
Scanability defaults
Apply these defaults to every documentation page:
- Front-load key information -- lead sentences and sections with the main point, push caveats to the end
- Use white space between logical groups -- add blank lines between conceptual groups, keep paragraphs to 3-5 sentences
- Replace prose with diagrams and tables where possible -- use diagrams for flows, tables for comparisons
- Mix short and long sentences for rhythm -- alternate punchy sentences (5-10 words) with explanatory ones (15-25 words)
Incorrect (buries the answer, no grouping, uniform sentences, prose where a table fits):
While there are several options, and depending on your needs,
you might want to consider the trade-offs. Option A is fast.
Option B is cheap. Option C is reliable. After evaluating the
options, the recommended approach is Option B.Correct (leads with the answer, grouped content, varied rhythm, table for comparison):
Use Option B for most deployments.
| Option | Speed | Cost | Reliability |
|--------|-------|------|-------------|
| A | Fast | High | Medium |
| B | Medium| Low | High |
| C | Slow | Low | High |Use three-column layout for API reference docs
API reference docs work best with three columns: navigation (left), description (center), and code examples (right). This lets developers read the explanation and see the code simultaneously without scrolling.
Incorrect (code blocks inline below each description):
## Create a user
Creates a new user account with the specified parameters.
### Request
POST /api/users
### Example
curl -X POST https://api.example.com/users \
-d '{"name": "Ada"}'Correct (description and code columns visually adjacent):
<!-- Three-column layout: nav | description | code -->
| Description | Example |
|--------------------------------------|--------------------------------------|
| **POST /api/users** | `curl -X POST .../users -d '{...}'` |
| Creates a new user with the | |
| specified parameters. | Response: `201 Created` |Reference: Stripe API docs: Layout pattern
Start with the bottom line
The first paragraph should tell readers what the document covers and what they'll be able to do after reading it ("bottom line up front"). State the problem and the outcome in the opening paragraph. Save backstory for later or put it in a separate explanation doc.
Incorrect (buries the purpose under background):
# Deploying to production
In the early days of our platform, deployments were done manually
using SSH. Over time, we developed an internal tool that automated
parts of the process. In version 2.3, we introduced the deploy
pipeline, which builds on lessons learned from these earlier
approaches. This guide covers the deploy pipeline.Correct (leads with the purpose and outcome):
# Deploying to production
This guide shows you how to deploy your application to production
in under 5 minutes. You'll configure the build pipeline, set
environment variables, and trigger your first deploy.
Before you begin, make sure you have the CLI installed and access
to the production project.Reference: Write the Docs: Writing style
Put conditions before instructions
State where to be, what to have, or what to check before telling the reader what to do. If the instruction comes first and the condition second, readers may act in the wrong context and have to undo it. Applies to prerequisites, UI navigation, and conditional branches.
Incorrect (instruction before condition):
Click **Save** to apply your changes on the Settings page.
Run the migration script if you're upgrading from version 2.x.
Enter your API key in the **Credentials** field, which you'll find
under **Project Settings > Integrations**.Correct (condition before instruction):
On the **Settings** page, click **Save** to apply your changes.
If you're upgrading from version 2.x, run the migration script.
Go to **Project Settings > Integrations**. In the **Credentials**
field, enter your API key.Tip: Look for the words "if," "when," "on," and "in" buried at the end of a sentence. Move them to the front.
Reference: Microsoft Writing Style Guide: Procedures and instructions
One doc type per file
Follow the Diataxis framework: each document should be exactly one type -- tutorial, how-to, reference, or explanation. Mixing types confuses readers because each type serves a different need and reading mode. When a document drifts into another type, split it into separate files and link between them.
Incorrect (mixed tutorial, reference, and explanation in one file):
# Authentication
## Getting started with auth
Follow these steps to add login to your app...
## API reference
### POST /auth/token
Parameters:
- grant_type (required): The OAuth grant type...
## How authentication works
The system uses a three-legged OAuth flow where...Correct (separate files, each one type):
<!-- tutorial-authentication.md -->
# Tutorial: Add login to your app
Follow these steps to add authentication...
<!-- reference-auth-api.md -->
# Auth API reference
### POST /auth/token
Parameters:
- grant_type (required): The OAuth grant type...
<!-- explanation-auth-architecture.md -->
# How authentication works
The system uses a three-legged OAuth flow where...Reference: Diataxis framework
Every heading needs an intro paragraph
Never follow a heading directly with a subheading, list, or code block. Add at least one sentence explaining what the section covers and why the reader should care. A single sentence is enough to orient the reader.
Incorrect (heading jumps straight to a list):
## Configuration
- `DB_HOST`: The database hostname
- `DB_PORT`: The database port
- `DB_NAME`: The database nameCorrect (heading followed by an intro sentence):
## Configuration
Configure the database connection by setting these environment
variables in your `.env` file.
- `DB_HOST`: The database hostname (default: `localhost`)
- `DB_PORT`: The database port (default: `5432`)
- `DB_NAME`: The database nameThis also applies when a heading is followed by a subheading -- add a sentence between them.
Reference: Google developer documentation style guide: Headings
Use heading levels in order
Don't skip heading levels -- go from H2 to H3 to H4 in sequence. Skipping levels breaks the logical outline, confuses screen readers, and makes the table of contents wrong. Use a single H1 for the page title and organize content under H2 sections.
Incorrect (skipped heading levels):
# Getting started
#### Prerequisites
Content here...
## Installation
#### macOS
Content here...Correct (sequential heading levels):
# Getting started
## Prerequisites
Content here...
## Installation
### macOS
Content here...
### Linux
Content here...Tip: If you find yourself reaching H5 or H6, the page probably covers too many topics. Consider splitting it into multiple documents.
Reference: Microsoft Writing Style Guide: Headings
End with next steps
End tutorials and how-to guides with a "Next steps" section linking to 2-4 related guides or logical next actions. Describe what each link helps the reader do, not just where it goes.
Incorrect (ends abruptly after the last step):
## Step 3: Verify the deployment
Run the health check endpoint to confirm the service is running:
curl https://api.example.com/health
You should see `{"status": "ok"}` in the response.Correct (ends with actionable next steps):
## Step 3: Verify the deployment
Run the health check endpoint to confirm the service is running:
curl https://api.example.com/health
You should see `{"status": "ok"}` in the response.
## Next steps
- [Configure a custom domain](custom-domains.md) to serve your
API from your own URL.
- [Set up monitoring](monitoring.md) to get alerts when the
health check fails.
- [Enable auto-scaling](auto-scaling.md) to handle traffic spikes.Reference: Diataxis: How-to guides
Numbered for sequential, bullets for non-sequential
Use numbered lists only when order matters (procedures, ranked results, dependent sequences). Use bullet lists for everything else (features, options, requirements, platforms). Numbering a non-sequential list falsely implies priority or order.
Incorrect (numbered list where order doesn't matter):
## Supported platforms
1. macOS 12 or later
2. Ubuntu 22.04 LTS
3. Windows 11
4. Debian 12
## Features
1. Automatic retries on failure
2. Built-in rate limiting
3. TLS encryption by defaultCorrect (bullets for non-sequential, numbers for sequential):
## Supported platforms
- macOS 12 or later
- Ubuntu 22.04 LTS
- Windows 11
- Debian 12
## Install the CLI
1. Download the binary for your platform.
2. Move it to a directory in your `PATH`.
3. Run `acme --version` to verify the installation.Reference: Google developer documentation style guide: Lists
One topic per section
Each section should advance one concept, feature, or step. Splitting keeps sections focused, scannable, and individually linkable. Test: if you can't summarize a section in one sentence, it covers too much.
Incorrect (two topics merged into one section):
## Authentication
To set up authentication, create an API key in the dashboard and
add it to your configuration file:
AUTH_KEY=your-key-here
If authentication fails, check these common issues:
- Expired API key: Generate a new key in the dashboard.
- Clock skew: Ensure your server time is within 5 minutes of UTC.
- IP allowlist: Verify your server IP is on the allowlist.Correct (each topic in its own section):
## Set up authentication
Create an API key in the dashboard and add it to your configuration
file:
AUTH_KEY=your-key-here
## Troubleshoot authentication errors
If authentication fails, check these common issues:
- **Expired API key**: Generate a new key in the dashboard.
- **Clock skew**: Ensure your server time is within 5 minutes of UTC.
- **IP allowlist**: Verify your server IP is on the allowlist.Reference: Write the Docs: Content organization
Write steps with imperative verbs
Start each step with an imperative verb (open, run, click, set, copy) and number sequential steps. Keep each step to one action. If a step requires a sub-action, use lettered sub-steps.
Incorrect (passive, descriptive steps):
## Changing the port
1. The configuration file needs to be opened.
2. The port value should be changed to the desired number.
3. The server needs to be restarted for the new settings.Correct (imperative verbs, goal stated up front):
## Change the port
To change the port your application listens on:
1. Open `config/server.yaml` in a text editor.
2. Set the `port` value to the desired number, for example `8080`.
3. Save the file and restart the server:systemctl restart myapp
Reference: Google developer documentation style guide: Procedures
Include a quick start for getting-started docs
Every getting-started or README document should include a minimal Quick Start section (3-5 steps) early in the document, before detailed explanations. Readers arrive with high motivation and low patience -- let them see results immediately and link to the full guide for more context.
Incorrect (buries the first command under background sections):
# Getting started
## Overview
Acme CLI is a tool for managing cloud deployments...
## Architecture
The CLI communicates with the Acme API using...
(six more sections before the first command)Correct (Quick Start gets the reader to "Hello World" fast):
# Getting started
## Quick start
1. Install the CLI:brew install acme-cli
2. Log in to your account:acme login
3. Deploy the starter template:acme deploy --template hello-world
Your app is live at the URL shown in the output. For detailed
setup options, see [Configuration](configuration.md).Voice defaults checklist
Claude follows these by default. This checklist codifies them as the project standard:
- [ ] Active voice, present tense -- put the actor before the action. Use passive only when the actor is unknown.
- [ ] Contractions -- use common contractions (don't, it's, you'll). Avoid unusual ones (mightn't, shan't).
- [ ] Second person -- address the reader as "you." Reserve "the user" for someone other than the reader.
- [ ] Professional, not promotional -- replace superlatives with measurable facts. No marketing hype.
- [ ] Reader-centric framing -- lead with what the reader can accomplish, not what the product does.
Incorrect (passive, formal, promotional, product-centric):
The configuration will be created by the system when the application
is started. It is not necessary for the user to redeploy. Our
blazing-fast platform supports parallel execution of up to 16 tasks.Correct (active, natural, reader-focused):
The system creates a configuration file when the application starts.
You don't need to redeploy. Run up to 16 tasks in parallel to finish
builds faster.Reference: Google developer documentation style guide
Don't give software human qualities
Software doesn't think, want, know, try, remember, or decide. Anthropomorphic language is imprecise and can mislead readers about what the system actually does. Use precise technical verbs instead: returns, sends, rejects, creates, deletes, validates, stores, triggers.
Incorrect (anthropomorphic language):
The server thinks the request is invalid and tries to recover
gracefully. The scheduler knows when to run the next job and wants
to keep the queue balanced. The load balancer prefers healthy nodes
and remembers which ones failed recently.Correct (precise technical verbs):
The server rejects the request and returns a 400 error with a
validation message. The scheduler checks the cron expression to
determine the next run time and distributes jobs across the queue.
The load balancer routes traffic to healthy nodes and skips nodes
that failed a health check in the last 60 seconds.Reference: Google developer documentation style guide: Anthropomorphism
Avoid jargon or define it on first use
If a technical term is necessary, spell it out and define it the first time it appears. After the first definition, use the short form freely. Don't stack multiple undefined terms in a single sentence; each unknown term compounds the reader's confusion.
Incorrect (undefined acronyms and stacked jargon):
Enable the RBAC module to configure ACLs for your tenants. The
IdP handles SSO federation, so make sure the SAML assertions
include the correct NameID format.Correct (terms defined on first use):
Enable the role-based access control (RBAC) module to configure
access control lists (ACLs), rules that define which users can
access which resources, for your tenants.
The identity provider (IdP) handles single sign-on (SSO) federation.
Make sure the SAML assertions include the correct NameID format.
See the [SAML reference](saml-reference.md) for supported formats.Reference: Google developer documentation style guide: Jargon
Use must, not should, for requirements
"Should" is ambiguous -- readers can't tell whether it's a requirement or a suggestion. Use "must" for mandatory behavior and "we recommend" for suggestions, per RFC 2119. Avoid "please" in requirements -- it softens mandatory instructions and implies the reader has a choice.
Incorrect (ambiguous "should" and "please"):
You should set the API key before making requests. The timeout
value should be at least 30 seconds. Please ensure the configuration
file has the correct permissions. You should back up the database
before upgrading.Correct (clear distinction between requirements and suggestions):
You must set the API key before making requests. We recommend
setting the timeout to at least 30 seconds for reliable performance.
The configuration file must have `600` permissions. Back up the
database before upgrading.Reference: RFC 2119: Key words for use in RFCs
Related skills
How it compares
Choose docs-writing when auditing or improving existing technical docs with Diataxis structure rather than generating marketing copy or agent configuration files.
FAQ
What documentation framework does docs-writing use?
docs-writing applies the Diataxis framework to classify content as tutorials, how-to guides, reference, or explanation. The skill also enforces Stripe-style clarity across 52 rules in 9 categories covering voice, structure, code examples, and navigation.
How many documentation rules does docs-writing include?
docs-writing bundles 52 rules across 9 categories covering voice, structure, clarity, code examples, formatting, navigation, scanability, content hygiene, and review. Developers use it when writing or auditing READMEs, API docs, and tutorials.
When should developers use docs-writing instead of readme-creator?
docs-writing handles writing and auditing existing technical documentation, API references, and tutorials. For generating a README from scratch, the skill routes developers to readme-creator; for AGENTS.md or CLAUDE.md files, use agents-md.