Style Guides skill for Claude Code
One voice and one term list, enforced in CI. Claude builds style guides people use. It audits existing docs for conflicting terms, inherits a published base guide and records only your overrides, defines voice traits with do and don't examples from your product, writes the terminology table that fixes most inconsistency, and encodes the enforceable rules as Vale styles and vocabularies rolled out gradually in CI.
- name
style-guides - size188 lines · ≈1,900 tokens
- files2
- licenseMIT
- updated
What Claude sees before loading it
This description is the only part of the skill that sits in context all the time. Claude reads it to decide when to load the full playbook below.
description: Creates writing style guides for documentation, product UI copy, and developer content - deciding which base guide to inherit, defining voice and tone by context, a terminology list with preferred and banned terms, grammar and formatting rules with do and don't examples, accessibility and inclusive language, and enforcement with Vale rules and vocabularies in CI. Use when a team needs a docs or content style guide, when terminology is inconsistent across docs and UI, when onboarding writers or engineers who write docs, or when setting up Vale or another prose linter. Try asking
- Create a style guide for our developer docs and set up Vale to enforce it
- Our docs say login, log in, and sign in interchangeably. Fix terminology everywhere
- Define voice and tone for our product with examples for errors, tutorials, and release notes
Use it when
- A team needs a documentation or content style guide
- Terminology is inconsistent across docs, UI, and help content
- Setting up Vale or another prose linter in CI
- Onboarding engineers or writers who contribute docs
Skip it when
- You want one draft edited for clarity — use prose-editing
- You are writing specific UI strings rather than rules for them — use ux-microcopy
How to check the result
Run Vale on the full docs tree and confirm error-level terminology rules report zero alerts, and that a sample of new pull requests gets useful, low-noise comments.
The common mistake it prevents
Turning on every linter rule at error level across the whole corpus on day one, which floods pull requests until someone disables the linter.
A style guide works when writers can answer a style question in under a minute, the rules that matter most are enforced by a linter in CI, and inconsistency in the published docs actually goes down. A 60-page guide that nobody opens and nothing enforces is a style essay.
Ground rules
- Inherit a published base guide (Google developer documentation style, Microsoft Writing Style Guide, or similar) and document only your differences and additions.
- Every rule gets a do and a don’t example from your own product. Rules without examples get interpreted five ways.
- Terminology is the highest-value section. Most real inconsistency is “sign in” vs “log in”, “workspace” vs “team”, product names capitalized three ways.
- Enforce mechanically what can be enforced (terms, banned words, capitalization, punctuation patterns); leave judgment calls (tone, structure) to review.
- Keep the guide short enough to read in 15 minutes; put the long term list in its own file.
Workflow
- [ ] 1. Audit existing content for inconsistencies
- [ ] 2. Choose the base guide and scope (docs, UI, marketing, API reference)
- [ ] 3. Define voice and tone by context
- [ ] 4. Build the terminology list
- [ ] 5. Write grammar, formatting, and mechanics rules with examples
- [ ] 6. Add accessibility and inclusive language rules
- [ ] 7. Encode rules in Vale; run on existing content; tune false positives
- [ ] 8. Publish, add CI, define ownership and change process
1. Audit
Sample 20-30 pages across docs, UI strings, and help content. Record conflicts:
# term variants across docs, counts per variant
grep -rhoiE "\b(log ?in|sign ?in|login|signin)\b" docs/ | sort | uniq -c | sort -rn
grep -rhoE "\b[Ww]ork[Ss]pace\b|\bTeam [Ss]pace\b" docs/ | sort | uniq -c
The audit output becomes the first terminology entries and shows where the guide will pay off.
2. Base and scope
| Decision | Options |
|---|---|
| Base guide | Google developer docs style (common for dev docs), Microsoft Writing Style Guide (common for product and UI), Chicago or AP for marketing/editorial |
| Scope | Which content types it governs; UI copy may need its own section or guide (see ux-microcopy) |
| Spelling locale | US or UK English, one choice, enforced by linter |
| Overrides | List each place you deviate from the base, with a reason |
3. Voice and tone
Voice is constant; tone shifts by context. Define voice in 3-4 traits, each with what it is and is not:
| Trait | We are | We are not |
|---|---|---|
| Direct | “Run acme deploy.” | “You may wish to consider running the deploy command.” |
| Plainspoken | “This deletes the project.” | “This action will result in the removal of the project resource.” |
| Calm in errors | “We couldn’t save your changes. Try again.” | “Oops! Something went terribly wrong!!” |
Tone map by context: tutorials (encouraging, step-focused), reference (neutral, terse), errors (calm, specific, actionable), release notes (factual), marketing (confident without superlatives).
4. Terminology list
Keep it in a table (or YAML that also feeds the linter):
| Use | Don't use | Notes |
|---|---|---|
| sign in (verb), sign-in (noun/adj) | log in, login, signin | Matches the UI button |
| workspace | team space, org (in UI) | "Organization" only for billing entities |
| Acme CLI | acme-cli, the Acme command line | First mention: "the Acme CLI (`acme`)" |
| select | click, hit | Device-neutral |
| allowlist / denylist | whitelist / blacklist | Inclusive language |
| email | e-mail | |
Include product names with exact capitalization, feature names, UI labels (bold, match the screen exactly), and words with a specific local meaning.
5. Grammar, formatting, mechanics
Decide and show examples for each of these; inherit the rest from the base guide:
| Topic | Typical decision |
|---|---|
| Person and mood | Second person (“you”), imperative for steps |
| Headings | Sentence case; task headings start with a verb (“Create a project”) |
| Lists | Parallel structure; numbered only for sequences |
| UI elements | Bold the exact label: Select Save. |
| Code | Inline code for commands, file names, parameters, values; fenced blocks with language tags |
| Placeholders | <PROJECT_ID> or PROJECT_ID in italics; pick one and explain it on first use |
| Numbers and units | Numerals for 10+, always for units (“5 GB”); space between number and unit |
| Dates and times | ISO in reference docs; spelled month in prose (“March 4, 2026”); time zones explicit |
| Oxford comma | Yes or no; enforce it |
| Contractions | Allowed in UI and tutorials; decide for reference |
| Links | Descriptive link text, never “click here” |
| Abbreviations | Spell out on first use unless universal (API, URL) |
6. Accessibility and inclusive language
- Alt text for every informative image; describe the purpose, not the pixels.
- No directional or sensory-only instructions (“the button on the right”, “the green icon”); name the element.
- Plain language: short sentences, common words, define jargon on first use.
- Inclusive terms: allowlist/denylist, primary/replica, “they” for unknown people, avoid idioms that do not translate.
- Do not use ableist metaphors (“sanity check” -> “quick check”, “crippled” -> “limited”).
7. Enforce with Vale
Vale checks prose against rules written in YAML. Minimal setup:
# .vale.ini
StylesPath = .github/styles
MinAlertLevel = suggestion
Vocab = Acme
Packages = Google
[*.{md,mdx}]
BasedOnStyles = Vale, Google, Acme
Google.Headings = NO # we use our own heading rule
vale sync # downloads packages listed in Packages
vale docs/ # lint
vale --output=JSON docs/ > vale.json
For the full layout (vocabulary accept/reject files, a terminology substitution rule, an existence rule for banned words, inline disabling, CI with reviewdog, and how to roll out on a large existing corpus), read references/vale-setup.md when setting up or tuning the linter.
Rollout: run on all existing content, fix or suppress the noisy rules, start CI at warning level on changed files only, then raise key rules to error.
8. Publish and govern
- Publish the guide in the docs repo (or docs site) with a search-friendly table of contents: Voice, Terminology, Formatting, Accessibility, Linting.
- Owner: a named person or team approves changes; changes go through pull requests with a reason and an example.
- Add a “Quick reference” card: the 10 rules people break most, with examples.
- Review the term list quarterly against new features and support tickets.
Gotchas
- Copying an entire external style guide into your repo makes it unreadable; link to it and keep only overrides.
- Linting everything at error level on day one floods pull requests and gets the linter disabled. Ramp up.
- Vocabulary accept lists also suppress spelling errors for those words everywhere; keep them tight and case-correct.
- UI labels change; the docs must match the shipped UI, so tie terminology changes to UI string changes.
- Style debates without examples go in circles. Decide with a real sentence from your docs.
Output contract
docs/style-guide/
README.md # voice, tone map, quick reference (10 rules)
terminology.md # use / don't use / notes
formatting.md # grammar and mechanics overrides with examples
accessibility.md
.vale.ini
.github/styles/Acme/*.yml
.github/styles/config/vocabularies/Acme/{accept,reject}.txt
CI: Vale on changed files, level <warning/error>; owner <team> Bundled files
Loaded only when a step in the skill needs them. Review them here before installing.
references/vale-setup.md
# Vale setup for a team style guide
Read this when installing Vale, encoding the terminology list as rules, or rolling the
linter out on an existing docs corpus. Paths assume Vale 3.x, where vocabularies live
under `<StylesPath>/config/vocabularies/`. Check `vale --version` and the Vale docs if
your version differs.
## Layout
```
.vale.ini
.github/styles/
Acme/ # your custom style (folder name = style name)
Terms.yml
Banned.yml
Headings.yml
config/
vocabularies/
Acme/
accept.txt # words Vale must accept (product names, jargon)
reject.txt # words that are always errors
Google/ # downloaded by `vale sync`, do not edit; add to .gitignore if you prefer
```
## .vale.ini
```ini
StylesPath = .github/styles
MinAlertLevel = suggestion
Vocab = Acme
Packages = Google
[*.{md,mdx}]
BasedOnStyles = Vale, Google, Acme
# turn off base rules that conflict with your guide
Google.Headings = NO
Google.WordList = NO
# change severity of a base rule
Google.Passive = suggestion
[CHANGELOG.md]
BasedOnStyles = Vale
```
Run `vale ls-config` to see the resolved configuration when rules do not apply as
expected.
## Vocabulary
`accept.txt` (one entry per line; regular expressions allowed; case-sensitive by default):
```
Acme
Kubernetes
PgBouncer
(?i)webhook
```
`reject.txt`:
```
whitelist
blacklist
```
Accepted terms are exempt from spelling checks and enforced with the listed
capitalization by Vale's built-in terms rule.
## Terminology rule (substitution)
`.github/styles/Acme/Terms.yml`:
```yaml
extends: substitution
message: "Use '%s' instead of '%s'."
link: https://docs.acme.example/style-guide/terminology
level: error
ignorecase: true
swap:
log in: sign in
login: sign in
e-mail: email
team space: workspace
click: select
```
The first `%s` is the replacement, the second is the matched text. Keep the swap map in
sync with `terminology.md`; generating one from the other with a small script avoids
drift.
## Banned words (existence)
`.github/styles/Acme/Banned.yml`:
```yaml
extends: existence
message: "Avoid '%s'; say what happens instead."
level: warning
ignorecase: true
tokens:
- simply
- just
- easy
- obviously
- please note
```
## Heading case (capitalization)
`.github/styles/Acme/Headings.yml`:
```yaml
extends: capitalization
message: "Use sentence case for headings: '%s'."
level: warning
scope: heading
match: $sentence
exceptions:
- Acme
- CLI
- API
```
## Inline exceptions in Markdown
```markdown
<!-- vale off -->
Text Vale ignores, such as a quoted error message.
<!-- vale on -->
<!-- vale Acme.Terms = NO -->
Login is the literal field name in the legacy API.
<!-- vale Acme.Terms = YES -->
```
Use inline exceptions sparingly and with a reason; a page full of them means the rule is
wrong.
## CI
GitHub Actions with reviewdog comments on changed lines:
```yaml
name: docs-lint
on: pull_request
jobs:
vale:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: errata-ai/vale-action@reviewdog
with:
files: docs
fail_on_error: true
filter_mode: added # only lines changed in the PR
```
Check the action's README for current input names before relying on them. Any CI system
can instead install the Vale binary and run `vale --minAlertLevel=error docs/`, which
exits non-zero when errors are found.
## Rolling out on an existing corpus
1. Run `vale --output=JSON docs/ > baseline.json` and count alerts per rule:
`jq -r '.[][] | .Check' baseline.json | sort | uniq -c | sort -rn`.
2. For the noisiest rules decide: fix the content (scripted replacements for terms),
lower severity, or disable the rule.
3. Enable CI on changed lines only at warning level for two to four weeks.
4. Promote terminology and banned-word rules to error once the backlog is fixed.
5. Re-run the baseline count monthly; it should trend to zero for error-level rules.
About this skill
Written and maintained by the Claude Skills editors to the same editorial standard as every skill in the directory: a selective trigger, a real workflow, known pitfalls and a verification step. First published , last updated . MIT licensed.