Skip to content

Instantly share code, notes, and snippets.

@ChristopherA
Last active April 12, 2026 09:32
Show Gist options
  • Select an option

  • Save ChristopherA/98628f8cd00c94f11ee6035d53b0d3c6 to your computer and use it in GitHub Desktop.

Select an option

Save ChristopherA/98628f8cd00c94f11ee6035d53b0d3c6 to your computer and use it in GitHub Desktop.
macOS Preferences Defaults
#!/bin/sh
# macOS Preferences Defaults
# By Christopher Allen @ChristopherA https://github.com/christophera/
#
# Personal macOS preferences applied via `defaults write`. Designed for
# macOS Tahoe 26.x on Apple Silicon. Some settings may work on earlier
# versions but are only tested on Tahoe.
#
# Repository DID: did:repo:1bd512b281bdedc2c76d9ba63c8c84b750847355
# Signing key: SHA256:a61TkTtLFGEYOmdRMbpYGkZwXw2QUrGkAWp3dok8jcw
#
# Usage:
# sh macOS-Preferences-Defaults.sh # apply to local machine
# ssh host 'sh -s' < macOS-Preferences-Defaults.sh # apply to remote
#
# Requirements:
# - macOS Tahoe 26.x (Apple Silicon)
# - Terminal/iTerm2 with Full Disk Access (for Safari settings)
# - Safari must be quit before running (for Safari settings)
#
# Sections:
# Appearance, Text Input, Trackpad, Dock, Desktop & Window Manager,
# Finder, Global Preferences, Safari, Script Menu, Keyboard Shortcuts,
# Spaces, Menu Bar, iTerm2, Dock App Removal, Security & Lock Screen
#
# Note: Some settings require logout/restart to take effect (marked below).
# Run `killall Dock Finder SystemUIServer` after to apply most changes.
# The Security & Lock Screen section uses sudo and sysadminctl, so this
# script may prompt for your password when run.
set -eu
printf "macOS Preferences Defaults\n"
printf "==========================\n\n"
# Verify macOS
if [ "$(uname)" != "Darwin" ]; then
printf "ERROR: This script is for macOS only.\n"
exit 1
fi
printf "macOS %s on %s\n\n" "$(sw_vers -productVersion)" "$(uname -m)"
#================================================
# APPEARANCE
#================================================
printf "Configuring appearance...\n"
# Dark mode
defaults write NSGlobalDomain AppleInterfaceStyle -string "Dark"
#================================================
# TEXT INPUT
#================================================
printf "Configuring text input...\n"
# Disable auto-correct
defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false
# Disable auto-capitalize
defaults write NSGlobalDomain NSAutomaticCapitalizationEnabled -bool false
# Disable smart quotes (use straight quotes for code)
defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
# Disable smart dashes
defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false
# Disable auto-period (double-space inserts period)
defaults write NSGlobalDomain NSAutomaticPeriodSubstitutionEnabled -bool false
# Disable auto text completion
defaults write NSGlobalDomain NSAutomaticTextCompletionEnabled -bool false
#================================================
# TRACKPAD
#================================================
printf "Configuring trackpad...\n"
# Disable tap to click (built-in and Bluetooth) — prefer physical click
defaults write com.apple.AppleMultitouchTrackpad Clicking -bool false
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool false
defaults -currentHost write NSGlobalDomain com.apple.mouse.tapBehavior -int 0
#================================================
# DOCK
#================================================
printf "Configuring Dock...\n"
# Position dock on the right
defaults write com.apple.dock orientation -string right
# Small icons (27px) with subtle magnification (33px on hover)
defaults write com.apple.dock tilesize -int 27
defaults write com.apple.dock magnification -bool true
defaults write com.apple.dock largesize -int 33
# Don't rearrange Spaces based on recent use
defaults write com.apple.dock mru-spaces -bool false
# Don't enter Mission Control by dragging windows to top
defaults write com.apple.dock enterMissionControlByTopWindowDrag -bool false
# Enable App Expose gesture (3-finger swipe down)
defaults write com.apple.dock showAppExposeGestureEnabled -bool true
# Hot corners
# Bottom-left: display sleep (10)
defaults write com.apple.dock wvous-bl-corner -int 10
defaults write com.apple.dock wvous-bl-modifier -int 0
# Bottom-right: disabled
defaults delete com.apple.dock wvous-br-corner 2>/dev/null || true
defaults delete com.apple.dock wvous-br-modifier 2>/dev/null || true
#================================================
# DESKTOP & WINDOW MANAGER
#================================================
printf "Configuring Desktop & Window Manager...\n"
# Disable click wallpaper to show desktop
defaults write com.apple.WindowManager EnableStandardClickToShowDesktop -bool false
# Hide widgets on desktop
defaults write com.apple.WindowManager StandardHideWidgets -bool true
defaults write com.apple.WindowManager StageManagerHideWidgets -bool true
# Disable window tiling by edge drag
defaults write com.apple.WindowManager EnableTiledWindowMargins -bool false
defaults write com.apple.WindowManager EnableTilingByEdgeDrag -bool false
defaults write com.apple.WindowManager EnableTopTilingByEdgeDrag -bool false
#================================================
# FINDER
#================================================
printf "Configuring Finder...\n"
# Disable Finder animations
defaults write com.apple.finder DisableAllAnimations -bool true
# Show status bar and path bar
defaults write com.apple.finder ShowStatusBar -bool true
defaults write com.apple.finder ShowPathbar -bool true
# Default to list view
defaults write com.apple.finder FXPreferredViewStyle -string "Nlsv"
# New Finder windows open to home directory
defaults write com.apple.finder NewWindowTarget -string "PfHm"
defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}/"
# Search current folder by default
defaults write com.apple.finder FXDefaultSearchScope -string "SCcf"
# Show all file extensions
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
# Show hidden files (dotfiles)
defaults write com.apple.finder AppleShowAllFiles -bool true
# Desktop icons: small (32px), grid 71, arranged by kind, text 10pt
/usr/libexec/PlistBuddy -c "Set :DesktopViewSettings:IconViewSettings:iconSize 32" ~/Library/Preferences/com.apple.finder.plist 2>/dev/null || true
/usr/libexec/PlistBuddy -c "Set :DesktopViewSettings:IconViewSettings:gridSpacing 71" ~/Library/Preferences/com.apple.finder.plist 2>/dev/null || true
/usr/libexec/PlistBuddy -c "Set :DesktopViewSettings:IconViewSettings:arrangeBy kind" ~/Library/Preferences/com.apple.finder.plist 2>/dev/null || true
/usr/libexec/PlistBuddy -c "Set :DesktopViewSettings:IconViewSettings:textSize 10" ~/Library/Preferences/com.apple.finder.plist 2>/dev/null || true
# Show external drives and removable media on desktop
defaults write com.apple.finder ShowExternalHardDrivesOnDesktop -bool true
defaults write com.apple.finder ShowRemovableMediaOnDesktop -bool true
# Don't write .DS_Store on USB or network volumes
defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true
# Skip disk image verification
defaults write com.apple.frameworks.diskimages skip-verify -bool true
defaults write com.apple.frameworks.diskimages skip-verify-locked -bool true
defaults write com.apple.frameworks.diskimages skip-verify-remote -bool true
# AirDrop over Ethernet
defaults write com.apple.NetworkBrowser BrowseAllInterfaces -bool true
# Small sidebar icons
defaults write NSGlobalDomain NSTableViewDefaultSizeMode -int 1
# Expand File Info panes by default
defaults write com.apple.finder FXInfoPanesExpanded -dict \
General -bool true \
OpenWith -bool true \
Privileges -bool true
#================================================
# GLOBAL PREFERENCES
#================================================
printf "Configuring global preferences...\n"
# Save to local disk by default (not iCloud)
defaults write NSGlobalDomain NSDocumentSaveNewDocumentsToCloud -bool false
# Expand save and print dialogs by default
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode2 -bool true
defaults write NSGlobalDomain PMPrintingExpandedStateForPrint -bool true
defaults write NSGlobalDomain PMPrintingExpandedStateForPrint2 -bool true
# Crash reporter as notification instead of dialog
defaults write com.apple.CrashReporter DialogType -string "notification"
# TextEdit defaults to plain text
defaults write com.apple.TextEdit RichText -int 0
# Disable screenshot floating thumbnail
defaults write com.apple.screencapture show-thumbnail -bool false
# Screenshots: save to clipboard, fallback to ~/Dropbox/Downloads
defaults write com.apple.screencapture target -string clipboard
defaults write com.apple.screencapture "location-last" -string "${HOME}/Dropbox/Downloads"
#================================================
# SAFARI
#================================================
# Note: Safari must be quit. Terminal needs Full Disk Access.
# Some settings may need re-verification after first Safari launch.
printf "Configuring Safari...\n"
if pgrep -x Safari > /dev/null 2>&1; then
printf " WARNING: Safari is running. Safari settings may not apply.\n"
printf " Quit Safari and re-run this script for Safari settings.\n"
else
# Safari settings require Full Disk Access for Terminal/iTerm2.
# If FDA is not granted, these fail silently rather than aborting.
defaults write com.apple.Safari ShowOverlayStatusBar -bool true 2>/dev/null || printf " SKIP: Safari prefs need Full Disk Access\n"
defaults write com.apple.Safari AutoOpenSafeDownloads -bool false 2>/dev/null || true
defaults write com.apple.Safari IncludeDevelopMenu -bool true 2>/dev/null || true
defaults write com.apple.Safari.SandboxBroker ShowDevelopMenu -bool true 2>/dev/null || true
defaults write com.apple.Safari WebKitDeveloperExtrasEnabledPreferenceKey -bool true 2>/dev/null || true
defaults write com.apple.Safari "WebKitPreferences.developerExtrasEnabled" -bool true 2>/dev/null || true
defaults write com.apple.Safari ShowFullURLInSmartSearchField -bool true 2>/dev/null || true
fi
#================================================
# SCRIPT MENU
#================================================
printf "Configuring Script menu...\n"
# Enable AppleScript menu bar item
defaults write com.apple.scriptmenu ScriptMenuEnabled -bool true
#================================================
# KEYBOARD SHORTCUTS
#================================================
# Remap Quit to Cmd+Opt+Q for apps prone to accidental quit
printf "Configuring keyboard shortcuts...\n"
defaults write com.apple.Safari NSUserKeyEquivalents -dict \
"Quit Safari" "@~q"
defaults write com.googlecode.iterm2 NSUserKeyEquivalents -dict \
"Quit iTerm2" "@~q" \
"Close" "@~^w"
defaults write com.apple.iWork.Pages NSUserKeyEquivalents -dict \
"Quit Pages" "@~q"
# Music: Cmd+G for Go to Current Song
defaults write com.apple.Music NSUserKeyEquivalents -dict \
"Go to Current Song" "@g" 2>/dev/null || true
#================================================
# SPACES (requires logout to take effect)
#================================================
# Enable Ctrl+1 through Ctrl+0 for switching to Desktops 1-10
# Note: You must create 10 Spaces manually in Mission Control first.
printf "Configuring Spaces hotkeys (Ctrl+1-0)...\n"
# Keycodes: 1=18, 2=19, 3=20, 4=21, 5=23, 6=22, 7=26, 8=28, 9=25, 0=29
PLIST="$HOME/Library/Preferences/com.apple.symbolichotkeys.plist"
KEYCODES="18 19 20 21 23 22 26 28 25 29"
I=118
for KC in $KEYCODES; do
/usr/libexec/PlistBuddy -c "Delete AppleSymbolicHotKeys:$I" "$PLIST" 2>/dev/null || true
/usr/libexec/PlistBuddy -c "Add AppleSymbolicHotKeys:$I dict" "$PLIST"
/usr/libexec/PlistBuddy -c "Add AppleSymbolicHotKeys:$I:enabled bool true" "$PLIST"
/usr/libexec/PlistBuddy -c "Add AppleSymbolicHotKeys:$I:value dict" "$PLIST"
/usr/libexec/PlistBuddy -c "Add AppleSymbolicHotKeys:$I:value:type string standard" "$PLIST"
/usr/libexec/PlistBuddy -c "Add AppleSymbolicHotKeys:$I:value:parameters array" "$PLIST"
/usr/libexec/PlistBuddy -c "Add AppleSymbolicHotKeys:$I:value:parameters:0 integer 65535" "$PLIST"
/usr/libexec/PlistBuddy -c "Add AppleSymbolicHotKeys:$I:value:parameters:1 integer $KC" "$PLIST"
/usr/libexec/PlistBuddy -c "Add AppleSymbolicHotKeys:$I:value:parameters:2 integer 262144" "$PLIST"
I=$((I + 1))
done
#================================================
# MENU BAR
#================================================
printf "Configuring menu bar...\n"
# Clock: show AM/PM and day of week, hide date
defaults write com.apple.menuextra.clock ShowAMPM -bool true
defaults write com.apple.menuextra.clock ShowDayOfWeek -bool true
defaults write com.apple.menuextra.clock ShowDate -int 0
# Remove Siri from menu bar
defaults write com.apple.Siri StatusMenuVisible -bool false
#================================================
# ITERM2
#================================================
printf "Configuring iTerm2...\n"
# Option key sends Esc+ (for terminal shortcuts like Alt+B, Alt+F)
# Note: This sets the profile default. Per-profile settings may override.
# Value 2 = Esc+, Value 0 = Normal, Value 1 = Meta
/usr/libexec/PlistBuddy -c "Set ':New Bookmarks:0:Option Key Sends' 2" \
~/Library/Preferences/com.googlecode.iterm2.plist 2>/dev/null || true
/usr/libexec/PlistBuddy -c "Set ':New Bookmarks:0:Right Option Key Sends' 2" \
~/Library/Preferences/com.googlecode.iterm2.plist 2>/dev/null || true
#================================================
# DOCK APP REMOVAL
#================================================
# Remove unwanted default apps from the Dock
printf "Removing unwanted Dock apps...\n"
DOCK_PLIST="$HOME/Library/Preferences/com.apple.dock.plist"
for BUNDLE_ID in com.apple.apps.launcher com.apple.mail com.apple.mobilephone com.apple.iCal com.apple.games; do
COUNT=$(/usr/libexec/PlistBuddy -c "Print persistent-apps:" "$DOCK_PLIST" 2>/dev/null | grep -c "Dict" || echo 0)
IDX=$((COUNT - 1))
while [ "$IDX" -ge 0 ]; do
BID=$(/usr/libexec/PlistBuddy -c "Print persistent-apps:${IDX}:tile-data:bundle-identifier" "$DOCK_PLIST" 2>/dev/null || true)
if [ "$BID" = "$BUNDLE_ID" ]; then
/usr/libexec/PlistBuddy -c "Delete persistent-apps:${IDX}" "$DOCK_PLIST"
printf " Removed %s\n" "$BUNDLE_ID"
break
fi
IDX=$((IDX - 1))
done
done
#================================================
# SECURITY & LOCK SCREEN
#================================================
# Some commands in this section use sudo or sysadminctl and may prompt
# for a password. Prime the sudo cache up front so the set -eu script
# doesn't abort between sudo invocations if the cache lapses mid-run.
# The sysadminctl quartet (automaticTime, guestAccount, afpGuestAccess,
# smbGuestAccess) runs without elevation.
printf "Configuring security and lock screen...\n"
sudo -v
HOSTNAME_LOCAL="$(hostname).local"
# Password hint (shown after failed login attempts).
# Stored in the user's OpenDirectory record as the 'hint' attribute.
# Requires sudo — the _writers_hint attribute is insufficient; dscl
# returns eDSPermissionError without root. Empirically verified on
# macOS 26.4 during seshat provisioning.
sudo dscl . -create "/Users/$(whoami)" hint "2016 Secure for $HOSTNAME_LOCAL" 2>/dev/null || \
printf " WARNING: failed to set password hint\n"
# Show password hint after 1 failed attempt (default: 3, 0 = never).
# Requires sudo (writes to /Library/Preferences/).
sudo defaults write /Library/Preferences/com.apple.loginwindow RetriesUntilHint -int 1
# Message shown at login window / lock screen.
sudo defaults write /Library/Preferences/com.apple.loginwindow LoginwindowText \
-string "$HOSTNAME_LOCAL: Contact ChristopherA@gmail.com or +1-510-908-1066"
# Automatic time.
sysadminctl -automaticTime on 2>/dev/null || true
# Disable guest accounts and guest file share access.
sysadminctl -guestAccount off 2>/dev/null || true
sysadminctl -afpGuestAccess off 2>/dev/null || true
sysadminctl -smbGuestAccess off 2>/dev/null || true
# Screen lock delay: 3600 seconds after display sleep.
# sysadminctl -screenLock requires the user password (interactive).
# Only prompt if the current value differs — keeps the script idempotent.
CURRENT_LOCK=$(sysadminctl -screenLock status 2>&1 | grep -oE '[0-9]+ seconds|immediate|is off' | head -1)
if [ "$CURRENT_LOCK" = "3600 seconds" ]; then
printf " screenLock already set to 3600 seconds\n"
else
printf " Setting screenLock to 3600 seconds (password prompt follows)...\n"
sysadminctl -screenLock 3600 -password - || \
printf " WARNING: failed to set screenLock delay\n"
fi
#================================================
# APPLY CHANGES
#================================================
printf "\nRestarting affected services...\n"
killall Dock 2>/dev/null || true
killall Finder 2>/dev/null || true
killall SystemUIServer 2>/dev/null || true
printf "\nDone. Some changes require logout/restart:\n"
printf " - Spaces hotkeys (Ctrl+1-0)\n"
printf " - Create 10 Spaces manually in Mission Control\n"
printf " - Music keyboard shortcut (launch Music first)\n"
printf " - Trackpad tap behavior (may need logout)\n"
printf " - Dark mode (applies immediately to new windows)\n"
printf " - Login window text and password hint (visible on next lock)\n"
@ChristopherA
Copy link
Copy Markdown
Author

  • TODO: Seemed to work on Mojave 10.14.6 but got a strange message Container.plist Data in middle of output:
Testing for Full Disk Access:

Container.plist	Data
Terminal.app has permission to continue

@ChristopherA
Copy link
Copy Markdown
Author

  • BUG: VMware test failed on Mojave 10.14.6, dock ended up on right (should be on bottom for VMware).

@ChristopherA
Copy link
Copy Markdown
Author

TBD: Initial macOS Sonoma 14.0 testing.

WARNING: Initial tests with macOS Sonoma 14.0 have a lot of failures, mostly with the approaches used request access. If you answer yes to all the errors will still occur, but you can run the script multiple times and it will eventually set most of them.

@luxuxl
Copy link
Copy Markdown

luxuxl commented Sep 9, 2024

hmm, I saw a post in reddit, it says you need full grant disk access to Terminal, https://www.reddit.com/r/MacOSBeta/comments/15yjcnc/change_in_defaults_domains_in_sonoma/, you can have a try.As I know,the plist property wont be deprecated at usual

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment