The lockfile
Your config says what to install. archix.lock says exactly which build. With the same config and the same lock, two machines get the same package versions, today or a year from now.
The lock is a TOML file next to init.lua. Commit it. archix writes it; you don’t edit it by hand.
What’s in it
Section titled “What’s in it”One lockfile covers every host in your config. Each host gets its own section:
# Generated by archix: change it with `archix lock` or `archix update`.version = 1
[hosts.desktop]date = "2026-10-14"repos = ["core", "extra", "multilib"]declared = ["firefox", "git", "neovim", "steam"]
[hosts.desktop.packages]git = { version = "2.51.0-1", repo = "extra", file = "git-2.51.0-1-x86_64.pkg.tar.zst", sha256 = "e6674e96c7bbc318a40c1fd0008a6b00688683ce3d1b324544ebc9380885d098", explicit = true }glibc = { version = "2.44+r50+g1848099f063e-1", repo = "core", file = "glibc-2.44+r50+g1848099f063e-1-x86_64.pkg.tar.zst", sha256 = "fe91fe5179f421e133eb3026c3d84c0be076041f526d247f81226fddc5ff216b", explicit = false }zlib = { version = "1:1.3.1-2", repo = "core", file = "zlib-1:1.3.1-2-x86_64.pkg.tar.zst", sha256 = "314d62041028cade4a3f33c1e6ee79c950c08ca13e7ebd7f6467297ba94125dc", explicit = false }
[hosts.laptop]date = "2026-10-09"repos = ["core", "extra"]declared = ["firefox", "git", "neovim", "tlp"]
[hosts.laptop.packages]# ...Each package is one inline table on one line, sorted by name, so a lock diff in git shows exactly which packages changed. Host and package names that aren’t plain letters, digits, - and _ are quoted, as in [hosts."my.laptop"] or "gtk+" = { ... }.
| Field | Meaning |
|---|---|
version (top level) |
The lock format version. A newer format is rejected with a clear error instead of being misread. |
date |
The Arch Linux Archive snapshot the host’s official packages come from. |
repos |
The official repos the host resolved against, in priority order. This is your repos option. |
declared |
The packages you declared, sorted. archix compares it with your config to see whether the lock is out of date. |
packages |
One inline table per installed package, dependencies included, keyed by package name. |
version, repo, file |
The exact package version, the repo it came from, and its package file. |
sha256 |
The checksum of the package file. A file that doesn’t match is never installed. |
explicit |
Whether pacman marks it as explicitly installed or as a dependency. |
Every host can sit on a different date. The laptop doesn’t have to update just because the desktop did.
Official repos: Arch Linux Archive snapshots
Section titled “Official repos: Arch Linux Archive snapshots”The Arch Linux Archive (ALA) keeps a full copy of the official repos for every day. archix locks your official packages to one of those days.
When archix installs, it uses its own temporary pacman.conf that points only at that snapshot. Your /etc/pacman.conf stays on your live mirrors, for when you run pacman yourself. The two are never mixed: a transaction uses either the snapshot or the live mirrors, never both, so you can’t end up with the partial upgrade the Arch wiki warns about.
The ALA also keeps every package version ever published under /packages/. So archix can fetch any exact version in the lock, even one that doesn’t belong to the snapshot date. That makes official packages always restorable.
The keyring exception
Section titled “The keyring exception”archlinux-keyring always comes from the latest date, not the snapshot. An old keyring doesn’t know about new packager keys and can fail signature checks, and the keyring itself only ever needs to move forward. Everything else stays on the locked date.
A pin holds or bumps one package without moving the rest. Hold mesa at its locked version while you archix update everything else, or bump just firefox ahead of the snapshot for a security fix. Pinned packages are recorded in the lock as exact-version entries: archix fetches that version from the ALA’s /packages/ instead of the snapshot.
The same mechanism handles packages you upgraded with pacman when they don’t match any single snapshot. See pacman and yay.
AUR packages: commits
Section titled “AUR packages: commits”An AUR package is a git repo of build files on aur.archlinux.org, so archix locks it by commit:
[hosts.desktop.packages]zen-browser-bin = { version = "1.16.3b-1", repo = "aur", commit = "cd6266c6847e61c71facdd7dbf869b5cf64359be" }The build runs in a clean chroot at the host’s snapshot date, so its dependencies are locked too. The built package is cached by PKGBUILD commit and snapshot date. See The AUR.
Third-party repos: cached copies
Section titled “Third-party repos: cached copies”Third-party repos like CachyOS and chaotic-aur have no dated archive. archix keeps a content-addressed copy of every package file it installs from them, and the lock refers to it by checksum:
[hosts.desktop.packages]linux-cachyos = { version = "6.17.2-2", repo = "cachyos-core-v3", file = "linux-cachyos-6.17.2-2-x86_64_v3.pkg.tar.zst", sha256 = "037c07941f32cbc6746bf10bda7f2f6dbd00a6035eb46ab98fa5c000baf2197b", explicit = true }On the machine that made the lock, that’s as solid as an ALA snapshot. On a fresh machine it may not be, because the repo may no longer have that version. Third-party repos explains what happens then.
lock and update
Section titled “lock and update”Two commands write the lock. They differ in whether the snapshot date moves.
archix lock keeps the host’s date and resolves your current config against it. Use it after adding or removing packages. New packages come from the same day as everything else, so nothing else changes:
$ archix lockresolving 86 declared packages against the 2026-10-14 snapshot+ htop 3.4.1-1+ libnl 3.11.0-11215 packages lockedwrote /etc/archix/archix.lockIf nothing changed, it says so and leaves the file alone:
$ archix lockarchix.lock is up to date for desktop (snapshot 2026-10-14)archix update moves the host to the newest snapshot and re-resolves. This is your system upgrade:
$ archix updateresolving 86 declared packages against the 2026-10-15 snapshotsnapshot 2026-10-14 -> 2026-10-15~ firefox 144.0-1 -> 144.0.1-1~ mesa 1:25.3.0-1 -> 1:25.3.1-1- libnl-legacy 1.1.4-11214 packages lockedwrote /etc/archix/archix.lock+ is a new package, ~ a changed version, - a package that’s no longer needed. The newest snapshot is the newest one the archive has published, so right after midnight it may still be yesterday’s.
To move to a specific day instead, pass --to. It works in both directions, which makes it a quick way to step a whole host back to a day you know was good:
$ archix update --to 2026-10-01You rarely need lock on its own: archix switch locks first when the config changed. Run it when you want to review and commit the lock before switching, or to lock another host with --host.
Neither command changes the system. archix diff shows what a switch would do with the current lock:
$ archix diffsnapshot 2026-10-15: 1214 packagesupgrade firefox 144.0-1 -> 144.0.1-1upgrade mesa 1:25.3.0-1 -> 1:25.3.1-1remove libnl-legacy 1.1.4-1 (not in the lock)Missing versions
Section titled “Missing versions”Official packages can always be fetched from the ALA. AUR and third-party packages can go missing: a cache gets cleaned, a repo drops an old build, an AUR package is deleted. When archix can’t get a locked version, it tries, in order:
- The local package cache.
- A rebuild from the locked AUR commit.
- A prompt.
The prompt offers the nearest version it can get:
$ sudo archix switchUse 0.5.1 (nearest newer) instead of 0.5.0? [Y/n]Whatever you choose is written back to the lock, so the next machine gets the same answer without being asked.
Policies
Section titled “Policies”Prompts don’t suit unattended runs. Set a policy in your config, or pass one on the command line, and archix picks the nearest version without asking:
$ sudo archix switch --accept-nearest=newer$ sudo archix switch --accept-nearest=older--noconfirm also skips the prompt and takes the nearest newer version, the same as --accept-nearest=newer.
Third-party repos add one more step before this prompt: falling back to another source for the same package. That has its own setting; see Third-party repos.