temper

Keep your machines the way you declared them: packages and configuration, described in a folder of plain, human-readable files.

brew trust --tap jakobhviid/tapbrew install jakobhviid/tap/temper

Install Read the README

macOS and Linux, x86_64 and arm64 · MIT licensed

What it does

The tool is the same for everyone; the spec is a folder you bring: a git repo, a synced Nextcloud or Dropbox folder, a USB stick. It holds one manifest, a recipe per app, and the real files those recipes deploy. Adding an app is a config file you write, never a tool release.

Packages and config, one tool

brew, cask, flatpak, mas, VS Code, GNOME extensions, rpm-ostree, and the distro's own dnf, apt or pacman, plus file, key, marker-block and root-owned /etc config steps. Real files, not a new language.

Drift, with the command to fix it

temper drift only reads. It reports what is out of sync and ends with the exact command for each way out, in both directions.

Two directions

temper install converges the machine toward the spec. temper reconcile absorbs the machine's live state back into the spec: packages, tap trust and GNOME settings, per key.

Reversible, and says where it is not

File writes, dconf keys and package installs are journaled, and temper undo reverts the last run without overwriting a file changed since. A run that touches state it cannot revert says so before you confirm.

A first look

On a Debian machine, a package installed by name since temper's baseline and declared nowhere is an extra. temper prune removes it; temper reconcile absorbs it into the machine's own list.

$ temper drift
drift · m

  apt
    ✗ bc        extra  [apt-extra]
    ✗ libonig5  extra  [apt-extra]
    … 1 more in sync

Install

Homebrew, on macOS and Linux

Installs a prebuilt binary with its man page and shell completions, so no compiler is needed. The tap is trusted once first, as Homebrew 6 and later ask.

brew trust --tap jakobhviid/tapbrew install jakobhviid/tap/temper

Or one line, without Homebrew

No compiler and no root: installs the prebuilt binary to ~/.local/bin.

curl -fsSL https://raw.githubusercontent.com/jakobhviid/temper/main/install.sh | sh

Then point it at your folder

Records where the folder lives, so temper runs from anywhere. Optional: run from inside the folder and it is found there. On a machine already set up the way you like, temper init writes its entry and seeds it from what is installed.

temper setup ~/my-spec

Documentation