For the complete documentation index, see llms.txt. This page is also available as Markdown.

Packages

Learn how configuration is shared, installed, and kept up to date.

StylesPath = styles

Packages = Microsoft, write-good

[*.md]
BasedOnStyles = Microsoft, write-good

Packages lists what vale sync installs into the StylesPath. A package is a style, a configuration file, or both, published as an archive, and naming it here is all a project has to do to use it. Update the package, run vale sync again, and every project that names it has the new rules.

Image
One upstream package is inherited by several projects, so an upstream change reaches all of them. Within a project, configuration is layered: the first package is overridden by the second, and local configuration overrides both.

Naming a package

Each entry in the list is one of four things:

  • A name from the library, such as Microsoft. A name is looked up in the package library, which the Package Explorer is built from, and the URL it records is what gets installed.

  • A URL to a .zip archive.

  • A path to a .zip archive on disk.

  • A path to a directory laid out like an unpacked archive.

A package's name is the archive's file name without .zip, or the directory's name, and the archive has to hold one folder with that name. Google.zip unpacks to Google/. A name that isn't in the library is tried as a path and then as a URL, so a misspelled name reports itself as a URL that couldn't be fetched.

Relative paths are resolved from the directory vale sync runs in, not from the configuration file.

What sync does

vale sync reads Packages from one configuration file, the one the search finds or the one --config names, and installs each entry in order. In doing so it:

  1. Creates the StylesPath if it doesn't exist, and deletes the .vale-config/ directory inside it.

  2. Fetches or unpacks each package, and copies what it holds into the StylesPath. A style already there with the same name is replaced whole, so an installed style is not the place to make edits.

  3. Merges the package's config/ into yours, one entry at a time: a vocabulary or dictionary the package carries lands beside the ones you have, and one with the same name replaces yours.

  4. Copies the package's .vale.ini, if it has one, into .vale-config/, named for its position in the list. A package that lists packages of its own has those installed too.

Run it after adding a package, and in CI before linting. --plain-progress prints a line per package instead of a progress bar, for logs.

Shapes

A package holds a style, a configuration file, or both.

A style

An archive of one style directory:

The directory is copied into the StylesPath, and BasedOnStyles = write-good switches it on.

A configuration

An archive of a .vale.ini alone, which is how support for a markup convention or a site generator is shared:

The file lands in .vale-config/ and is read before your own, so its settings are the base yours sit on. Nothing in it needs to be repeated locally.

Both

A .vale.ini beside a styles/ directory that is a StylesPath of its own:

The directory has to be named styles, and it can hold anything a StylesPath can, styles and the config/ directory alike. Its .vale.ini refers to it, switches its rules on, and can list further packages:

On sync, styles/ is merged into the project's StylesPath and the .vale.ini goes to .vale-config/.

A vocabulary

Requires Vale v3.25.0 or later.

A package can carry a vocabulary and turn it on for every file by naming it in [*]:

Its terms add to the project's own vocabularies, and its rules, Vale.MyTerms.Terms and Vale.MyTerms.Avoid, are on for every file. A project can switch them off by name, or drop the vocabulary with Vocab = NONE in its own [*]:

Pinning a version

Naming a package installs its latest release, so the rules it brings change as the package is updated. To hold a package at a known version, give the release URL in place of the name:

A style takes its name from the folder inside the archive, so BasedOnStyles reads the same either way. Only where the package comes from changes. Run vale sync again after editing the URL to move to a different version.

This is worth doing wherever a new rule arriving on its own would be disruptive, such as a repository several people write in, or a CI job that fails on new alerts.

Ordering

Configuration is read in this order: each package's .vale.ini in the order Packages lists them, then your own file.

A list key such as BasedOnStyles gathers every value from every source, so the styles pkg1 and pkg2 switch on run alongside House. Any other key takes the last value read: MinAlertLevel, a rule's level, a parameter, and a switch all end up as your file has them, and pkg2 has them as it does where your file is silent.

The version Vale supports

Requires Vale v3.23.0 or later.

A package's meta.json names the Vale it needs, as vale_version. When the release sync downloads needs a newer Vale than the one running, sync installs the newest release this Vale does support instead, and says so:

If no release supports the running Vale, sync installs the latest one and warns, which is what it always did; the metadata can only improve on that. A package pinned to a release URL is installed as asked, with the same warning when it needs a newer Vale.

This is what lets a package raise the Vale it needs without breaking anyone: an older Vale keeps the last release that worked for it. Sync finds the earlier releases one of two ways:

  • A manifest. meta.json lists the releases, each with its version, the Vale it needs, and its archive URL. The URLs can point anywhere, so this works on any host, and sync downloads only the release it picks:

  • The release feed. Without a manifest, a package served from a GitHub releases/latest/download URL has its releases read from the repository's Atom feed, named in meta.json as feed or derived from the package's URL, and the ten most recent are tried newest first until one fits.

Publishing a package

A package is a release asset: a .zip whose single top-level folder is the package's name, attached to a release of a Git repository. The releases/latest/download URL then always points at the newest one. To make a package installable by name, add an entry for it to the library in a pull request. The repository's README describes the entry.

Version control

Commit the styles you wrote and the config/ directory. Everything vale sync writes, the installed styles and .vale-config/, is rebuilt from Packages, so most projects ignore it. Ignoring the whole StylesPath is simplest when nothing in it is yours. When some of it is, ignore selectively:

This ignores everything under .github/styles/ except .github/styles/config/vocabularies/Base.

Last updated