Mac Installation Logging Guide#

A simple reference for tracking everything installed on your Mac, saved to a plain text file.


Wrap your package managers with a logging function. Add this to your ~/.zshrc or ~/.bashrc:

# Installation Logger
INSTALL_LOG="$HOME/install_log.txt"

log_install() {
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" >> "$INSTALL_LOG"
}

# Wrap brew
brew() {
  command brew "$@"
  if [[ "$1" == "install" ]]; then
    log_install "brew install ${@:2}"
  fi
}

# Wrap pip
pip() {
  command pip "$@"
  if [[ "$1" == "install" ]]; then
    log_install "pip install ${@:2}"
  fi
}

# Wrap pip3
pip3() {
  command pip3 "$@"
  if [[ "$1" == "install" ]]; then
    log_install "pip3 install ${@:2}"
  fi
}

# Wrap npm global installs
npm() {
  command npm "$@"
  if [[ "$1" == "install" && ("$2" == "-g" || "$2" == "--global") ]]; then
    log_install "npm install ${@:2}"
  fi
}

After adding, run source ~/.zshrc. Every install will append to ~/install_log.txt like:

[2026-05-10 14:32:01] brew install wget
[2026-05-10 14:45:12] pip3 install pandas
[2026-05-10 15:01:55] npm install -g typescript

2. Periodic Snapshots (Passive, No Effort)#

For a full inventory rather than a changelog, run this as a cron job or manually:

# Add to crontab (runs every Sunday at midnight): crontab -e
0 0 * * 0 {
  echo "=== Snapshot: $(date) ===" >> ~/install_log.txt
  echo "-- Brew --"          >> ~/install_log.txt && brew list             >> ~/install_log.txt
  echo "-- Pip --"           >> ~/install_log.txt && pip3 list             >> ~/install_log.txt
  echo "-- npm global --"    >> ~/install_log.txt && npm list -g --depth=0 >> ~/install_log.txt
  echo "-- /Applications --" >> ~/install_log.txt && ls /Applications      >> ~/install_log.txt
}

3. One-Shot Full Inventory (Right Now)#

Run this block in your terminal to generate a complete snapshot immediately:

{
  echo "=== Mac Install Inventory: $(date) ==="
  echo ""
  echo "--- Homebrew Formulae ---"
  brew list --formula
  echo ""
  echo "--- Homebrew Casks (GUI apps) ---"
  brew list --cask
  echo ""
  echo "--- pip3 packages ---"
  pip3 list
  echo ""
  echo "--- npm global ---"
  npm list -g --depth=0
  echo ""
  echo "--- /Applications ---"
  ls /Applications
} > ~/install_inventory.txt

Output is saved to ~/install_inventory.txt.


4. Watch /Applications for Changes (launchd)#

To detect new apps as they are added, use a launchd watcher instead of cron.

Create the file ~/Library/LaunchAgents/com.user.appwatcher.plist:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
  "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.user.appwatcher</string>
  <key>ProgramArguments</key>
  <array>
    <string>/bin/sh</string>
    <string>-c</string>
    <string>echo "[$(date '+%Y-%m-%d %H:%M:%S')] APP CHANGE DETECTED:" >> ~/install_log.txt && ls /Applications >> ~/install_log.txt && echo "---" >> ~/install_log.txt</string>
  </array>
  <key>WatchPaths</key>
  <array>
    <string>/Applications</string>
  </array>
</dict>
</plist>

Load it with:

launchctl load ~/Library/LaunchAgents/com.user.appwatcher.plist

This triggers automatically whenever anything changes in /Applications — no polling needed.


Quick Reference#

GoalApproach
Track when something was installedScript-based wrapper (Section 1)
Know what’s currently installedOne-shot inventory (Section 3)
Weekly automated snapshotCron job (Section 2)
Detect new GUI apps instantlylaunchd watcher (Section 4)
Complete setupCombine Section 1 + Section 2 + Section 4