Linting…your writing

  general

“Linting” is a technique used on code to identify common issues based on accepted good practice. Linting is referred to as “static” checking, because the code isn’t run to find particular problems.

I wrote about linting in 2019 for Express and 2022 for client-side Javascript, and I’ve used linters such as ESLint (Javascript & Typescript), lintr (R) and Ruff (Python).

So I was intrigued when I came across Vale, a linter for…writing?

Before

For this blog, which I write in VS Code, I use the Code Spell Checker extension and Australian English dictionary.

From time to time I’ve used other tools such as Grammarly, Hemingway, and plain old Word. I don’t always agree with the “grammar”/readability recommendations made by those tools. My readability scores (when I bother to check) often edge up towards Year 11 or 12 levels - which seem appropriate for technical writing.

Now I can go further

Now, with Vale and the Vale VSCode extension, I have immediate, useful and controllable feedback where I write my blog posts - in VS Code.

Beyond just grammar, Vale can also be used as a writing style guide.

I adapted the installation steps over at https://www.nikhilajain.com/post/how-to-install-vale-linter-for-documentation-in-vs-code for my Jekyll blog; but I assume would work similarly on a Hugo or other markdown-based blog.

On first use, the sheer number of rules can seem overwhelming. I’d suggest focusing on rules that help readers understand your writing. Individual rules can be turned off.


  • install Vale using homebrew: brew install vale
    • or run on-demand using Docker (not covered here) - no local install required
    • while on the command line I noticed out-of-date brew packages, so updated with this handy one-liner: brew update && brew upgrade && brew upgrade --cask && brew cleanup
  • create a .vale.ini file in your blog root directory (if using Jekyll, the directory with Gemfile and _config.yml)
# subdirectory where vale styles are to be installed (must exist)
StylesPath = _vale-styles
# minimum level to report - can be set to "warning" or "error" ("suggestion" is default)
MinAlertLevel = suggestion
# styles AKA packages, named or from zip file
# not listed here - others I've tried like write-good, Microsoft
# just an example - YMMV
Packages = alex, Google, proselint

# rules for .markdown and .md files
[*.{md,markdown}]
BasedOnStyles = Vale, alex, Google, proselint
  • side note: Vale has three levels of rules - suggestion, warning and error
    • can turn off “suggestions” in .vale.ini by setting MinAlertLevel to warning (you could go further and set to error to ignore suggestions as well as warnings)
  • create a local subdirectory for Vale styles, for example _vale-styles
    • this must match the “StylesPath” in .vale.ini
  • create a config subdirectory inside _vale-styles
  • from a command prompt, run vale sync to download styles set in .vale.ini
  • now you can run Vale from the command line on an example file like:
vale example.markdown
  • since there’s some overlap between Vale, proselint and Google styles, let’s turn off a couple of unneeded rules in .vale.ini by adding to the end of the file, below the “markdown” section:
# this is a blog which will use "I" a lot
Google.FirstPerson = NO
# disable rule that expects space between number and unit
Google.Units = NO
# disable rule that suggests not using so many parentheses
Google.Parens = NO
# disable warning on using the word "will"
Google.Will = NO
# disable error for exclamation marks
Google.Exclamation = NO
# disable some rules duplicated in different styles
# disable duplicate suggestion about passive voice
Google.Passive = NO
  • now is a good time to install the VS Code extension Vale VSCode extension
    • if using VS Code extension, may need to close and re-open VS Code to pick up changes made to .vale.ini (for example, disabling rules)
  • don’t forget to update Git ignore file .gitignore to ignore downloaded Vale styles (but, don’t ignore custom config)
...
_vale-styles/*
!_vale-styles/config/

._vale-styles/config/*
!_vale-styles/config/vocabularies/

._vale-styles/config/vocabularies/*
!_vale-styles/config/vocabularies/blog
...
  • every time you add a new style/package, need to run vale sync

Next level - adding your own technical terms

  • for acronyms, best option is to fully spell the term out first like “Network Attached Storage (NAS)”, which passes rules
  • otherwise, to add custom words and terms (including accepted capitalisation), under _vale-styles/config/vocabularies/blog/accept.txt enter your words, one per line:
Unifi
  • also add the following to the top of .vale.ini to tell it about the custom vocabulary:
# use "blog" directory vocabulary
# expect directory /_vale-styles/config/vocabularies/blog
Vocab = blog
...

Now when I use the word “UniFi” or “unifi”, Vale will suggest the correct casing based on the accept.txt file.

You can check out my full .vale.ini, custom words or more at my blog’s source code at GitHub: https://github.com/thomasswilliams/thomasswilliams.github.io