Install Configuration¶
Define installation requirements per overlay under an install key in the
overlay config (TOML/YAML). Supports system package managers and
language-specific installers with optional pre/post script hooks. See
ADR-004
for the design behind this.
Supported managers:
- System:
archlinux,apt,brew,winget - Language:
cargo,python(uv, pipx, pip),node(npm)
Forms¶
Each manager accepts either a flat list (shorthand) or a full object with
packages, pre, post (and manager-specific fields):
Flat (YAML):
install:
archlinux:
- pkg1
- pkg2
apt:
- curl
brew:
- jq
cargo:
- ripgrep
python:
- requests
node:
- typescript
winget:
- Git.Git
Flat (TOML):
[install]
archlinux = ["pkg1", "pkg2"]
apt = ["curl"]
brew = ["jq"]
cargo = ["ripgrep"]
python = ["requests"]
node = ["typescript"]
winget = ["Git.Git"]
Full (YAML):
install:
pre:
- echo "setup"
archlinux:
packages: [pkg1, pkg2]
apt:
packages: [curl]
brew:
taps: [my/tap]
packages:
- name: jq
- name: firefox
cask: true
cargo:
packages:
- name: ripgrep
locked: true
- git: https://github.com/sharkdp/fd
tag: v9.0.0
python:
packages:
- name: requests
tool: uv
extras: [security]
- name: black
tool: pipx
node:
packages:
- name: typescript
options: "--force"
winget:
packages:
- name: Git.Git
- id: Microsoft.VisualStudioCode
post:
- echo "done"
Full (TOML):
[install]
pre = ['echo "setup"']
archlinux.packages = ["pkg1", "pkg2"]
apt.packages = ["curl"]
brew.taps = ["my/tap"]
brew.packages = [
{ name = "jq" },
{ name = "firefox", cask = true }
]
cargo.packages = [
{ name = "ripgrep", locked = true },
{ git = "https://github.com/sharkdp/fd", tag = "v9.0.0" }
]
python.packages = [
{ name = "requests", tool = "uv", extras = ["security"] },
{ name = "black", tool = "pipx" }
]
node.packages = [
{ name = "typescript", options = "--force" }
]
winget.packages = [
{ name = "Git.Git" },
{ id = "Microsoft.VisualStudioCode" }
]
post = ['echo "done"']
Brew Package Options¶
Brew packages can specify options (string split by whitespace) and
cask: true to install via the cask tap. The --cask flag is automatically
added when cask: true and de-duplicated if already present in options.
Cargo Packages¶
Fields: name, version, git, tag, branch, rev, path, features
(array), locked (bool), options (extra flags). Provide one of: name
only, git + optional tag/branch/rev + optional name, or path.
Python Packages¶
Fields: name, tool (one of uv, pipx, pip or omit for auto),
extras (array), options (additional flags). Auto selection prefers uv,
then pipx, then pip based on availability.
Node Packages¶
Installed globally via npm install -g. Field: name, optional options
appended to the command before the package name.
Winget Packages¶
Fields: name (display name), id (winget package identifier), optional
options (extra flags). Provide either name or id to identify the
package.
Precedence & Execution Order¶
Order:
- Global
prescripts - Platform
prescripts - System managers (Linux precedence determined by distro; macOS: brew; Windows: winget)
- Language managers (
cargo,python,node) - Platform
postscripts - Global
postscripts
Linux system manager precedence:
- Arch: archlinux, brew
- Debian/Ubuntu: apt, brew
- Other: archlinux, apt, brew (attempt those present)
If a platform section matching the distro exists, all listed managers in precedence order run; otherwise the first available top-level manager only.
Platform Sections¶
Add distro/OS-specific overrides using keys inside install matching the
/etc/os-release ID (e.g. ubuntu, debian, arch) or macos/
windows. These mirror top-level structure but apply only on that
platform.
Note: archlinux is not a valid platform-section key — it's already
the top-level Arch package manager field shown above, so
[install.archlinux] sets that manager's config, not a platform override
(the actual Arch platform key is arch, matching the real
/etc/os-release ID). Package extraction across uses dependencies
does accept archlinux as an alias for arch when looking up platform
sections, but the other manager/pre/post resolution paths do not —
use arch to be safe.
Scripts¶
Each manager can define its own pre / post arrays executed immediately
before/after that manager's install step.
Windows¶
Windows is supported via winget as the system package manager. Language
managers (cargo, python, node) work the same as on other platforms.
Platform-specific overrides use the windows key inside install.
Composition via Uses¶
Packages from overlays referenced in uses are merged (set union) to avoid
duplicates across overlays. See
ADR-008.