Installation
Get started with Vale in just a few minutes.
Pick your platform
The recommended approach on every platform is a package manager: it puts vale on your $PATH and keeps you up to date with new releases.
> choco install vale> scoop install vale> winget install -e --id errata-ai.ValeOn Debian and Ubuntu, the pkg.haus APT archive ships Vale for stable, testing, and unstable (amd64 and arm64), built from source at release tags. Set up the archive per the instructions on pkg.haus, then:
$ sudo apt install valeOn Arch Linux, Vale is in the official repositories:
$ sudo pacman -S valeSnapcraft works across distributions:
$ sudo snap install valeMany other distributions—Alpine, openSUSE, Void, and more—package Vale in their own repositories; see the full list.
Vale is in the ports collection as textproc/vale:
$ pkg install valeThere are no official FreeBSD binaries on the releases page, so the port is also the answer for build-from-source setups.
Installing Vale with a project
A system-wide install leaves each contributor on whatever version they happened to get, and your CI on another. Declaring Vale in the project instead pins one version for everyone—which matters because a new release can add rules or change what an existing one matches.
mise does this for any project, whatever it's written in:
$ mise use vale@3.26.0If your project already installs its tools through a language's package manager, Vale is packaged there too. Each of these downloads the same release binaries and puts vale on your $PATH:
$ npm install --save-dev @vvago/valeAdds @vvago/vale to devDependencies; run it with npx vale.
$ pip install valeInstalls vale into the active environment; pin it in requirements.txt or your pyproject.toml.
$ conda install conda-forge::valeInstalls conda-forge/vale into the active environment, or list it under dependencies in environment.yml.
For linting in CI, the Vale GitHub Action installs and runs Vale in one step, and Vale can also run as a pre-commit hook.
GitHub Releases
Archives of precompiled binaries are available for Windows, macOS, and Linux (amd64 and arm64). Download the archive for your platform, extract it, and (optionally) add the extracted directory to your $PATH.
Building from source
Vale is a Go program, so go install builds it for any platform Go supports—including those without a release archive:
This needs Go 1.25.7 or later and a C compiler, since Vale's source-code parsers are built through cgo. A binary built this way reports its version as master rather than the release number.
Docker
Vale is available on Docker Hub at jdkato/vale:
Vale requires three components: a .vale.ini config file, a StylesPath directory (specified in the config file), and a document or directory to lint.
Here's an example of calling Vale with locally-defined components (assuming $(pwd)/fixtures/styles/demo contains a config file):
By default, the image supports HTML, Markdown, AsciiDoc, and reStructuredText content. If you need support for DITA as well, you'll need to add the relevant dependencies—for example,
Keeping Vale up to date
A system package manager updates Vale along with everything else it installed. A version pinned in a project stays put until someone moves it, which is what dependency-update bots are for. None of them know anything about Vale: they read the file where you wrote a version number, ask the registry that file points at whether a newer one exists, and open a pull request that changes the number. The pull request's CI run is the useful part. A new release can add rules to a package or change what an existing rule matches, so a red build on the bump shows the new alerts before anyone else sees them.
Renovate
Renovate runs either as the hosted Mend app for GitHub or self-hosted from an npm package, a Docker image, or its own GitHub Action, and it supports GitHub, GitLab, Bitbucket, Azure DevOps, and Forgejo. Once installed, it opens a first pull request that adds a renovate.json and lists everything it found; merging that turns it on.
From then on, each run scans the repository for the manifest files its managers recognize, looks each dependency up in the registry it belongs to, and opens one pull request per available update. Every way of pinning Vale from the previous section maps to a manager:
mise.toml
mise
Vale's GitHub releases, via the mise registry
package.json
npm
npm
requirements.txt
pip_requirements
PyPI
pyproject.toml
pep621
PyPI
Dockerfile
dockerfile
Docker Hub
.github/workflows/*.yml
github-actions
the action's tags
.pre-commit-config.yaml
pre-commit
Vale's GitHub tags
All of these are on by default except pre-commit, which Renovate leaves off because hook revisions are often deliberately old. A minimal renovate.json that enables it:
Two pins need a number to bump. A FROM jdkato/vale line with no tag floats, so Renovate has nothing to update; pin it to jdkato/vale:v3.20.0 as in the Docker example above. And the Vale GitHub Action's version input defaults to latest: Renovate bumps the action's own reference, but a pinned version: 3.20.0 inside a workflow is plain YAML to it and needs a custom manager to be tracked.
Dependabot
Dependabot is built into GitHub, so there is nothing to install. It reads one file, .github/dependabot.yml, and each updates entry names a package ecosystem, the directory holding its manifest, and how often to check. Every entry is checked independently and opens its own pull requests.
Where Vale is pinned
package-ecosystem
package.json
npm
requirements.txt or pyproject.toml
pip
environment.yml
conda
Dockerfile
docker
.github/workflows/*.yml
github-actions
A config that covers an npm-managed project with a Docker image and the Vale action:
Dependabot has no ecosystem for mise or pre-commit, so a mise.toml pin or a .pre-commit-config.yaml revision stays where it is. For pre-commit, pre-commit.ci fills the gap with a weekly pull request that bumps every hook's rev. The same tag rule applies as with Renovate: an untagged FROM jdkato/vale is never updated.
Last updated