Skip to content

Package Management

All package declarations live in home/.chezmoidata/packages.yaml as the single source of truth across every package manager the repo supports — brew, apt, dnf, and flatpak. The Brewfile is rendered from this data by chezmoi; the apt/dnf/flatpak install scripts read it directly.

Nothing prevents you from using the system package managers directly (apt install foo, flatpak install bar, brew install baz) — they work as normal. The reason to add a package to packages.yaml instead is to have it installed automatically on a fresh system bootstrap and to opt in to the convenience recipes below.

No declarative removal. This is install-side declarative only. Removing a package from packages.yaml does not uninstall it on machines where it's already present. Uninstall manually via the relevant package manager (brew uninstall, sudo apt remove, flatpak uninstall, etc.).

Init vs runtime

Two distinct concerns. Both consume packages.yaml, but at different times and for different reasons.

Init — one-shot bootstrap

On first chezmoi init --apply on a fresh machine:

Script (in home/.chezmoiscripts/) Installs
run_once_before_03-install-linux-packages.sh apt or dnf packages
run_once_before_04-install-flatpaks.sh Flatpak apps from flathub
run_once_after_10-brew-bundle.sh Brewfile contents

Each script runs once per machine; chezmoi tracks execution in its state DB. They are not invoked automatically again on later applies.

Runtime — on-demand package management

Day-to-day, after a package is added to packages.yaml:

  • chezmoi apply re-renders generated files (~/Brewfile, any other managed templates) — file state.
  • The new package is not automatically installed. Use the runtime recipes below to install it (just sys pm install, or just update for the full refresh).

This separation is deliberate: chezmoi apply is for file state; just update (and the sys::pm::* recipes) is for package state. Two verbs, two purposes.

Removal is asymmetric — see the note above. Recipes here install declared packages; they do not remove undeclared ones.

Recipes

  • just update — full refresh. Chains dotfiles::updatesys::pm::updatedotfiles::verify.
  • just sys pm install — install missing packages from packages.yaml on every detected manager (brew, apt, dnf, flatpak). Idempotent.
  • just sys pm update — refresh repos + upgrade installed packages + install missing declared packages.
  • just sys pm edit-package-data — open packages.yaml in $EDITOR, prompt to apply chezmoi afterward, then run sys pm install for any newly-declared packages.

Per-manager dispatch is internal — the user doesn't choose between brew, apt, dnf, or flatpak; the platform answers that via command -v detection. Absent managers are silently skipped, so just sys pm install on macOS only touches brew (no apt/dnf/flatpak available).

Per-manager notes (brew on Bluefin, dnf in Distrobox vs host image, flathub remote setup, etc.) live in home/dot_just/sys/pm/help.md — reach it with just sys pm help.