Skip to content

Playbooks

Write a playbook when a team must build the same kind of thing more than once, and the hard part is the decisions, not the typing. A playbook is an actionable blueprint for one pattern. It records the build order, the constraints, and the traps. It isn’t a tutorial, and it isn’t a reference.

This playbook is the source standard for every playbook on this site. The one rule: give the reader the decisions and the traps, and prove each one with evidence.

A playbook answers eight questions for one pattern:

  • What does the reader have when they finish?
  • Which concepts and invariants does every step depend on?
  • When is this pattern the right tool, and when is it the wrong one?
  • What are the parts?
  • In what order does the reader build them?
  • Which mistakes look correct but fail later?
  • How does the reader prove that it works?
  • Which evidence supports each claim?

The reader is a capable developer or an agent. The reader can write the code. The reader doesn’t know the non-obvious decisions. The playbook supplies those decisions.

Write a playbook when two or more of these conditions are true:

  • The team built this pattern at least once, and will build it again.
  • The first build found traps that a second build will hit again.
  • The correct build order isn’t obvious.
  • An agent must follow the pattern without a human in the loop.
  • A technology has security, release, or platform rules that a team must apply on every project.

Don’t write a playbook for these cases:

  • A pattern with no evidence. Build it once, or find the primary documentation, then write it down. A playbook from memory or theory has the wrong traps.
  • A step-by-step tutorial for one product. Put it under guide/.
  • A list of flags, fields, or endpoints. Put it under reference/.
  • A rule that a script can check. Write the script instead.

Write the parts in this order.

PartRequiredPurpose
FrontmatterYesThe title, the description, and the last updated date
OpeningYesWhat the reader builds, when, the scope, and the one rule
Core modelYesThe concepts and the invariants that every step depends on
When to use itYesThe conditions for use, and the conditions against use
BaselineNoThe prerequisites, the default stack, and what to commit
PartsNoA table of every component and its purpose
Build orderYesNumbered steps, in dependency order
Minimum viable versionNoThe first release, and what waits for later
Change workflowNoThe sequence for each later change
Design rulesNoThe principles that apply across all steps
Anti-patternsYesEach mistake, its failure mode, and the accepted pattern
VerificationYesThe pass signals and the checklists
SourcesNoThe primary documents behind the claims

The required parts are the minimum viable playbook. Add an optional part when its trigger applies:

  • Baseline: the reader needs tools, accounts, or a default stack before step 1.
  • Parts: the reader builds distinct components separately.
  • Minimum viable version: the parts can ship in stages.
  • Change workflow: the team extends the result again and again, for example one feature at a time.
  • Design rules: a principle applies to more than one step.
  • Sources: the claims come from external documentation.

Also add an optional part when a reader asks the same question twice.

Base every playbook on evidence. Use one or both of these sources:

  • A real implementation: a repository, a project, or a pull request that proves the pattern.
  • Primary documentation: the official documentation for the technology.

Read the evidence before you write. Each step in the playbook must trace to it. If you have no evidence, stop. Build the pattern once, or find the primary documentation.

Every playbook starts with this frontmatter:

---
title: Feature Flags
description: How to add feature flags to a web application
lastUpdated: 2026-09-25
---

Follow these rules:

  • title: the short name of the pattern or the technology. Not “How to” and not “Playbook”.
  • description: one sentence that starts with “How to”.
  • lastUpdated: an ISO date, YYYY-MM-DD. Starlight shows it in the page footer.

Change lastUpdated on every change to the content. Don’t change it for a typo or a formatting fix. The date tells the reader how much to trust the content.

Keep one date only. Don’t write a second date in the body. Two dates can disagree, and the reader can’t tell which one is correct.

Don’t add a # heading. Starlight shows the title as the page heading.

Write one paragraph that starts with “Build a X when…”, “Write a X when…”, or “Use this playbook to…”. State what the thing is in one or two sentences.

Then write the scope:

  • The basis: the reference implementation, or the documentation.
  • The target version, when the version changes the guidance.
  • The recheck trigger, when the playbook depends on external documentation. For example: “Recheck the linked documentation before each major release.”

If one rule matters more than the rest, state it in the opening. Don’t put it at the end. A reader who stops early must still see it.

Under ## Core model, state the concepts that every step depends on. Use one or both of these forms:

  • The questions that the pattern answers, as a list.
  • The components, the boundaries between them, and the invariant for each. For example: two trust zones, and the zone that enforces security.

Keep it short. The detail goes in the steps.

Under ## When to use it, list the conditions for use as bullets. State how the conditions combine: all, any, or a threshold such as “three or more”. A threshold stops the reader from using the pattern for a weak match.

Then list the conditions against use, and name the better alternative. This is often the most useful line in the playbook.

Write these sections only when their triggers apply.

Under ## Baseline, list the prerequisites and the default stack. When the pattern has secrets or generated files, add two lists: the files to commit, and the items to never commit.

Under ## Parts, write a two-column table: the part, and its purpose. Put the required parts in the table. Put the optional parts in a list below the table, and say which problem makes each one necessary.

Under ## Build order, write numbered ### 1. Imperative title steps in dependency order. Each step does one thing. Each step opens with an instruction, not with background.

Use unnumbered #### headings for the topics inside one step. Don’t number any other heading. A number tells the reader that the order matters.

Put the decisions in the steps:

  • The ordering that matters, and why.
  • The constraint that isn’t obvious.
  • The default value, for example a port offset or a timeout.
  • The thing to never do in this step.

Use a code block, a table, or a schema only when prose can’t state the detail exactly. A config file, an interface contract, a directory tree, or one line that fixes an ordering is acceptable. A full implementation isn’t.

Write each placeholder in capital letters. Explain it below the step:

Replace the following:
- `PRODUCT`: the short name of the product family.

When a claim comes from external documentation, add a source line at the end of the section:

Source: [Content Security Policy](https://example.com/docs/csp/).

8. Add the minimum viable version and the change workflow

Section titled “8. Add the minimum viable version and the change workflow”

Write these sections only when their triggers apply.

Under ## Minimum viable version, list the three to five items to ship first, as a numbered list. Then state which parts wait for a second release, and which real problem makes them necessary.

Under ## Change workflow, write the numbered sequence for one repeated change, for example a new feature. Start at the user outcome. End at the verification of the released result.

Under ## Design rules, write the principles that apply to more than one step. Start each rule with a bold sentence. Follow it with one or two sentences of reason.

If a rule applies to only one step, move it into that step.

Under ## Anti-patterns, write a table with three columns:

| Anti-pattern | Failure mode | Accepted pattern |
|---|---|---|
| Hold a lock during I/O | Requests stall or deadlock | Copy the state, release the lock, then do the I/O |

The failure mode is mandatory. A mistake with no failure mode is only an opinion. The accepted pattern tells the reader what to do instead.

Take the anti-patterns from real failures and from warnings in the primary documentation. A good anti-pattern looks correct to a new reader. “Don’t write bad code” isn’t an anti-pattern.

A row can repeat a “never” statement from a step. The table is the index that a reviewer scans.

Under ## Verification, give the pass signal for the result. A pass signal is concrete: a command and its expected output, a log line, or a check that must pass. Never write only “test it”.

Write the checks as - [ ] checklists. Group a long checklist under #### headings by concern, for example security and reliability.

Add a separate checklist for each recurring event:

  • A review checklist, when the team changes the result through pull requests.
  • A release checklist, when the result ships releases.

Under ## Sources, list the primary documents, one link per line. The reader uses this list to recheck the playbook at the recheck trigger in the opening.

Save the file as src/content/docs/playbooks/SLUG.md. The sidebar generates the entry from the folder.

Replace the following:

  • SLUG: the kebab-case form of the title, for example feature-flags.

Link each companion playbook in the opening.

  • One pattern per playbook. Split a frontend concern and a backend concern into two linked playbooks. Each reader finds only their part.
  • Decisions, not boilerplate. The reader can write the code. Give them the choices that they would otherwise learn from a failure.
  • Name the tool, not the version. A pinned version is wrong within months, and the reader trusts it. Pin a version only when the pattern requires it, and state why. A security fix is a valid reason.
  • State the prohibitions. Write “never” lists for the most expensive mistakes, for example the items to never commit or never log. A reader follows an explicit prohibition more reliably than an implied one.
  • Cite the source next to the claim. A source line at the end of the section lets the reader recheck that one claim after a release.
  • Write in simplified technical English. Use active voice, short sentences, and one word for one meaning. Don’t use em dashes.
  • Write timelessly. Describe how the pattern works, not how it changed. The lastUpdated date records when.
  • Link, don’t copy. When another document owns a subject, link to it. Duplicated prose drifts.
Anti-patternFailure modeAccepted pattern
No lastUpdated dateThe reader can’t tell a current playbook from a stale one, so they trust neitherSet lastUpdated in the frontmatter
A lastUpdated change with no content changeThe date stops meaning anythingChange the date only when the content changes
A second date in the bodyThe two dates disagree, and the reader can’t tell which one is correctKeep one date, in the frontmatter
A # heading in the bodyThe page shows two titlesLet Starlight show the title
A playbook from memory or theoryIt documents imagined traps and misses the real onesTrace every step to a real build or to primary documentation
Full implementations in the stepsThey go stale, they cost attention, and the reader copies them instead of reading the decisionShow only the contract or the config, and name the decision
No “when not to use it”Readers apply the pattern to every problem that looks similarName the conditions against use, and the better alternative
Generic anti-patterns such as “handle errors”They teach nothing and hide the specific anti-patternsTake the anti-patterns from real failures and documentation warnings
An anti-pattern with no failure modeThe reader can’t weigh it against the cost of the fixWrite the failure mode and the accepted pattern in the table
One playbook for several patternsThe reader can’t find their part, and each update touches unrelated contentWrite one playbook per pattern, and link them
The most important rule at the endA reader who stops early never sees itState the one rule in the opening
Rationale and history at the topThe reader who must act now has to scroll past itPut the steps first and the sources last
A number on every headingThe reader can’t tell an ordered step from a topicNumber only the build order steps
A claim with no sourceThe reader can’t recheck it after a releaseAdd a source line after the section
A pinned version with no reasonIt becomes wrong, and nothing tells the readerName the tool, or state why the version matters
No pass signalThe reader can’t prove that the result worksGive a command, an expected output, or a checklist
A tutorial or a reference page filed as a playbookIt has no decisions and no traps, so it fails the purpose of the folderPut it under guide/ or reference/

A playbook is ready when every item passes:

  • The frontmatter has title, description, and lastUpdated.
  • The description starts with “How to”.
  • The body has no # heading and no second date.
  • The opening names the basis. It names the target version and the recheck trigger when they apply.
  • Every required part is present, in the order of the parts table.
  • “When to use it” states how the conditions combine, and names an alternative.
  • Only the build order steps have numbers.
  • Each anti-pattern row has a failure mode and an accepted pattern.
  • The verification section gives a concrete pass signal.
  • perl -CSD -ne 'print "$.: $_" if /[\x{2013}\x{2014}]/' FILE prints nothing. This finds en dashes and em dashes.
  • npm run build completes, and the page footer shows the last updated date.
  • An implementer can follow the playbook in their own codebase and ask no questions.