Repository navigation
Home
Every machine you own carries a loadout — the set of programs it's equipped with, the way each one gets installed, and the maintenance steps that keep it healthy. On most machines that loadout is implicit: it lives in shell history, in "oh right, I installed that from a tap", in the drift between the laptop you set up carefully and the desktop you set up in a hurry.
loadout (the tool) makes the loadout explicit. You declare it once, in a git repo; every machine converges to its declared loadout, observes itself continuously, and publishes what it actually has — so drift, in every direction, is always one command away from visible.
Everything in loadout is one of three kinds of truth, and they never mix:
| Truth | Where it lives | Who writes it |
|---|---|---|
| Declared intent — what each machine's loadout should be |
loadout.yaml, the fragments it lists, machines/, profiles/
|
you, deliberately, in commits |
| Observed reality — what each machine actually has | state/<machine>.json |
the tool, only for the machine it runs on |
| Remote candidates — what the outside world offers | nowhere (asked live) |
loadout outdated asks; nothing is stored |
The engine that connects them is the check: a re-askable command that
proves a piece of the loadout is really there (rpm -q kitty, chezmoi verify, test -f ~/.ssh/config). loadout never trusts "it ran once" —
convergence means making the checks pass, and observation means asking
them again. Where a check lives follows where the truth lives: a package
database, a binary's version output, or a script you write only when neither
knows.
One repo holds the loadouts of your whole fleet — and, if you like, its
dotfiles too, each tool's fragment beside its config, observed and applied
like everything else (Repo layout).
Machines of the same kind share small profiles (profiles/omarchy.yaml,
profiles/macos.yaml), and each real machine's file declares only what makes
it different — down to a one-line file for a machine that's pure standard
issue:
# machines/new-macbook.yaml
extends: [macos]Machines see each other only through the state files they commit — plain
git, no server, works offline. loadout diff lays the fleet side by side.
- Explicit over implicit, everywhere. No package-manager auto-detection, no fallbacks, no heuristics. Every mapping is written down; errors beat guesses; the error message carries the fix.
-
Mechanics ship with the tool; intent lives in your repo. dnf, dnf-repo
(a vendor rpm repository), dnf-copr, brew, brew-cask, flatpak, apt,
pacman, omarchy and omarchy-aur are built in — how to install, how to check, how to ask what's
newer. Your repo says which programs and which machine gets them from
where.
loadout installersshows what a name means, your owninstallers:entry with the same name replaces one, andloadout installers --ejecthands you the lot. Built in is not detected: nothing picks an installer for you. - Checks are the truth. Success isn't an exit code — it's the check passing afterwards.
-
Converging installs; upgrading is its own verb.
setup-new-machineandinstalladd what's missing and never move a version that's already there.loadout upgrademoves versions — a whole mechanism at a time (dnf,brew…), never a single package, because partial upgrades are what package managers exist to avoid. Pins you own (a version in.tool-versions, a plugin clone) are the exception: those update one item at a time, through a command your oracle declares. - Intent and observation never mix. The tool never edits your authored files; you never edit state.
-
The mechanism lives inside; the concern is the name. Scripts are named
for what they assert (
dotfiles-pull,setup-git), not for the tool that does it.
-
Repo layout —
loadout.yaml, where fragments live, paths relative to their file, machines, profiles anddata. - Writing your manifest — start with a one-line loadout and grow it: installers, variants, scripts, profiles.
- A day with loadout — the whole lifecycle in practice: observing, maintaining, adding gear, new-machine day.
- A real repo — the author's live fleet config and dotfiles; every pattern on these pages links into it.
$ curl -fsSL https://raw.githubusercontent.com/josemiguelo/loadout/master/install.sh | shOne static binary (Kotlin/Native — no JVM, no runtime dependencies) for
linux-x64, macos-arm64, macos-x64. It shells out to your package managers
and git, so those must be on PATH. Already installed? loadout self-upgrade.
Then just run loadout: on a terminal the bare command is the home
screen — four rows (programs, scripts, remote, fleet), each with its
verdict and the one key that resolves it. Everything it shows is a command
you could have run yourself; the day page walks it.