Linting Documentation with Vale to Increase Quality & Consistency

Most software developers are familiar with tools to lint their source code. What if you could lint your documentation as well?

Jeroen L.
Jeroen L.
Published April 11, 2023

Most software developers are familiar with tools to lint their source code. Linting code is the process of checking your code against a defined set of rules to help keep a consistent naming convention, prevent common mistakes, and anti-patterns in other aspects of your code, provided the requirement can be expressed in configuration understood by your linting tool.

What if you could lint your documentation as well? We are all familiar with spell checking tools and you might already use, like Grammarly. But, those tools are only available in your editing environment and not a part of the normal workflows related to source code.

Documentation as code is a common recommendation for software developers. When we treat our documentation as code, we also want to run all the automated checks we run against source code on our documentation as well.

With Vale you can lint the documentation in your source code repository.

What is Vale?

Vale is a command-line and open-source linting tool that allows developers to define and apply custom rules for documentation/editorial style guides. Incorporating Vale in documentation helps to detect errors and provides error-fixing suggestions.

Here are other ways to leverage Vale:

  • Use as a linting tool for documentation and code documentation.
  • Ensure documentation and generated API docs are of high quality and free of avoidable mistakes.
  • Can use different styles, e.g. Google’s docs styles or the one from Microsoft (and even things like gender-neutral language).
  • Due to automation the need to manually check for it at certain times is gone.

It is backed and used by companies like Google, Microsoft, GitHub, and RedHat, and it has a collection of packages ready for you to implement. Using Vale provides flexibility because it allows developers to create their style guides from scratch or use its config generator. Using the config generator of Vale, you can generate configuration files for your style guide with existing base and supplementary style implementations.

Why Should You Run a Linter on Your Documentation?

Running a linter on your documentation enforces the use of your documentation style guides. It helps:

  • Identify errors and styling issues in your technical documentation.
  • Bring coherency in the different parts of your documentation.
  • Ensure consistency when several team members contribute to documenting your API, framework or app.
  • Remove the difficulty of manually ensuring code blocks and written content adheres to your style guide.
  • Provide positive and great developer reading experience.

Vale is commonly used to help ensure documentation consistency, whether for a software project, a technical manual, or any other type of documentation. Vale can flag any inconsistencies or deviations from the established style guide. This helps to ensure that all documentation is written in a consistent tone and style, making it easier for readers to understand.

Vale can also help improve the clarity of technical writing by flagging complex sentences, jargon, and other issues that may make the writing more difficult to understand. This can be particularly useful for technical writers communicating complex concepts to various audiences.Vale can also help catch common mistakes like passive voice, repetitive phrasing, or overly complex sentences.

Vale is highly customizable and can also be used to define custom writing rules and styles. There are established writing rules and styles defined by several large companies you can also choose to use. The availability of established rulesets makes Vale a powerful tool allowing you to quickly get started. But, if you want to establish your style guide and writing standards, that's also perfectly fine. You can adjust an established set of rules and styles with relative ease. By defining a set of rules and styles specific to your needs, you can ensure that all written materials adhere to your established standards.

How To Set Up Vale in a Project

If you want to use Vale in your project, there are some steps you need to take. The configuration you need to add describes to Vale what to check against which rules.

Here’s an example of Vale configuration from one of our SDK repositories.

  1. Create the .vale.ini file
    a. Path to styles file
    b. MinAlertLevel set to error (means that breaking builds when there are issues)
    c. Packages allow for expansion
  2. Set it up for docs
    a. Check the path ([*.md])
    b.BasedOnStyles
    c. TokenIgnores / BlockIgnores
  3. Set it up for code comments
    a. Transform to use e.g. .jsx files to .js
    b. Supported languages
    c. Add ignores (if necessary)

Setting Vale Up In CI

Once you configure Vale on your project, you probably want your CI environment to also lint your documentation. At Stream we use GitHub actions for our CI execution environment. Here’s an example of how we configure Vale on one of our SDKs.

If you are unfamiliar with GitHub Actions, make sure to check it out, especially if you host your Git repositories on GitHub. To learn more about GitHub Actions,click here.

  1. When should it run (on trigger, for us on every opened PR)
  2. It can run on ubuntu-latest (even for Swift, as it’s preinstalled there)
  3. Start with the checkout step and then run the vale-action step (link to it on Github for reference)
  4. Set the config options (such as filter_mode, fail_on_error and which files it should run on (e.g. docusaurus only or also code files)

Integrations Available With Your Favorite Editors

By now you have Vale configured on your project and perhaps even your CI environment. You can run Vale from the command line, but integrating Vale with your favorite code editor or IDE will be a huge help. Vale has documentation on several commonly used editors and IDEs.

We will describe the steps you need to take to integrate Vale in any of JetBrains’ tools and Visual Studio Code. And to top it off, we spent some time on getting integration with Xcode working as well. Xcode is not supported out of the box by Vale, but by using a build phase and some scripting we were able to create a tight integration between Xcode and Vale.

JetBrains Tools

To integrate Vale with any of JetBrain’s tools, you can use the Vale Plugin for IntelliJ IDEA. Here are the seven steps you must follow to install and use the plugin:

  1. Open IntelliJ IDEA and navigate to "Settings" by clicking on "File" > "Settings" (or "IntelliJ IDEA" > "Preferences" on a Mac).
  2. In the "Settings" dialog, click on "Plugins" on the left-hand side of the window.
  3. Click on the "Marketplace" tab, then search for "Vale" in the search bar.
  4. Install the Vale Plugin by clicking on the "Install" button.
  5. Once the installation is complete, you will need to configure the plugin. Go to "Settings" > "Tools" > "Vale" and enter the path to your Vale installation in the "Vale Path" field.
  6. You will also need to have a Vale configuration available within your project. This is described in a previous section of this article.
  7. Once you have created a Vale configuration available, you can start using Vale to lint your text. Open a file in IntelliJ IDEA, then click on "Vale" > "Run Vale" in the top menu bar. This will run Vale and display any errors or warnings in the "Vale Messages" pane at the bottom of the IntelliJ IDEA window.

Integrating Vale with Visual Studio Code

To integrate Vale with Visual Studio Code, you can use the Vale Server extension. Here are the six steps you must complete to install and use the extension:

  1. Open Visual Studio Code and navigate to the Extensions Marketplace by clicking on the "Extensions" icon on the left-hand side of the window.
  2. Search for "Vale Server" in the search bar and click on the "Install" button to install the extension.
  3. Once the installation is complete, you will need to configure the extension. Go to "File" > "Preferences" > "Settings" and search for "Vale Server".
  4. In the settings, enter the path to your Vale installation in the "Vale Server: Path" field.
  5. Again, you will need to have a Vale configuration available within your project. See the previous section on creating a Vale configuration of this article.
  6. Once you have your Vale configuration file, you can start using Vale to lint your text. Open a file in Visual Studio Code, then click on "Vale Server: Lint Document" in the Command Palette (Ctrl+Shift+P on Windows/Linux or Cmd+Shift+P on Mac). This will run Vale and display any errors or warnings in the "Vale Server" output channel at the bottom of the Visual Studio Code window.

Integrate Vale with Xcode

To integrate Vale with Xcode we need to do some more work. There is not an Xcode plugin available at the moment allowing easy integration with Vale.But fortunately, the Vale tool itself is very flexible. Here’s how to integrate:

  1. After creating your Vale configuration, make sure it works on the commandline.
  2. This guide assumes you created your Vale styles configuration in the .styles folder of your repository containing your Xcode project.
  3. In the directory called .styles, create a file names: xcode-line.tmpl. The contents of this file should be:
    {{range .Files}}
    {{- $path := .Path -}}
    {{- range .Alerts -}}
    {{$path}}:{{.Line}}:{{index .Span 0}}: {{.Severity}}: {{.Check}}:{{.Message}}
    {{end -}}
    {{end -}}
  4. Next, make sure the directory containing your markdown files is a part of the Xcode project. Make sure it is not a part of any build target. Otherwise the directory will be included in any bundle output your project build might create.
  5. Create a script file called vale-linting.sh in the directory bin at the root of your project.
    a. Change the directory in your terminal at the root of your project.
    b. Run mkdir bin if the bin directory does not exist yet.
    c. Next, run touch bin/vale-linting.sh.
    d. Make sure your new script is executable by running: chmod +xu bin/vale-linting.sh.
    e. Edit the vale-linting.sh file with your text editor of choice and make sure the contents of the file are:

    if ! which vale >/dev/null; then
    if ! which brew >/dev/null; then                    # If it's not found, check the Homebrew location and update PATH when needed
        if test -e "/usr/local/bin/brew"; then          # Default Homebrew location (pre M1 era)
            PATH="${PATH}:/usr/local/bin"
        elif test -e "/opt/homebrew/bin/brew"; then     # Default Homebrew location (M1 era)
            PATH="${PATH}:/opt/homebrew/bin"
        else
            echo "warning: Homebrew not found at default location"
        fi
    fi
    fi
    if which vale >/dev/null; then
    vale --output=./.styles/xcode-line.tmpl docusaurus
    else
    echo "warning: Vale not installed, download from https://vale.sh"
    fi

    f. Finally, add a custom build script step to your build target.

    1. Click on the project in the navigator on the left side of the Xcode screen.
    2. In the target list, choose your app target, or whatever other target you want to add the Vale linting on.
    3. Select “Build phases” from the horizontal target specific tab bar.
    4. Click on the “+” icon and in the popup menu that appears select “New Run Script Phase”
    5. A new section will appear in the list of Build Phases.
    6. On your new Script build phase, give it a meaningful name by double clicking on the build phase’s title.
    7. Next, make sure the checkbox with “Based on dependency analysis” is disabled.
    8. Finally, in the script section, add the line ./bin/vale-lint.sh.

Stream’s Swift Chat SDK has a working setup based on the above.

Conclusion

At Stream, we rely on Vale to catch a lot of the typical issues that creep into documentation. Not only does it allow us to lint our markdown files, it also lints the structured documentation comments in our sourcecode. Vale is optimized for speed and when made part of a build its runtime impact is negligible, but its value in catching typos and common errors is great. At Stream we consider Vale to be an important part of improving and maintaining the quality of our documentation.