Extension Points Overview
Vale supports the following extension points:- existence: Check for the presence of specific words or patterns
- substitution: Suggest replacements for matched text
- occurrence: Enforce min/max limits on pattern occurrences
- repetition: Detect repeated words or phrases
- consistency: Ensure consistent usage between alternatives
- conditional: Enforce that one pattern implies another
- capitalization: Check capitalization styles
- readability: Calculate readability scores
- spelling: Check spelling with custom dictionaries
- sequence: Ensure ordered patterns
- metric: Calculate custom text metrics
- script: Execute Tengo scripts for complex logic
Rule Anatomy
Every Vale rule is a YAML file with required and optional keys:Required Keys
- extends: The extension point (one of the 12 types above)
- message: The alert message (use
%sfor the matched text) - level:
error,warning, orsuggestion
Common Optional Keys
- scope: Where to apply the rule (e.g.,
text,heading,paragraph.text) - link: URL to documentation about the rule
- action: Automated fix configuration
- exceptions: Array of patterns to ignore
All rules must have the
.yml extension and follow the naming convention StyleName/RuleName.ymlWriting an Existence Rule
Theexistence extension point checks for the presence of tokens. It’s the most common rule type.
Configure the pattern matching
The Use
existence extension compiles your tokens into a regex pattern. By default, it uses word boundaries:nonword: true to remove word boundaries:Vale uses the
regexp2 library which supports advanced regex features like lookarounds and backreferences.Writing a Substitution Rule
Thesubstitution extension suggests replacements for matched patterns.
styles/MyStyle/Abbreviations.yml
swap are regex patterns, and the values are the suggested replacements.
Multiple Suggestions
Provide multiple alternatives using the pipe character:Case Preservation
Usecapitalize: true to preserve the case of the original text:
Writing an Occurrence Rule
Theoccurrence extension enforces min/max limits on pattern matches.
styles/MyStyle/SentenceLength.yml
How occurrence counting works
How occurrence counting works
The
occurrence rule counts all matches of the token pattern within the specified scope. If the count is outside the min/max range, it triggers an alert.- Use
maxto set an upper limit - Use
minto set a lower limit - Use both for a range
Writing a Repetition Rule
Therepetition extension detects repeated tokens.
styles/MyStyle/Repetition.yml
- alpha: Only check alphabetic tokens (ignores numbers)
- max: Maximum allowed repetitions (default: 0)
Writing a Conditional Rule
Theconditional extension ensures that the presence of one pattern implies another.
styles/MyStyle/Acronyms.yml
Writing a Capitalization Rule
Thecapitalization extension checks capitalization styles.
styles/MyStyle/Headings.yml
Built-in Styles
- $title: Title case (AP or Chicago style)
- $sentence: Sentence case
- $lower: All lowercase
- $upper: All uppercase
- Custom regex pattern
Adding Actions for Automatic Fixes
Actions enable Vale to suggest automatic fixes.Replace Action
Edit Action
Theedit action modifies the matched text:
truncate: Remove text after a delimitertrim,trim_left,trim_right: Remove charactersregex: Apply regex replacementsplit: Split and take specific part
Remove Action
Using Scopes
Scopes control where rules apply. Vale has a hierarchical scope system:Writing a Script Rule
For complex logic, use thescript extension with Tengo:
styles/MyStyle/SectionLength.yml
Scripts have access to the
text, fmt, and math standard library modules. The os module is disabled for security.Testing Your Rules
Use Vale’s CLI commands to test rules:Best Practices
- Start simple: Begin with
existencerules before moving to complex patterns - Use exceptions liberally: Prevent false positives with the
exceptionskey - Test thoroughly: Run rules against representative documents
- Provide clear messages: Use
%splaceholders to show matched text - Add links: Include documentation URLs for context
- Scope appropriately: Use scopes to avoid checking markup
- Use word boundaries: Set
nonword: false(default) for most word-based checks - Leverage vocab: Set
vocab: trueto respect project vocabularies
Next Steps
Custom Styles
Learn how to organize rules into reusable style packages
Rule Reference
Explore detailed documentation for each extension point