docs/bootstrap/packages/index.md
mise can ensure machine-global system packages are installed via the
[bootstrap.packages] section of mise.toml:
[bootstrap.packages]
"apt:libssl-dev" = "latest"
"apt:build-essential" = "latest"
"brew:postgresql@17" = "latest"
"brew:ffmpeg" = "latest"
"brew-cask:firefox" = "latest"
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).
mise can also place config files (dotfiles) — see
Dotfiles, which uses mise dotfiles commands.
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 and
brew-cask, by mise's built-in Homebrew installers, which don't require
Homebrew itself. Use them for shared libraries, build dependencies, and
machine-global GUI apps (libssl-dev, postgresql, ffmpeg, firefox),
not for project dev tools — those belong in [tools].
The [bootstrap] section can also declare
macOS defaults ([bootstrap.macos.defaults]),
applied by mise bootstrap macos-defaults apply. Current-user
login shells ([bootstrap.user].login_shell) are
applied by mise bootstrap user apply or mise bootstrap.
| Manager | Platform | Page |
|---|---|---|
apt | Debian, Ubuntu | apt |
dnf | Fedora, RHEL, CentOS, Rocky, Alma | dnf |
pacman | Arch, Manjaro | pacman |
brew | macOS (arm64), Linux (x86_64/arm64) — no Homebrew required | brew |
brew-cask | macOS — no Homebrew required | brew |
apt
entries are ignored on macOS, dnf entries on Ubuntu, and so on. brew
works on both macOS and Linux; brew-cask works on macOS. Status commands
still list unavailable managers so nothing is silently invisible.mise install will print a one-time hint when packages are
missing, but only mise bootstrap packages install ever installs anything.For current-user login shell setup, use [bootstrap.user].login_shell:
[bootstrap.user]
login_shell = "/bin/zsh"
See User Login Shell for details.
mise bootstrap packages status # table of requested vs installed packages
mise bootstrap packages status --json # machine-readable
mise bootstrap packages status --missing # exit 1 if anything is out of sync (CI check)
mise bootstrap packages install # install whatever is missing (prompts first)
mise bootstrap packages install apt:curl # install specific packages (configured or not)
mise bootstrap packages install --dry-run # print the commands without running them
mise bootstrap packages install --yes # skip the confirmation prompt
mise bootstrap packages install --manager apt
mise bootstrap packages install --update # refresh package manager metadata first
mise bootstrap packages use apt:curl brew:jq brew-cask:firefox # add and install
mise bootstrap packages use -g brew:ffmpeg # write globally
mise bootstrap packages use apt:[email protected] # pin a version (brew pins via the
# formula name: brew:postgresql@17)
mise bootstrap packages upgrade # upgrade installed packages to current versions
mise bootstrap packages upgrade --manager brew
mise bootstrap packages upgrade --manager brew-cask
mise bootstrap packages 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.
mise bootstrap packages 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, brew,
and brew-cask can't install pins, so
pinned entries are skipped with a warning). Packages that aren't installed
yet are skipped — that's mise bootstrap packages install's job. For brew
this pours the formula's current bottle and replaces the old keg; for
brew-cask this installs the current cask artifact.
mise doctor also reports configured system packages and warns when any are
missing.
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.
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:
[settings]
system_packages.managers = ["apt"]
This composes with platform-specific config files
(mise.macos.toml, mise.linux.toml) when you want different selections per
OS.
The Linux package managers require root. When not running as root, mise
elevates with sudo, which prompts for your password as usual. The same
sudo path is used when [bootstrap.user].login_shell needs to add a shell to
/etc/shells, and it only happens during an explicit mise bootstrap:
sudo apt-get install ... with a normal sudo
promptSet system_packages.sudo = false to forbid
elevation entirely; mise will print the command for you to run yourself
instead. The brew manager never needs sudo except once to create
/opt/homebrew (see brew).
In containers you're typically already root, so no prompts occur:
mise bootstrap packages install --yes
mise install
mise bootstrap --yes combines both (and runs a task
named bootstrap afterwards, if one is defined) — one command to set up a
fresh machine or container.
mise bootstrap packages status --missing exits 1 when packages are missing, which makes
a convenient CI check without installing anything.