Opinionated macOS + Linux dev environment. zsh, modern CLI replacements, package managers layered intentionally, scripts for the boring parts. Battle-tested on a daily-driver M1 Pro, with the configs validated on macOS and Linux VM guests (see Tested on).
Not a framework. Not a one-command installer. A reference set of configs and decisions you can read, understand, and adapt.
| Section | What it covers |
|---|---|
shell/ |
zsh, Oh-My-Zsh (curated plugins only), Powerlevel10k |
git/ |
git config, SSH commit signing, useful aliases |
cli-tools/ |
bat, ripgrep, fzf, eza, fd, zoxide, delta, htop, procs |
packages/ |
Brewfile (macOS + Linux), apt package list |
nix/ |
Home Manager — cross-platform declarative config |
python/ |
Miniconda setup, env patterns, ML environment example |
node/ |
NVM with lazy-loading |
scripts/ |
System health check, safe cleanup, update-everything |
vms/ |
Running Linux VMs on macOS (UTM, VMware) and Linux (VirtualBox) |
docs/ |
The thinking behind the choices — installation order, PATH, shell load order, package manager decisions |
You probably don't want to clone and apply this as-is — opinionated configs are personal, and "personal" is the whole point.
The intended path:
- Read
docs/installation-order.mdfirst. Setup order matters more than the configs themselves. - Browse the sections that match what you need. Each has its own README with the why, then the what.
- Copy what you like. Files are not interdependent — you can take the shell config without the Nix setup, or the scripts without the aliases.
- Manage your dotfiles however you want. When you have enough configs to make tracking annoying, look at YADM, GNU Stow, chezmoi, or a bare git repo. This repo doesn't pick one for you.
These show up in every section. Naming them upfront so the choices read consistently.
1. Package managers exist for a reason — use them, in the right order.
System-level tools via the OS package manager (Homebrew on macOS, apt/dnf on Linux). Language runtimes via their dedicated managers (NVM, Miniconda, rustup). Project deps via project-local tools (venv, npm). Globally pip install-ing things is how PATH gets ugly.
2. Modern CLI replacements pay for themselves.
bat > cat, eza > ls, fd > find, rg > grep, zoxide > cd, delta > git's default diff. Set them up once, they're better forever.
3. Configs should explain themselves. Comments in config files. READMEs that justify decisions. The next person reading this — including future-you on a new machine — should understand why something is set the way it is, not just what.
4. Don't fight the platform.
macOS expects ~/Library/. Linux expects ~/.config/. Both expect XDG Base Directory where applicable. The configs here respect that — they don't try to make macOS feel like Linux or vice versa.
5. Reversible over clever.
Aliases for rm, cp, mv include -i (interactive). Scripts avoid rm -rf; they mv to Trash instead. Backups before destructive operations. The five seconds of friction is worth it.
If you want to lift just the bones of this in 30 minutes:
# 1. Install Homebrew (or Linuxbrew on Linux)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# 2. Install the modern CLI replacements
brew install zsh git bat eza fd ripgrep fzf zoxide git-delta htop procs
# 3. Install Oh-My-Zsh
sh -c "$(curl -fsSL https://raw.githubusercontent.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"
# 4. Install Powerlevel10k
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
# 5. Pull this repo's shell config as a reference
git clone https://github.com/asifulshiam/dotfiles.git ~/dotfiles-referenceThen read shell/README.md to apply the configs.
For the full philosophy and longer setup, start with docs/installation-order.md.
| Platform | Version | Notes |
|---|---|---|
| macOS Tahoe 26 | currently 26.4.1 (Apple Silicon, M1 Pro) | Primary target — daily driver across the whole 26 line. zsh 5.9 default shell. |
| macOS Sequoia 15 | 15.7.7 (ARM, VM guest) | Configs parse clean; check_system.sh runs and degrades gracefully on a stock system (reports absent tooling rather than erroring). |
| Ubuntu | 24.04.4 LTS (aarch64, VM guest) | zsh 5.9. All shell configs parse clean; macOS-only sections are $OSTYPE-guarded and skipped automatically; the Brewfile Linux-derive snippet works. |
The two VM guests above are ARM (aarch64) and were validated at the config-load + script-run level, not full daily-driver use. Ubuntu 24.04 is the base most Mint/Debian derivatives share, so those should work too. x86_64/AMD64 Linux, Fedora, and Arch are not yet personally tested — the configs are written portably, so if something breaks on your setup, open an issue. It's useful feedback even if I don't fix it personally.
Retest cadence: the macOS row is re-verified on each major macOS release; the Linux rows are spot-checked when the configs change materially. Untested platforms above are the standing to-do.
This repo doesn't cover Windows directly. Three paths if you want a similar setup on Windows:
- WSL2 (recommended) — install Ubuntu via WSL2, then most of this repo applies as-is to the Linux side. Best of both worlds for development.
- Virtual machine — VirtualBox or Hyper-V with a Linux guest. Heavier, but fully isolated.
- Native Windows — Scoop or Chocolatey for package management, winget for built-ins. You'll need to adapt most things; PowerShell ≠ zsh.
I don't test on Windows. The configs here aren't designed for it. Caveat emptor.
MIT — fork, copy, adapt freely. Attribution appreciated but not required.
