Skip to content

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.

One lockfile covers every host in your config. Each host gets its own section:

archix.lock
# 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.

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.

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 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.

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:

Terminal window
$ archix lock
resolving 86 declared packages against the 2026-10-14 snapshot
+ htop 3.4.1-1
+ libnl 3.11.0-1
1215 packages locked
wrote /etc/archix/archix.lock

If nothing changed, it says so and leaves the file alone:

Terminal window
$ archix lock
archix.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:

Terminal window
$ archix update
resolving 86 declared packages against the 2026-10-15 snapshot
snapshot 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-1
1214 packages locked
wrote /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:

Terminal window
$ archix update --to 2026-10-01

You 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:

Terminal window
$ archix diff
snapshot 2026-10-15: 1214 packages
upgrade firefox 144.0-1 -> 144.0.1-1
upgrade mesa 1:25.3.0-1 -> 1:25.3.1-1
remove libnl-legacy 1.1.4-1 (not in the lock)

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:

  1. The local package cache.
  2. A rebuild from the locked AUR commit.
  3. A prompt.

The prompt offers the nearest version it can get:

Terminal window
$ sudo archix switch
Use 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.

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:

Terminal window
$ 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.