A community package manager for Void Linux, built on top of xbps and xbps-src.
Fork of paru. vary reuses paru's user experience (familiar interface, interactive search and install) but talks exclusively to the XBPS ecosystem: no pacman, no ALPM. The port and current development are by Dicov (SrDicov); all credit for the original work goes to Morganamilo and the paru community.
Its core piece is the VUR protocol: distributed Git repositories that combine void-packages-style templates with a declarative .VURINFO (JSON) index generated by CI, plus optional HTTP-served binaries signed with xbps-rindex.
MVP under development. Only main (stable) and testing (integration) exist; installed on testing: command interfaces and formats may change without notice.
- Void Linux with
xbpsandxbps-srcinstalled (plusbase-develto compile). git— used to clonevoid-packagesand VUR repos. It is mandatory: if missing, vary fails at startup withgit es requerido por vary pero no está instalado. Instálalo con: xbps-install git.
There are no manual bootstrap steps: on the first vary -Syu, vary automatically clones void-packages into ~/.cache/vary/void-packages, prepares the xbps-src masterdir, and creates its local caches.
# Initial sync/bootstrap (clones void-packages and prepares xbps-src)
vary -Syu
# Search official repos and registered VURs
vary -Ss firefox
# Install a package
vary -S firefox
# Register a remote VUR repo (cloned into ~/.local/share/vary/vurs/ and
# registered in /etc/xbps.d/20-vur-<name>.conf).
# The default branch is auto-detected (main, master, ...); override with --branch.
vary --repo add https://git.example.com/user/vur.git
vary --repo add https://github.com/SrDicov/z-packages z-packages --branch masterOther commands available in the MVP: -Si (detailed info), -Sw (download without installing), -R (remove), --repo list|remove|rekey|re-trust (re-trust re-affirms a rotated repo key), --force-build (build from source even if a binary exists: prefers source candidates across repositories and overrides the official bucket when a VUR template exists — warns explicitly when it can't) and --prefer-binary (prefer signed binaries, switching repositories when needed; --no-prefer-binary forces the source path). Without these flags the historical precedence applies (official first, then the merged VUR candidate). --yes is an alias of --noconfirm (note: -y means refresh, not yes); --asdeps/--asexplicit are rejected (vary always installs as explicit). -Sp prints the install plan (topological levels, single binary batch, estimated elevations) without changing anything: script-parseable, no lock, no elevation (the VUP index may refresh its cache read-only, like -Sy). --lock (re)generates ~/.config/vary/vary.lock (repos + packages pinned); install/upgrade warn on divergence. --challenge <pkg> --experimental rebuilds and compares against installed files. --why <pkg> explains what pulls a package; --log [pkg] shows the operation history.
User configuration lives in ~/.config/vary/vary.conf (optional; full example in etc/vary.conf.example):
[general]
cache_dir = "~/.cache/vary"
data_dir = "~/.local/share/vary"
log_level = "info"
[build]
max_concurrent_builds = 2
force_rebuild = false
[search]
ttl_cache_seconds = 3600Privilege escalation is tool-agnostic: vary uses whatever is configured via --sudo / sudo_bin (sudo, doas, run0), auto-detects in that order when unset, and skips the wrapper entirely when running as root.
VUR repos are declared in ~/.config/vary/repos.conf:
[vur.my-vur]
url = "https://git.example.com/user/vur.git"
branch = "main"
priority = 10
# Optional: VUP-style remote binary index (index.json). When set, vary
# installs that repo's binaries for your architecture without needing
# .VURINFO or templates (Phase 1 adapter, binary only).
# index_url = "https://vup-linux.github.io/vup/index.json"Repos that publish a VUP-style index.json (e.g. VUP-Linux/vup) can be used
for binary installs:
vary --repo add https://github.com/VUP-Linux/vup vup \
--index-url https://vup-linux.github.io/vup/index.json
vary -S vlang # binary install from the matching release repoNotes: needs curl (configurable via --curl / [general] curl_bin); the
repo's keys/*.plist key is verified like any VUR key (key_fingerprint
in repos.conf); source builds from such repos are not supported yet. On the
first binary install vary pre-imports the key into the xbps keyring, so only
vary's own trust confirmation is asked (no second xbps key-import prompt).
The fingerprint vary prints matches xbps's: pin it via key_fingerprint.
A rolling XBPS repository with signed packages lives at a fixed URL and is refreshed on every successful build:
echo 'repository=https://github.com/SrDicov/Vary/releases/download/repo' | sudo tee /etc/xbps.d/20-vary.conf
sudo xbps-install -S # accept the RSA fingerprint when prompted
sudo xbps-install vary # later: sudo xbps-install -Su keeps it currentBoth glibc and musl are served from that single URL (x86_64 / x86_64-musl). The musl artifact (vary-*_1.x86_64-musl.xbps) is dynamically linked (interpreter /lib/ld-musl-x86_64.so.1) and requires a Void musl system to run; it does not run on glibc (verified by the verify musl workflow job in a musl container). The signing public key is published as keys/vary-repo.pub.pem.
graph TD
A[CLI: src/lib.rs] --> B[Resolver: src/resolver.rs]
B --> C{Package type}
C -->|Official| D[Action::Install<br/>xbps-install]
C -->|VUR Binary| E[Verify RSA signature<br/>src/keys.rs → Install]
C -->|VUR Source| F[Copy template → xbps-src pkg<br/>→ Action::Install]
B --> G[Cache: src/cache.rs<br/>~/.cache/vary/cache.json]
B --> H[DB: src/db.rs<br/>~/.cache/vary/installed.json]
F --> I[Bootstrap: src/bootstrap.rs<br/>void-packages + masterdir]
E --> J[Keys: /etc/xbps.d/keys/]
A --> K[Config: src/config.rs<br/>vary.conf + repos.conf]
Relevant directories:
| Path | Purpose |
|---|---|
~/.cache/vary/void-packages/ |
void-packages checkout used by xbps-src |
~/.cache/vary/cache.json |
search/metadata cache |
~/.cache/vary/installed.json |
database of packages managed by vary |
~/.cache/vary/logs/ |
build logs |
~/.local/share/vary/vurs/ |
local clones of VUR repos |
~/.config/vary/vary.conf, ~/.config/vary/repos.conf |
user configuration |
/etc/xbps.d/10-vary.conf, /etc/xbps.d/20-vur-<name>.conf |
xbps integration |
During the MVP, vary favors simplicity over completeness: VUR dependency resolution is based on the declarative .VURINFO index published by each repository, not on fully evaluating templates on your machine. That implies important restrictions described below, plus planned features that are still missing (see roadmap).
NOTE ON DYNAMIC VARIABLES: The .VURINFO generated by scripts/vur-generator.sh reflects DEFAULT build options (no active XBPS_PKG_OPTIONS). If the end user builds with custom options (XBPS_PKG_OPTIONS_), initial dependency resolution may be incomplete. xbps-src will handle additional dependencies during the real build. This is acceptable for the MVP: DAG resolution is an optimization to minimize unnecessary builds, not a completeness guarantee.
Use -v/-vv for DEBUG/TRACE console output (RUST_LOG overrides them); log_level in vary.conf sets the default level.
- Phase 2 — concurrent builds: parallel builds limited by
max_concurrent_buildsviatokio::sync::Semaphore(today builds are sequential). - Phase 2 — automated
regen-aur: avary --repo regen-aur <pkg>style command to refresh AUR-derived templates without manual steps (seedocs/AUR2XBPS.md).
GPL-3.0. vary is a port of the excellent work by Morganamilo and the paru community; all credit for the original authorship belongs to them. The Void Linux/XBPS port and current development are by Dicov (SrDicov). See LICENSE.