Pacman Hooks: The Small Feature That Replaces Your Post-Upgrade Checklist
Pacman hooks turn your post-upgrade checklist into declarative, version-controllable automation. Here's how they work, a real example, and the trade-offs to respect.
12 Nov 2025, 17:26 UTC

Every Arch maintainer has a version of the same ritual: upgrade the kernel, then remember to rebuild the initramfs, refresh the font cache, reload the systemd daemon, recompile DKMS modules. Forget one step and you find out at the next reboot. Pacman hooks exist to delete that ritual entirely — and they're a first-class, officially supported feature, not a community hack.
The thesis here is simple: if a step must happen every time a particular package changes, that step belongs in a hook file, not in your memory or a wiki page.
What a hook actually is
A pacman hook is a small INI-style file with a .hook extension. Pacman reads hooks from two directories: /usr/share/lib/pacman/hooks (owned by packages — do not edit these, upgrades will overwrite them) and /etc/pacman.d/hooks (yours). Hooks in /etc also override same-named package hooks, which is the supported way to disable or adjust a shipped hook.
Each hook declares when it runs (When = PreTransaction or PostTransaction), what triggers it, and what command to execute. Triggers can match on package operations (Operation = Install/Upgrade/Remove with a Target package name) or on file paths (Type = Path), which is how font-cache and icon-cache hooks fire when anything installs files into a watched directory.
A worked example: daemon-reload after package changes
Say you want systemctl daemon-reload to run automatically whenever a package installs or upgrades systemd unit files, so you never again wonder why a freshly upgraded service behaves like the old version. Create /etc/pacman.d/hooks/systemd-daemon-reload.hook as root:
[Trigger]
Type = Path
Operation = Install
Operation = Upgrade
Target = usr/lib/systemd/system/*
[Action]
Description = Reloading systemd daemon after unit file changes...
When = PostTransaction
Exec = /usr/bin/systemctl daemon-reloadThat's the whole thing. The next pacman -Syu that touches a unit file runs the reload for you. Two fields deserve attention: NeedsTargets = yes would pass the matched targets to your command (useful for hooks that rebuild only what changed), and AbortOnFail on a PreTransaction hook stops the transaction if the hook fails — powerful, but handle with care.
To sanity-check your setup, list the hooks already on your system with ls /usr/share/lib/pacman/hooks and read one — you'll see hooks shipped for systemd-sysusers, tmpfiles, texinfo, and more. The format is documented in man alpm-hooks; check it against your installed pacman version, since supported fields have evolved over time.
Why this beats post-install scripts
Historically, this kind of automation lived in package install scripts or in admin habit. Hooks are better on three axes. They're declarative: a hook file states its trigger and action in a dozen auditable lines. They're version-controllable: /etc/pacman.d/hooks sits alongside the rest of your system config and can live in the same dotfiles or config-management repo. And they're the maintained path — Arch itself ships its own automation as hooks, which means the mechanism gets exercised and tested on every system, every upgrade.
The trade-off: invisible automation
Centralizing automation has a cost: upgrades now do things you didn't explicitly type. A failing hook can interrupt a transaction, and a badly written one — especially around kernels or bootloaders — can leave a half-configured system. Two disciplines keep this safe. First, make hooks idempotent: running them twice must be harmless (daemon-reload qualifies; a script that appends to a config file does not). Second, test before trusting: install a trivial package that matches your trigger and confirm the hook fired — a temporary hook that appends a line to a log file is a good smoke test. If a hook misbehaves, removing the file from /etc/pacman.d/hooks fully disables it; nothing else persists.
Where to start
Pick one manual step you repeat after upgrades — the one you've forgotten at least once — and encode it as a hook this week. Start with a PostTransaction hook without AbortOnFail, verify it fires on a real transaction, and only then consider anything that can block a transaction. Your future self, rebooting into a working system, will appreciate it.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.