> For the complete documentation index, see [llms.txt](https://docs.vale.sh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.vale.sh/keys/packages.md).

# Packages

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

```ini
StylesPath = styles

Packages = Microsoft, write-good

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

`Packages` lists what `vale sync` installs into the [`StylesPath`](/keys/stylespath.md). 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.

![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.](https://2533404145-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEMH7s0sC5N9L8xSMXGwW%2Fuploads%2Fgit-blob-85b00d5c4986cdb8561019246bb3b1b3374b1700%2Fpackage.svg?alt=media)

## [Naming a package](#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](https://github.com/vale-cli/packages), which the [Package Explorer](https://vale.sh/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](#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.

```console
$ vale sync --plain-progress
Synced Microsoft
Synced write-good
 SUCCESS  Synced 2 package(s) to '/home/me/docs/styles'.
```

## [Shapes](#shapes)

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

### [A style](#a-style)

An archive of one style directory:

```console
$ unzip write-good.zip
Archive:  write-good.zip
   creating: write-good/
  inflating: write-good/README.md
  inflating: write-good/Cliches.yml
  inflating: write-good/ThereIs.yml
  inflating: write-good/Weasel.yml
  ...
  inflating: write-good/meta.json
```

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

### [A configuration](#a-configuration)

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

```console
$ unzip Hugo.zip
Archive:  Hugo.zip
   creating: Hugo/
  inflating: Hugo/.vale.ini
```

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](#both)

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

```
MyPackage/
├── .vale.ini
└── styles/
    ├── MyStyle/
    │   └── MyRule.yml
    └── config/
        ├── dictionaries/
        │   └── MyDic.dic
        ├── scripts/
        │   └── MyScript.tengo
        └── vocabularies/
            └── MyVocab/
                ├── accept.txt
                └── reject.txt
```

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:

```ini
# MyPackage/.vale.ini
StylesPath = styles

Packages = proselint

[*.{md,adoc}]
BasedOnStyles = MyStyle
```

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

## [Pinning a version](#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:

```ini
StylesPath = styles

Packages = https://github.com/vale-cli/Google/releases/download/v0.7.0/Google.zip

[*.md]
BasedOnStyles = Google
```

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](#ordering)

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

```ini
Packages = pkg1, pkg2

[*.md]
BasedOnStyles = House
```

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](#the-version-vale-supports)

{% hint style="info" %}
Requires Vale v3.23.0 or later.
{% endhint %}

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:

```console
$ vale sync
 INFO  'Readability' needs Vale >=3.23.0; this is 3.22.0: installed v0.1.1 instead.
```

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:

  ```json
  {
    "vale_version": ">=3.23.0",
    "releases": [
      {"version": "v0.3.0", "vale_version": ">=3.23.0", "url": "https://example.com/readability/v0.3.0/Readability.zip"},
      {"version": "v0.2.0", "vale_version": ">=2.13.0", "url": "https://example.com/readability/v0.2.0/Readability.zip"}
    ]
  }
  ```
* **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](#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](https://github.com/vale-cli/packages) in a pull request. The repository's README describes the entry.

## [Version control](#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:

```gitignore
# Ignore the StylesPath except for our own vocabulary.

.github/styles/*
!.github/styles/config/

.github/styles/config/*
!.github/styles/config/vocabularies/

.github/styles/config/vocabularies/*
!.github/styles/config/vocabularies/Base
```

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


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.vale.sh/keys/packages.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
