Skip to content

Instantly share code, notes, and snippets.

@sashaaldrick
Last active August 31, 2025 19:32
Show Gist options
  • Save sashaaldrick/648a0994626cf83f4c029136167164b8 to your computer and use it in GitHub Desktop.
Save sashaaldrick/648a0994626cf83f4c029136167164b8 to your computer and use it in GitHub Desktop.
macOS bootstrap setup script
#!/usr/bin/env bash
# run with '/bin/bash -c "$(curl -fsSL https://setup.sasha.computer)"'
set -euo pipefail
echo "That Fresh Mac Feeling..."
###############################################################################
# Xcode Command Line Tools and Rosetta
###############################################################################
echo "Installing Xcode Command Line Tools..."
xcode-select --install 2>/dev/null || echo "Xcode CLI tools already installed or prompt already shown."
echo "Installing Rosetta 2..."
# Check if Rosetta 2 is already installed
if /usr/bin/pgrep oahd >/dev/null 2>&1; then
echo "Rosetta 2 is already installed."
else
echo "Rosetta 2 is not installed. Installing now..."
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
if [ $? -eq 0 ]; then
echo "Rosetta 2 installation succeeded."
else
echo "Rosetta 2 installation failed."
exit 1
fi
fi
###############################################################################
# Homebrew Setup
###############################################################################
if [ ! -x "/opt/homebrew/bin/brew" ]; then
echo "Installing Homebrew..."
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
eval "$(/opt/homebrew/bin/brew shellenv)"
else
echo "Homebrew already installed"
eval "$(/opt/homebrew/bin/brew shellenv)"
fi
brew update
###############################################################################
# Git Config
###############################################################################
echo "Configuring Git..."
git config --global user.name "Sasha Aldrick"
git config --global user.email "[email protected]"
###############################################################################
# Shell (fish installed and set as default)
###############################################################################
FISH_PATH="/opt/homebrew/bin/fish"
if command -v fish &>/dev/null; then
echo "fish shell already installed."
else
echo "Installing fish shell..."
brew install fish
fi
# Add fish to allowed shells if not already present
if ! grep -q "$FISH_PATH" /etc/shells; then
echo "$FISH_PATH" | sudo tee -a /etc/shells
fi
# Set fish as default shell if not already
if [[ "$SHELL" != "$FISH_PATH" ]]; then
echo "Setting fish as the default shell..."
chsh -s "$FISH_PATH"
else
echo "fish is already the default shell"
fi
echo "Installing Jetbrains Mono Fonts..."
brew install --cask font-jetbrains-mono-nerd-font
brew install --cask font-jetbrains-mono
echo "Installing Starship prompt..."
brew install starship
echo "Configuring Starship prompt for fish shell..."
CONFIG_FISH="$HOME/.config/fish/config.fish"
# Ensure the directory exists
mkdir -p "$(dirname "$CONFIG_FISH")"
# Ensure the file exists
touch "$CONFIG_FISH"
# Append only if not already present
if ! grep -q 'starship init fish | source' "$CONFIG_FISH"; then
echo 'starship init fish | source' >> "$CONFIG_FISH"
fi
touch ~/.hushlogin
if [ ! -d "$HOME/Developer" ]; then
mkdir -p "$HOME/Developer"
echo "Created ~/Developer directory."
else
echo "~/Developer already exists."
fi
CONFIG_FISH="$HOME/.config/fish/config.fish"
if ! grep -qxF 'set fish_greeting ""' "$CONFIG_FISH"; then
echo 'set fish_greeting ""' >> "$CONFIG_FISH"
fi
#############################################################
# TouchID Sudo #
#############################################################
PAM_FILE="/etc/pam.d/sudo"
BACKUP_FILE="/etc/pam.d/sudo.bak.$(date +%Y%m%d%H%M%S)"
# Check if the line is already present
if grep -q "^auth\s\+sufficient\s\+pam_tid.so" "$PAM_FILE"; then
echo "Touch ID for sudo is already enabled."
fi
# Backup original file
echo "Backing up $PAM_FILE to $BACKUP_FILE"
sudo cp "$PAM_FILE" "$BACKUP_FILE"
# Insert the line at the top of the file
echo "Enabling Touch ID for sudo..."
sudo sed -i '' '1i\
auth sufficient pam_tid.so
' "$PAM_FILE"
echo "Done! Test with 'sudo ls'."
###############################################################################
# Application Installs
###############################################################################
echo "Installing applications via Homebrew Cask..."
brew install --cask 1password
brew install --cask raycast
brew install --cask visual-studio-code
brew install --cask appcleaner
brew install --cask slack
brew install --cask signal
brew install --cask telegram
brew install --cask spotify
brew install --cask brave-browser
brew install --cask little-snitch
brew install --cask battery
brew install --cask orion
brew install --cask vlc
brew install --cask runelite
brew install nextdns
echo "Cleaning up Homebrew cache and outdated versions..."
brew cleanup
###############################################################################
# Rust Install
###############################################################################
echo "Checking for Rust installation..."
if command -v rustc &>/dev/null; then
echo "✅ Rust is already installed."
else
echo "Installing Rust using rustup..."
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
echo "✅ Rust installed. Restart your terminal to use it."
fi
###############################################################################
# macOS System Preferences
###############################################################################
echo "Configuring macOS defaults..."
# Autocorrect
defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false
# Mission Control
defaults write com.apple.dock expose-animation-duration -float 0.1
defaults write com.apple.dock expose-group-by-app -bool true
defaults write NSGlobalDomain NSAutomaticWindowAnimationsEnabled -bool false
# Dock
defaults write com.apple.dock autohide -bool true
defaults write com.apple.dock autohide-delay -float 0
defaults write com.apple.dock autohide-time-modifier -float 0
defaults write com.apple.dock tilesize -int 96
defaults write com.apple.dock persistent-apps -array
defaults write com.apple.dock show-recents -bool false;
killall Dock
# Finder
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false
defaults write com.apple.finder FXPreferredViewStyle Clmv
defaults write com.apple.finder ShowStatusBar -bool true
defaults write com.apple.finder ShowPathbar -bool true
defaults write com.apple.finder AppleShowAllFiles -bool true
defaults write com.apple.finder FXPreferredViewStyle -string "Nlsv" # List view
defaults write com.apple.finder ShowRecentTags -bool false
defaults write com.apple.finder SidebarShowCloudDrive -bool false
defaults write com.apple.finder SidebarShowICloudDocuments -bool false
defaults write com.apple.finder FXPreferredGroupBy -string "Kind"
defaults write com.apple.finder FXArrangeBy -string "date-modified"
defaults write com.apple.finder FXArrangeAscending -bool false
killall Finder
# disable photos from auto opening
defaults -currentHost write com.apple.ImageCapture disableHotPlug -bool true
# disable quicktime auto opening
defaults write com.apple.QuickTimePlayerX MGPlayMovieOnOpen -bool true
# Keyboard/Input
defaults write NSGlobalDomain ApplePressAndHoldEnabled -bool false
defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false
defaults write NSGlobalDomain NSAutomaticPeriodSubstitutionEnabled -bool false
defaults write NSGlobalDomain KeyRepeat -int 2
defaults write NSGlobalDomain InitialKeyRepeat -int 15
# Save & Print Panels Expanded
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true
defaults write NSGlobalDomain PMPrintingExpandedStateForPrint -bool true
defaults write NSGlobalDomain PMPrintingExpandedStateForPrint2 -bool true
# Software update check frequency
defaults write com.apple.SoftwareUpdate ScheduleFrequency -int 1
# Mouse and Trackpad
defaults write -g com.apple.trackpad.scaling -float 2
defaults write -g com.apple.mouse.scaling -float 2.5
###############################################################################
# Security Tweaks
###############################################################################
echo "Checking FileVault status..."
if fdesetup status | grep -q "FileVault is On."; then
echo "✅ FileVault is already enabled."
else
echo "Enabling FileVault..."
sudo fdesetup enable
fi
echo "Checking Gatekeeper status..."
if spctl --status | grep -q "assessments enabled"; then
echo "Gatekeeper is enabled. Disabling Gatekeeper to allow all app installs..."
sudo spctl --master-disable || true
defaults write com.apple.LaunchServices LSQuarantine -bool false
echo "⚠️ Gatekeeper has been disabled, but macOS requires you to manually confirm this change in System Settings → Privacy & Security."
echo "The script will continue running; please make sure to confirm this change later."
else
echo "Gatekeeper is already disabled."
fi
echo "Disabling Apple Music media key hijack..."
launchctl unload -w /System/Library/LaunchAgents/com.apple.rcd.plist 2>/dev/null || true
###############################################################################
# Done
###############################################################################
echo "Setup complete! Some changes require logout or reboot."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment