Two commands to turn a fresh OS into a fully configured development environment.
Every fresh OS install means hours of manual setup: installing packages, configuring dotfiles, tweaking system preferences. This repo replaces that with two idempotent commands per OS. Pick a profile (minimal, developer, or full), run them, get back to building.
git clone https://github.com/BragatteMAS/os-postinstall-scripts
cd os-postinstall-scripts
./bootstrap.sh # prereqs: Homebrew + Bash 4+ on macOS, git/curl/build-essential on Linux
./setup.sh --dry-run # preview what will be installed
./setup.sh # install (default profile: developer)git clone https://github.com/BragatteMAS/os-postinstall-scripts
cd os-postinstall-scripts
powershell -ExecutionPolicy Bypass -File .\bootstrap.ps1 # prereqs: winget + Git
powershell -ExecutionPolicy Bypass -File .\setup.ps1 -DryRun
powershell -ExecutionPolicy Bypass -File .\setup.ps1 -Profile developerDon't have Git yet?
winget install Git.Git, restart PowerShell, then clone.
If you only want a modern terminal (CLI tools + prompt + aliases + zsh plugins) and don't need the full system setup, run the terminal blueprint directly:
git clone https://github.com/BragatteMAS/os-postinstall-scripts
bash os-postinstall-scripts/terminal-setup.sh --interactive # wizard — choose components
bash os-postinstall-scripts/terminal-setup.sh --dry-run # preview first
bash os-postinstall-scripts/terminal-setup.sh # install everythingWindows: examples/terminal-setup.ps1.
What it installs:
| Component | Details |
|---|---|
| Nerd Font | JetBrainsMono Nerd Font (auto-installed) |
| CLI tools | bat, eza, fd, fzf, ripgrep, delta, zoxide, starship |
| Prompt | MAS Oceanic Theme (powerline, git, languages, status bar) + 3 presets |
| Aliases | 50+ shortcuts for git, navigation, sysup, mkcd, gcb |
| Functions | Welcome message, h (help), preview (fzf), aliases (search) |
| Plugins | zsh-autosuggestions, zsh-syntax-highlighting, zsh-completions |
| Safety | --dry-run preview, --interactive wizard, automatic backups, idempotent |
Demo:
Since v5.1.4 the main
setup.shalso offers to run this at the end (interactive prompt). Skipping the prompt? Runbash terminal-setup.sh --interactivewhenever you like.
| Feature | Minimal | Developer | Full |
|---|---|---|---|
| System packages (apt / brew / winget) | ✓ | ✓ | ✓ |
| Dev tools + Rust CLI baseline | ✓ | ✓ | |
| GUI apps (cask / flatpak / snap) | ✓ | ✓ | |
| AI / MCP tools | ✓ | ||
| Personal preferences | ✓ | ||
| Estimated time | 2-5 min | 5-15 min | 10-30 min |
./setup.sh minimal # essentials only
./setup.sh developer # neutral dev defaults (default)
./setup.sh full # developer + extras (browsers, AI editors, design apps)Note:
fulladds opinionated personal extras (specific browsers, AI editors, design apps). If you want only neutral dev defaults without the curator's personal apps, usedeveloper.
Profile details: docs/installation-profiles.md.
The developer and full profiles install Rust-based replacements for traditional Unix tools:
| Traditional | Modern | Why |
|---|---|---|
cat |
bat |
syntax highlighting, line numbers |
ls |
eza |
icons, git status, tree view |
find |
fd |
intuitive syntax, respects .gitignore |
grep |
ripgrep (rg) |
faster, respects .gitignore |
cd |
zoxide (z) |
frequency-based smart jumping |
diff |
delta |
syntax-highlighted side-by-side |
Aliases configured via data/dotfiles/shared/aliases.sh. Full reference: docs/modern-cli-tools.md.
Skip every prompt —
./setup.sh -y fullruns end-to-end with no interactive questions. Use this when you want a hands-off install on a fresh machine.
./setup.sh --dry-run # preview, no changes
./setup.sh -y full # unattended full install (skips ALL prompts)
./setup.sh dotfiles # symlink dotfiles only
./setup.sh unlink # remove dotfile symlinks (restores backups)
./setup.sh defaults # macOS system defaults (Dock, Finder, etc.)
./setup.sh drift # report packages no longer in lists| Flag | Short | Env Var | Description |
|---|---|---|---|
--dry-run |
-n |
DRY_RUN=true |
preview without installing |
--verbose |
-v |
VERBOSE=true |
debug output with timestamps |
--unattended |
-y |
UNATTENDED=true |
skip confirmation prompts |
--groups |
-g |
GROUPS_MODE=true |
replace all-or-nothing cask install with interactive picker (10 curated groups) |
--help |
-h |
— | show help |
bash setup.sh --groups developer (or full) skips the default cask install
and shows an interactive multi-select. You pick which groups to install:
| Group | Apps |
|---|---|
browsers |
Firefox, Chromium, Chrome, Zen, Brave, Opera |
ai-editors |
Cursor, Zed, Claude (desktop + CLI), ChatGPT, Antigravity |
code-editors |
VS Code, Sublime Text, Warp, Positron, RStudio |
dev-infra |
Docker, OrbStack, DBeaver, Insomnia, GitHub Desktop |
productivity |
Rectangle, Alt-Tab, Raycast, HiddenBar, Caffeine, AppCleaner, Numi, MeetingBar |
communication |
Slack, Discord |
knowledge |
Obsidian, Zotero |
media |
IINA, Spotify, CapCut, Loom, Clop, Wispr Flow |
creative |
Inkscape, GIMP, Affinity |
essentials |
Bitwarden, Google Drive, LibreOffice, Logi Options+, Karabiner, Nerd fonts |
UI uses gum choose --no-limit (Charm's TUI) when available — bash numbered-menu
fallback otherwise. All formulae, Rust CSV tools, and AI tools install as usual.
Edit data/packages/groups/*.txt to customise.
Customization (extra packages, custom profiles, dotfiles): docs/user-guide.md.
| Platform | Package Managers | Architectures |
|---|---|---|
| Ubuntu / Pop!_OS / Mint | APT, Snap, Flatpak, Cargo, npm | x86_64, arm64 |
| macOS | Homebrew, Brew Cask, Cargo, npm | Intel + Apple Silicon |
| Windows 10/11 | WinGet, npm | x86_64 |
| Problem | Fix |
|---|---|
bash 3.2 too old on macOS |
run ./bootstrap.sh (or brew install bash) |
./setup.sh: Permission denied |
chmod +x setup.sh |
| APT lock on Linux | wait for unattended-upgrades / Software Center to finish |
winget: command not found |
update App Installer from Microsoft Store |
| PowerShell execution policy blocks script | use -ExecutionPolicy Bypass flag (shown in Quick Start) |
For mid-install failures with brew see the recovery cookbook in
docs/troubleshooting.md. Full pitfalls list:
docs/PITFALLS.md.
- Dry-run skips all sudo requests, network calls, and file mutations
- Existing dotfiles are backed up to
~/.dotfiles-backup/before any symlink ./setup.sh unlinkrestores original files from backups- Script never deletes files outside its own backup paths
For vulnerability reports: SECURITY.md.
| Topic | Where |
|---|---|
| Quick install guide | docs/quick-start.md |
| Complete usage | docs/user-guide.md |
| Profile details | docs/installation-profiles.md |
| Modern CLI tools | docs/modern-cli-tools.md |
| Old machine → new machine | docs/migration-guide.md |
| Shell history sync — atuin (optional) | docs/atuin.md |
| Troubleshooting + recovery cookbook | docs/troubleshooting.md |
| 47 cataloged pitfalls | docs/PITFALLS.md |
| Contributing | CONTRIBUTING.md |
| Changelog | CHANGELOG.md |
- Inspired by mathiasbynens/dotfiles, thoughtbot/laptop
- Static analysis via ShellCheck
- Diagrams via Mermaid
- Built with Claude Code as co-pilot (580+ commits)
Apache 2.0 — see LICENSE and NOTICE.
If this project helped you, a star helps others find it.

