macOS 26.3.1 (Apple Silicon) workstation configuration. Everything is installed via Homebrew 5.1.0 unless noted otherwise.
The default macOS command-line tools were designed decades ago and show their age. They produce dense, uncolored output, ignore modern conventions like .gitignore, and lack features developers now take for granted (syntax highlighting, git awareness, fuzzy search). This setup replaces them with modern alternatives — mostly written in Rust — that are faster, produce more readable output, and work the way you'd expect in a git-centric workflow. Every replacement is aliased to the original command name so muscle memory carries over.
| Tool | Replaces | Why |
|---|---|---|
| Homebrew | — | Single package manager for installing and updating everything else in this list |
| bat | cat |
Adds syntax highlighting to file output so you can actually read code in the terminal |
| eza | ls, tree |
Shows git status, file icons, and relative timestamps inline — context that ls forces you to get elsewhere |
| fd | find |
Sane defaults (recursive, ignores .gitignore, regex) without the arcane flag syntax of find |
| ripgrep | grep |
Searches entire codebases in milliseconds with automatic .gitignore and binary file filtering |
| dust | du |
Answers "what's using all the space" instantly with a sorted visual bar chart instead of raw numbers |
| duf | df |
Groups volumes by type with usage bars — readable at a glance instead of a wall of numbers |
| procs | ps |
Human-readable process output with color, keyword search, and CPU/memory percentages |
| btop | top |
Full system dashboard with per-core graphs, disk I/O, and network — replaces the need for multiple tools |
| GNU sed/tar/make | BSD variants | Eliminates cross-platform gotchas where scripts written for Linux break silently on macOS BSD tools |
| tldr | man |
Shows the 5 examples you actually need instead of a 2000-line man page |
| fzf | — | Adds fuzzy search to shell history, file paths, and directories — faster than tab completion for deep trees |
| zoxide | cd |
Learns your most-used directories so z proj replaces typing full paths you visit daily |
| mise | nvm, pyenv, etc. |
One tool manages all language runtimes per-project instead of juggling separate version managers |
| Starship | — | Shows git branch, status, and context at a glance without cluttering the prompt with noise |
brew install bat eza fd ripgrep dust duf procs btop fzf zoxide mise starship tldr gnu-sed gnu-tar makeThe default macOS shell. Configuration lives in ~/.zshrc.
Zsh completions are loaded at shell startup with compinit. The rehash style is enabled so that newly installed binaries are immediately available for tab completion without opening a new shell:
autoload -Uz compinit && compinit
zstyle ':completion:*' rehash trueDuplicated iTerm2 tabs reset to the home directory instead of inheriting the previous tab's working directory:
if [[ -o interactive && -n "$ITERM_SESSION_ID" && "$PWD" != "$HOME" ]]; then
export ITERM_ORIG_DIR="$PWD"
cd ~
fi- Homebrew:
/opt/homebrew/bin(added viabrew shellenv) - User-local binaries:
~/.local/bin(Claude Code CLI, etc.)
The standard package manager for macOS. Handles installation, updates, and dependency management for all CLI tools and many desktop applications. Installed at /opt/homebrew on Apple Silicon Macs. The shell environment is configured at the top of .zshrc via eval "$(/opt/homebrew/bin/brew shellenv)", which adds Homebrew's bin, sbin, and related paths to the shell environment. All CLI tools documented below are installed via brew install <name>.
Every legacy Unix command below is aliased to a modern replacement. Most are written in Rust, offering significant speed improvements and better default output. To bypass an alias and access the original command, use command <cmd> or \<cmd>.
A cat clone with syntax highlighting, git integration, and automatic paging. Supports hundreds of languages and file formats out of the box. Can show line numbers, git diff markers, and file headers. In this setup it is aliased with --paging=never --style=plain so it behaves like a drop-in cat replacement that adds syntax highlighting without altering output flow. When you need the full feature set (line numbers, grid, headers), call bat directly with different flags.
alias cat='bat --paging=never --style=plain'A modern replacement for ls built in Rust. Provides color-coded output, file type icons (via Nerd Fonts), native git status per file, and human-readable metadata. Unlike ls, eza understands git repositories and shows whether each file is modified, staged, or untracked directly in the listing. It also replaces tree with a built-in --tree flag that produces the same recursive directory view with all the same enhancements.
Three aliases are configured:
-
ls— Long-format listing with icons, directories grouped first, git status column, and relative timestamps (e.g., "2 hours ago" instead of "Mar 24 14:32"):alias ls='eza -l --icons=auto --group-directories-first --git --time-style=relative'
-
ll— Same aslsbut includes hidden files (-a) and adds a column header row:alias ll='eza -la --icons=auto --group-directories-first --git --header --time-style=relative'
-
tree— Recursive tree view with icons and directories first:alias tree='eza --tree --icons=auto --group-directories-first'
A fast, user-friendly alternative to find. Uses sensible defaults: ignores hidden files and .gitignore patterns by default, uses regex patterns instead of -name glob syntax, and searches recursively from the current directory without requiring . as an argument. Significantly faster than find on large directory trees due to parallelized traversal. Supports colored output and can execute commands on results similar to find -exec. Common usage: fd 'pattern' to find files matching a pattern, fd -e py to find all Python files, fd -t d to find only directories.
alias find='fd'A line-oriented search tool that recursively searches directories for regex patterns. Built in Rust with PCRE2 support and SIMD acceleration. Automatically respects .gitignore rules, skips hidden files and binary files, and searches recursively by default. Substantially faster than grep -r on large codebases — often 2-5x faster than alternatives. Provides colored output with line numbers and file paths. Supports file type filtering (rg -t py 'pattern'), replacement (rg -r 'replacement'), multiline search, and JSON output for tooling integration. The --pcre2 flag enables lookaheads and other advanced regex features.
alias grep='rg'A more intuitive disk usage tool written in Rust. Instead of the flat, hard-to-read output of du, dust presents disk usage as a visual bar chart sorted by size, making it immediately obvious which directories and files are consuming the most space. It traverses directories in parallel for speed, displays sizes in human-readable format, and shows a percentage bar next to each entry. By default it shows the biggest items first and limits depth to keep output readable. Useful for quickly finding what is eating disk space without piping du through sort and head.
alias du='dust'A better df that displays disk usage and free space for all mounted volumes in a clean, color-coded table. Groups output by device type (local disks, network volumes, special devices) and shows usage bars alongside the numbers. Much easier to read at a glance than the default df -h output, especially on systems with many mount points. Shows total, used, available, and percentage for each filesystem.
alias df='duf'A modern process viewer written in Rust that provides color-coded, human-readable output. Unlike ps, procs displays memory and CPU usage with readable formatting, shows the full command tree, and supports keyword searching across all process fields. Configured here as a shell function: with no arguments it shows the top 20 processes by CPU usage (useful as a quick "what's using resources" check); with arguments it searches across process names, PIDs, and other fields.
ps() { if [[ $# -eq 0 ]]; then command procs | head -22; else command procs "$@"; fi }A terminal-based resource monitor with a rich TUI. Shows CPU usage per core with graphs, memory and swap usage with bar charts, disk I/O, network activity, and a full process list — all in a single interactive dashboard. Supports mouse interaction, process sorting, filtering, tree view, and sending signals to processes. Provides a much denser and more useful overview of system health than top or htop.
alias top='btop'macOS ships with BSD versions of sed, tar, and make that have subtle syntax differences from their GNU counterparts. Most online documentation and build scripts assume GNU behavior. These aliases ensure consistent behavior across macOS and Linux, avoiding common issues like sed -i requiring a backup extension on BSD, tar lacking --transform, or make missing features like $(file ...) functions. Installed via Homebrew as gsed, gtar, gmake and aliased to the standard command names.
alias sed='gsed'
alias tar='gtar'
alias make='gmake'Community-maintained, simplified help pages for command-line tools. Instead of the exhaustive but dense man pages, tldr shows the most common usage examples for a command in a concise, practical format. Covers thousands of commands and is especially useful for quickly remembering the syntax for tools you don't use daily. Aliased to help for natural usage: help tar, help ffmpeg, etc.
alias help='tldr'A muted color palette is set via EZA_COLORS. Directories are bold, most metadata is dimmed, and git status indicators use color:
| Git Status | Color |
|---|---|
| New (staged) | bold green |
| Modified | bold yellow |
| Deleted | bold red |
| Renamed | bold blue |
| Type change | bold yellow |
| Conflicted | bold red |
| Ignored | dimmed |
A general-purpose command-line fuzzy finder. It reads lines from stdin (or from a file list) and presents an interactive, filterable selection interface. As you type, it narrows results in real time using a fuzzy matching algorithm — you don't need to type exact strings or remember full paths. It integrates deeply with the shell via key bindings that replace the default behaviors for history search, file insertion, and directory navigation. It can also be piped into from any command (git log | fzf, brew list | fzf, etc.) to add interactive filtering to anything.
Loaded via source <(fzf --zsh), which installs the following shell keybindings:
| Keybinding | Action |
|---|---|
Ctrl-R |
Replaces the default reverse history search with a fuzzy-searchable, full-screen history browser. Shows all previous commands and filters as you type. Selected command is placed on the command line ready to edit or execute. |
Ctrl-T |
Recursively lists all files under the current directory, lets you fuzzy-search through them, and inserts the selected file path at the cursor position. Useful for building commands without manually typing paths. |
Alt-C |
Recursively lists all directories under the current directory, lets you fuzzy-search, and cds into the selected directory. Faster than navigating with cd and tab completion for deeply nested paths. |
A smarter cd that learns which directories you visit most frequently. Every time you cd into a directory (or use z), zoxide records it in a local database and ranks directories by frequency and recency of access. You can then jump to any previously visited directory by typing just a fragment of its name — z proj might jump to ~/projects, z doc to ~/docs, etc. If multiple directories match, zoxide picks the highest-ranked one. Use zi for an interactive selection when multiple matches exist. This eliminates the need to type or remember full paths for directories you visit regularly. Activated via eval "$(zoxide init zsh)".
A polyglot runtime version manager that handles installing and switching between versions of languages and tools like Node.js, Python, Go, Ruby, Java, Terraform, and hundreds of others. It replaces tools like nvm, pyenv, rbenv, and asdf with a single, faster alternative written in Rust.
mise works by shimming or hooking into your shell to automatically activate the correct tool versions when you enter a project directory. Per-project versions are defined in .mise.toml or .tool-versions files at the project root. When you cd into a directory containing one of these files, mise ensures the correct versions are on your PATH. This means different projects can use different Node or Python versions without manual switching.
Activated via eval "$(mise activate zsh)". No global tool versions are currently configured — all version pinning is done per-project.
A minimal, fast, cross-shell prompt written in Rust. Starship dynamically assembles the prompt each time you hit Enter, detecting the current context (git repo, language project, Docker environment, etc.) and displaying only the relevant information. It is fast enough that there is no perceptible delay, even with git status checks on large repositories. It works identically across zsh, bash, fish, and other shells, so the same config file works everywhere.
Configured at ~/.config/starship.toml. Must be initialized last in .zshrc so it can wrap the prompt after all other tools have set up their hooks.
<user>@<hostname> <directory> on <git_branch> [<git_status>] took <duration>
❯ <time>
- Left side: user, host, directory (truncated to 5 segments), git branch/status, command duration (if >1s)
- Right side: current time (12-hour format)
- Prompt character:
❯(white on success, red on error)
Everything uses white/dimmed white for a minimal, low-contrast look. Language version indicators (Node.js, Python, Bun) and package version are disabled to keep the prompt clean.
format = """
$username\
$hostname\
$directory\
$git_branch\
$git_status\
$docker_context\
$cmd_duration\
$line_break\
$jobs\
$character"""
right_format = "$time"Key sections:
| Module | Setting |
|---|---|
username |
Always shown |
hostname |
Always shown, trimmed at first . |
directory |
5 segments max, does not truncate to repo root |
git_branch |
Branch name with dimmed style |
git_status |
Shown in brackets |
cmd_duration |
Shown if command took >1 second |
time |
Right-aligned, 12-hour format |
character |
❯ white/red |
package, nodejs, python, bun |
Disabled |
| File | Purpose |
|---|---|
~/.zshrc |
Shell config, aliases, tool initialization |
~/.config/starship.toml |
Prompt configuration |
~/.config/mise/config.toml |
mise global config (if used) |