System Packages | mise-en-place
Skip to content
Appearance
MenuReturn to top
System Packages experimental ""><br>mise can ensure machine-global system packages are installed via the [system.packages] section of mise.toml:<br>toml[system.packages]<br>"apt:libssl-dev" = "latest"<br>"apt:build-essential" = "latest"<br>"brew:postgresql@17" = "latest"<br>"brew:ffmpeg" = "latest"<br>Each entry is keyed "manager:package" — the manager prefix is required — and the value is a version: "latest" for whatever the manager installs, or a pin in the manager's native format where supported (see the per-manager pages).<br>mise can also place machine-global config files (dotfiles) — see System Files, which follows the same rules and shares the same commands.<br>System packages are intentionally separate from [tools]: they are not version-pinned per-project, do not get shims, and are installed machine-globally by the platform's package manager — or, for brew, by mise's built-in Homebrew bottle installer, which doesn't require Homebrew itself. Use them for shared libraries and build dependencies that dev tools need (libssl-dev, postgresql, ffmpeg), not for the dev tools themselves — those belong in [tools].<br>The [system] section can also declare macOS defaults ([system.defaults]), applied by the same mise system install command.<br>Supported package managers <br>ManagerPlatformPageaptDebian, UbuntuaptdnfFedora, RHEL, CentOS, Rocky, AlmadnfpacmanArch, ManjaropacmanbrewmacOS (arm64), Linux (x86_64/arm64) — no Homebrew required brewSemantics <br>Declarative and additive — entries merge across the config hierarchy (global → project) as a union of keys. A project can add packages on top of the global list (and override a global entry's version pin) but not remove them.<br>OS-filtered — entries for a manager that isn't available on the current machine are not acted on, so the same config works across platforms: apt entries are ignored on macOS, dnf entries on Ubuntu, and so on (brew works on both macOS and Linux). mise system status and mise doctor still list unavailable managers so nothing is silently invisible.<br>Manual installation only — mise never installs system packages implicitly. mise install will print a one-time hint when packages are missing, but only mise system install ever installs anything.<br>Unknown managers are ignored with a warning so configs using managers from newer mise versions still parse.<br>Commands <br>shmise system status # table of requested vs installed packages<br>mise system status --json # machine-readable<br>mise system status --missing # exit 1 if anything is out of sync (CI check)
mise system install # install whatever is missing (prompts first)<br>mise system install apt:curl # install specific packages (configured or not)<br>mise system install --dry-run # print the commands without running them<br>mise system install --yes # skip the confirmation prompt<br>mise system install --manager apt<br>mise system install --update # refresh package manager metadata first
mise system use apt:curl brew:jq # add to [system.packages] and install<br>mise system use -g brew:ffmpeg # write to the global config instead<br>mise system use apt:curl@8.5.0-2 # pin a version (brew pins via the<br># formula name: brew:postgresql@17)
mise system upgrade # upgrade installed packages to current versions<br>mise system upgrade --manager brew<br>mise system use is mise use for system packages: it writes "manager:package" = "version" entries to mise.toml (the local file by default, the global one with -g) and installs whatever is missing. Entries for managers that aren't available on the current machine are written without installing — that's how a shared config picks up apt: lines authored on a Mac.<br>mise system upgrade refreshes package manager metadata and upgrades the configured packages that are already installed to the newest available version — apt and dnf also honor a version pinned in config (pacman and brew can't install pins, so pinned entries are skipped with a warning). Packages that aren't installed yet are skipped — that's mise system install's job. For brew this pours the formula's current bottle and replaces the old keg.<br>mise doctor also reports configured system packages and warns when any are missing.<br>Choosing which managers run <br>By default mise acts on every configured manager that is available on the current machine. Since availability implies the OS (apt only exists on Debian-family systems, brew wherever a bottle exists), this usually does the right thing without configuration.<br>If more than one manager could apply — several package managers installed on one machine, or a shared config listing managers you don't want here — pick a subset with the system_packages.managers setting:<br>toml[settings]<br>system_packages.managers = ["apt"]<br>This composes with platform-specific config files (mise.macos.toml, mise.linux.toml) when you want different selections per OS.<br>sudo <br>The Linux package managers require root. When not running as root, mise elevates with sudo, which prompts for...