I bought a new MacBook Air M4, so it's time to document my 2025 macOS setup and what changed since last year. I'm writing this primarily for myself - last year's post really helped me when migrating to a new laptop.
From 2024, my browser situation has simplified. I've settled on Brave as my daily driver, using Browserino as a browser switcher to Chrome, Edge, and Firefox.
I finally made the switch to fish shell with fisher for plugin management and the Tide prompt. Also, I replaced Docker Desktop with Orb (OrbStack). On the editor front, I've been experimenting with Cursor and Zed. I've also tightened up my Git/SSH configuration. But most system tweaks remain unchanged from 2024.
I've also started using Ghostty as my terminal and Nix for dependency management.
If you're setting up a fresh Mac:
- Install Homebrew first
- Install CLI and GUI apps via Homebrew (see my lists below)
- Install remaining apps directly from official sites or the App Store
System Settings
- Migrated from previous macOS and ran setup script.
- Manually checked Settings
- Battery → Slightly dim the screen on battery
- Battery → Low Power Mode always on battery
- Battery → Prevent automatic sleep on power adapter
- Battery → Optimize video while on battery
- Accessibility → Display → Reduce motion
- Wallpaper → Black
- Keyboard → Input Sources → Use Caps Lock to switch languages
- Default browser — Browserino (browser switcher with profiles)
macOS Setup Script
I considered Ansible or Nix for configuration management, but a tried‑and‑true bash script is still the simplest option for me. I like it 🙂.
#!/usr/bin/env bash
set -Eeuo pipefail
# macOS Setup Script - Compatible with macOS 15 Sequoia & 26 Tahoe
#
# Sources:
# - https://macos-defaults.com
# - https://github.com/mathiasbynens/dotfiles
# - https://github.com/driesvints/dotfiles
#
echo "Running macOS setup for Sequoia/Tahoe..."
# Detect macOS version
OS_VERSION=$(sw_vers -productVersion)
echo "Detected macOS version: $OS_VERSION"
echo "Some settings require Full Disk Access for Terminal.app"
echo ""
# ============================================================================
# === SCRIPT INITIALIZATION ===
# ============================================================================
# Close any open System Settings panes
osascript -e 'tell application "System Settings" to quit'
# Ask for the administrator password upfront
sudo -v
# ============================================================================
# === SYSTEM CORE SETTINGS ===
# ============================================================================
echo "Configuring system core settings..."
# Disable startup noise
sudo nvram StartupMute=%01
# Automatically switch between light and dark mode
defaults write NSGlobalDomain AppleInterfaceStyleSwitchesAutomatically -bool true
# Reveal IP address, hostname, OS version when clicking login clock
sudo defaults write /Library/Preferences/com.apple.loginwindow AdminHostInfo HostName
# Expand save panel by default
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode -bool true
defaults write NSGlobalDomain NSNavPanelExpandedStateForSaveMode2 -bool true
# Save to disk (not iCloud) by default
defaults write NSGlobalDomain NSDocumentSaveNewDocumentsToCloud -bool false
# Expand print panel by default
defaults write NSGlobalDomain PMPrintingExpandedStateForPrint -bool true
defaults write NSGlobalDomain PMPrintingExpandedStateForPrint2 -bool true
# Disable tiled window margins (Sequoia's window tiling)
defaults write com.apple.WindowManager EnableTiledWindowMargins -bool false
# Reduce motion (more effective than NSAutomaticWindowAnimationsEnabled)
defaults write NSGlobalDomain ReduceMotionEnabled -bool true
# ============================================================================
# === FINDER & FILE MANAGEMENT ===
# ============================================================================
echo "Configuring Finder settings..."
# Use list view by default
defaults write com.apple.finder FXPreferredViewStyle -string "Nlsv"
# Keep folders on top when sorting by name
defaults write com.apple.finder _FXSortFoldersFirst -bool true
# Disable Finder animations for speed
defaults write com.apple.finder DisableAllAnimations -bool true
# Show "Quit Finder" menu item
defaults write com.apple.finder QuitMenuItem -bool true
# Show hidden files (Cmd+Shift+. also works)
defaults write com.apple.finder AppleShowAllFiles -bool true
# Always show file extensions
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
# Disable warning when changing file extensions
defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false
# Search current folder by default
defaults write com.apple.finder FXDefaultSearchScope -string "SCcf"
# Show path bar and status bar
defaults write com.apple.finder ShowPathbar -bool true
defaults write com.apple.finder ShowStatusBar -bool true
# Show POSIX path in title
defaults write com.apple.finder _FXShowPosixPathInTitle -bool true
# New windows open to home folder
defaults write com.apple.finder NewWindowTarget -string "PfHm"
defaults write com.apple.finder NewWindowTargetPath -string "file://${HOME}/"
# Show drives on desktop
defaults write com.apple.finder ShowHardDrivesOnDesktop -bool true
defaults write com.apple.finder ShowMountedServersOnDesktop -bool true
defaults write com.apple.finder ShowExternalHardDrivesOnDesktop -bool true
defaults write com.apple.finder ShowRemovableMediaOnDesktop -bool true
# Show ~/Library folder
chflags nohidden ~/Library
# Show /Volumes folder
sudo chflags nohidden /Volumes
# Disable .DS_Store on network and USB drives
defaults write com.apple.desktopservices DSDontWriteNetworkStores -bool true
defaults write com.apple.desktopservices DSDontWriteUSBStores -bool true
# ============================================================================
# === DOCK & MISSION CONTROL ===
# ============================================================================
echo "Configuring Dock and Mission Control..."
# Auto-hide Dock
defaults write com.apple.dock autohide -bool true
# Fast Dock animations
defaults write com.apple.dock autohide-time-modifier -float 0.15
defaults write com.apple.dock autohide-delay -float 0
# Smaller Dock icons
defaults write com.apple.dock tilesize -int 48
# No magnification
defaults write com.apple.dock magnification -bool false
# Scale effect for minimizing
defaults write com.apple.dock mineffect -string "scale"
# Hide recent applications
defaults write com.apple.dock show-recents -bool false
# Show indicator lights for open applications
defaults write com.apple.dock show-process-indicators -bool true
# Make hidden app icons translucent
defaults write com.apple.dock showhidden -bool true
# Don't rearrange Spaces automatically
defaults write com.apple.dock mru-spaces -bool false
# Group windows by application in Mission Control
defaults write com.apple.dock expose-group-by-app -bool true
# Disable hot corners (set all to 0 for no action)
defaults write com.apple.dock wvous-tl-corner -int 0
defaults write com.apple.dock wvous-tr-corner -int 0
defaults write com.apple.dock wvous-bl-corner -int 0
defaults write com.apple.dock wvous-br-corner -int 0
# Enable scroll gesture to open Dock stacks
defaults write com.apple.dock scroll-to-open -bool true
# ============================================================================
# === UI & ANIMATIONS ===
# ============================================================================
echo "Configuring UI and animations..."
# Reduce menu bar spacing for MacBooks with notch
defaults write NSGlobalDomain NSStatusItemSelectionPadding -int 10
defaults write NSGlobalDomain NSStatusItemSpacing -int 10
# Faster window resize
defaults write NSGlobalDomain NSWindowResizeTime -float 0.001
# Instant Quick Look
defaults write NSGlobalDomain QLPanelAnimationDuration -float 0
# ============================================================================
# === INPUT & TEXT ===
# ============================================================================
echo "Configuring input and text settings..."
# Disable all automatic text corrections
defaults write NSGlobalDomain NSAutomaticCapitalizationEnabled -bool false
defaults write NSGlobalDomain NSAutomaticDashSubstitutionEnabled -bool false
defaults write NSGlobalDomain NSAutomaticQuoteSubstitutionEnabled -bool false
defaults write NSGlobalDomain NSAutomaticPeriodSubstitutionEnabled -bool false
defaults write NSGlobalDomain NSAutomaticSpellingCorrectionEnabled -bool false
defaults write NSGlobalDomain NSAutomaticTextCompletionEnabled -bool false
# Disable language indicator
defaults write kCFPreferencesAnyApplication TSMLanguageIndicatorEnabled -bool false
# Full keyboard access (Tab through all controls)
# Note: Sequoia changed values - use 2, not 3
# https://github.com/nix-darwin/nix-darwin/issues/1378
defaults write NSGlobalDomain AppleKeyboardUIMode -int 2
# Disable press-and-hold for accented characters
defaults write NSGlobalDomain ApplePressAndHoldEnabled -bool false
# Fast keyboard repeat rate (requires logout)
defaults write NSGlobalDomain KeyRepeat -int 2
defaults write NSGlobalDomain InitialKeyRepeat -int 15
# Trackpad: Enable tap-to-click
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad Clicking -bool true
defaults write com.apple.AppleMultitouchTrackpad Clicking -bool true
defaults -currentHost write NSGlobalDomain com.apple.mouse.tapBehavior -int 1
defaults write NSGlobalDomain com.apple.mouse.tapBehavior -int 1
# Enable three-finger drag
defaults write com.apple.AppleMultitouchTrackpad TrackpadThreeFingerDrag -bool true
defaults write com.apple.driver.AppleBluetoothMultitouch.trackpad TrackpadThreeFingerDrag -bool true
# ============================================================================
# === SCREENSHOTS ===
# ============================================================================
echo "Configuring screenshot settings..."
# Save as PNG
defaults write com.apple.screencapture type -string "png"
# Save to Downloads
defaults write com.apple.screencapture location -string "${HOME}/Downloads"
# Disable shadow in screenshots
defaults write com.apple.screencapture disable-shadow -bool true
# No floating thumbnail
defaults write com.apple.screencapture show-thumbnail -bool false
# Custom name prefix
defaults write com.apple.screencapture name -string "Screenshot"
# ============================================================================
# === ACTIVITY MONITOR ===
# ============================================================================
echo "Configuring Activity Monitor..."
# Show all processes
defaults write com.apple.ActivityMonitor ShowCategory -int 0
# Sort by CPU usage
defaults write com.apple.ActivityMonitor SortColumn -string "CPUUsage"
defaults write com.apple.ActivityMonitor SortDirection -int 0
# Show CPU history in Dock icon
defaults write com.apple.ActivityMonitor IconType -int 6
# Update frequency: Often (2 seconds)
defaults write com.apple.ActivityMonitor UpdatePeriod -int 2
# ============================================================================
# === PRIVACY & SECURITY ===
# ============================================================================
echo "Configuring privacy settings..."
# Disable Spotlight web search (keeps searches local)
defaults write com.apple.lookup.shared LookupSuggestionsDisabled -bool true
# Disable crash reporter dialog
defaults write com.apple.CrashReporter DialogType -string "none"
# ============================================================================
# === SYSTEM PREFERENCES ===
# ============================================================================
echo "Configuring system preferences..."
# Prevent Photos from auto-launching
defaults -currentHost write com.apple.ImageCapture disableHotPlug -bool YES
# Disable app state restoration
defaults write NSGlobalDomain NSQuitAlwaysKeepsWindows -bool false
defaults write com.apple.loginwindow TALLogoutSavesState -bool false
defaults write com.apple.loginwindow LoginwindowLaunchesRelaunchApps -bool false
# Enable spring loading for directories
defaults write NSGlobalDomain com.apple.springing.enabled -bool true
# Remove spring loading delay
defaults write NSGlobalDomain com.apple.springing.delay -float 0
# ============================================================================
# === CLEANUP ===
# ============================================================================
echo "Cleaning up old settings..."
# Remove deprecated Launchpad settings if they exist
defaults delete com.apple.dock springboard-columns 2>/dev/null || true
defaults delete com.apple.dock springboard-rows 2>/dev/null || true
# Reset Launchpad
defaults write com.apple.dock ResetLaunchPad -bool true
# ============================================================================
# === APPLY CHANGES ===
# ============================================================================
echo "Applying changes..."
# Restart affected services
for app in "Finder" "Dock" "SystemUIServer" "WindowManager"; do
killall "${app}" &> /dev/null || true
done
# Restart preference daemon
killall cfprefsd
echo ""
echo "✅ Setup complete!"
echo ""
echo "Consider rebooting for all changes to take effect." Browser
My daily browser is now Brave, with Browserino as a profile switcher to manage different contexts (personal, work, etc.). At work, I use Chrome or Edge, depending on the laptop. I use Edge on my MacBook Air because it comes preinstalled with my work account.
I also occasionally use Firefox or Zen Browser. I typically prefer Firefox for its extensions, though Brave has largely addressed this gap. I use Firefox less now...
As for Zen Browser, I like the concept and have been using it since around its second release. However, I had to recreate my account because Zen couldn't migrate data after an update, which was frustrating. This is the main reason I now take a wait-and-see approach, only trying occasional releases.
Browser Extensions
- Bitwarden
- OneTab — saves open tabs to a local list. I use it as a reading list.
- uBlock Origin — cleaner browsing (even with Pi‑hole)
- Simple Translate — the cleanest translator extension that I saw
- Clickbait Remover for YouTube
- Enhancer for YouTube
- SponsorBlock
- Claude — for occasional experiments
Homebrew
I install most CLI tools through Homebrew, while GUI apps are a mix of Homebrew Casks and direct downloads. When an app has its own auto-updater, I prefer installing it directly to avoid version management conflicts with Homebrew.
I generate these lists with:
brew leaves | xargs brew desc --eval-all
brew ls --casks | xargs brew desc --eval-all CLI Applications (generated)
age: Simple, modern, secure file encryption
ansible: Automate deployment, configuration, and upgrading
ansible-lint: Checks ansible playbooks for practices and behaviour
atuin: Improved shell history for zsh, bash, fish and nushell
awscli: Official Amazon AWS command-line interface
bat: Clone of cat(1) with syntax highlighting and Git integration
btop: Resource monitor. C++ version and continuation of bashtop and bpytop
cloudflared: Cloudflare Tunnel client (formerly Argo Tunnel)
cmake: Cross-platform make
codex: OpenAI's coding agent that runs in your terminal
curl: Get a file from an HTTP, HTTPS or FTP server
dialog: Display user-friendly message boxes from shell scripts
direnv: Load/unload environment variables based on $PWD
dust: More intuitive version of du in rust
eza: Modern, maintained replacement for ls
fastfetch: Like neofetch, but much faster because written mostly in C
fd: Simple, fast and user-friendly alternative to find
fish: User-friendly command-line shell for UNIX-like operating systems
fzf: Command-line fuzzy finder written in Go
gh: GitHub command-line tool
git: Distributed revision control system
git-delta: Syntax-highlighting pager for git and diff output
git-filter-repo: Quickly rewrite git repository history
gnu-tar: GNU version of the tar archiving utility
golang-migrate: Database migrations CLI tool
golangci-lint: Fast linters runner for Go
goreleaser: Deliver Go binaries as fast and easily as possible
gping: Ping, but with a graph
graphviz: Graph visualization software from AT&T and Bell Labs
grpcurl: Like cURL, but for gRPC
terraform: Terraform
httpie: User-friendly cURL replacement (command-line HTTP client)
jq: Lightweight and flexible command-line JSON processor
lazydocker: Lazier way to manage everything docker
lazygit: Simple terminal UI for git commands
llama.cpp: LLM inference in C/C++
lld: LLVM Project Linker
make: Utility for directing compilation
miniserve: High performance static file server
mpv: Media player based on MPlayer and mplayer2
mypy: Experimental optional static type checker for Python
neovim: Ambitious Vim-fork focused on extensibility and agility
nmap: Port scanning utility for large networks
openfortivpn: Open Fortinet client for PPP+TLS VPN tunnel services
bun: Incredibly fast JavaScript runtime, bundler, transpiler and package manager - all in one.
p7zip: 7-Zip (high compression file archiver) implementation
pnpm: Fast, disk space efficient package manager
protobuf: Protocol buffers (Google's data interchange format)
pv: Monitor data's progress through a pipe
pwgen: Password generator
qemu: Generic machine emulator and virtualizer
repomix: Pack repository contents into a single AI-friendly file
ruby: Powerful, clean, object-oriented scripting language
ruff: Extremely fast Python linter, written in Rust
shellcheck: Static analysis and lint tool, for (ba)sh scripts
solidity: Contract-oriented programming language
sops: Editor of encrypted files
sshs: Graphical command-line client for SSH
swiftlint: Tool to enforce Swift style and conventions
teleport: Modern SSH server for teams managing distributed infrastructure
telnet: User interface to the TELNET protocol
typst: Markup-based typesetting system
uv: Extremely fast Python package installer and resolver, written in Rust
watch: Executes a program periodically, showing output fullscreen
wget: Internet file retriever
yamllint: Linter for YAML files
yazi: Blazing fast terminal file manager written in Rust, based on async I/O
yq: Process YAML, JSON, XML, CSV and properties documents from the CLI
zig: Programming language designed for robustness, optimality, and clarity
ast-grep: Code searching, linting, rewriting
GUI Applications (generated)
anki: (Anki) Memory training application
flashspace: (FlashSpace) Virtual workspace manager
font-inter: (Inter) [no description]
font-jetbrains-mono-nerd-font: (JetBrainsMono Nerd Font families (JetBrains Mono)) [no description]
font-noto-color-emoji: (Noto Color Emoji) [no description]
font-roboto-mono: (Roboto Mono) [no description]
iina: (IINA) Free and open-source media player
jdownloader: (JDownloader) Download manager
obsidian: (Obsidian) Knowledge base that works on top of a local folder of plain text Markdown files
orbstack: (OrbStack) Replacement for Docker Desktop
postman: (Postman) Collaboration platform for API development
qbittorrent: (qBittorrent) Peer to peer Bitorrent client
raycast: (Raycast) Control your tools with a few keystrokes
syncthing: Open source continuous file synchronization application
syncthing-app: (Syncthing) Real time file synchronisation software
thunderbird: (Mozilla Thunderbird) Customizable email client
vlc: (VLC media player) Multimedia player
wireshark: Network analyzer and capture tool - without graphical user interface
wireshark-app: (Wireshark) Network protocol analyzer
Apps Installed Outside Homebrew
# Browsers
Browserino
Brave Browser
Firefox
# Communication & Meetings
Slack
Discord
Telegram
Telegram Lite
WhatsApp
TeamViewer
AnyDesk
zoom.us
# Code & IDEs
Cursor
Visual Studio Code
Zed
Sublime Text
Goland
RustRover
# Git & Diff
Sublime Merge
GitButler
Kaleidoscope
# DevOps & Containers
Lens
Orb
# Media & Capture
Shottr
Screen Studio
Streisand
VoiceInk
# Productivity & Knowledge
Anytype
Lookupper
Microsoft Office
Yomu
Flow
Horo
# System & Tuning
Rectangle
Macs Fan Control
DaisyDisk
Keka
Handy
# VPN & Networking
WireGuard
OpenVPN
Transmit
# Virtualization & Compatibility
Parallels Desktop
CrossOver
# Games
Steam Terminal & Editor
Python global venv
I create one global Python virtual environment in my home directory for system-wide Python tools, which I activate in fish later, because I think this is a cleaner approach than installing everything globally and some deps have conflicting versions.
~/personal> uv venv fish
# Add fish to shells
echo "/opt/homebrew/bin/fish" | sudo tee -a /etc/shells
# Change shell to fish
chsh -s /opt/homebrew/bin/fish Install Fisher and plugins
I use Fisher as a package manager for fish shell to install and manage plugins.
- https://github.com/jorgebucaran/fisher - package manager for fish shell
fisher install IlanCosman/tide@v6- promptfisher install jorgebucaran/autopair.fish- auto closing brackets, quotes, etc.fisher list | fisher update- update plugins
It should look like this:
jorgebucaran/fisher
ilancosman/tide@v6
jorgebucaran/autopair.fish Configure Tide and fish
tide configure --auto --style=Classic --prompt_colors='True color' --classic_prompt_color=Light --show_time='24-hour format' --classic_prompt_separators=Vertical --powerline_prompt_heads=Sharp --powerline_prompt_tails=Flat --powerline_prompt_style='Two lines, character' --prompt_connection=Dotted --powerline_right_prompt_frame=No --prompt_connection_andor_frame_color=Dark --prompt_spacing=Compact --icons='Few icons' --transient=No ~/.config/fish/config.fish
# Disable greeting
set fish_greeting
# Language environment
set -gx LC_ALL en_US.UTF-8
set -gx LANG en_US.UTF-8
# Default editor and terminal
set -gx PAGER less
set -gx EDITOR nvim
set -gx VISUAL nvim
# Add Homebrew to PATH
/opt/homebrew/bin/brew shellenv | source
# and other
fish_add_path /opt/homebrew/opt/ruby/bin
fish_add_path $HOME/.docker/bin
fish_add_path $HOME/.cargo/bin
fish_add_path $HOME/go/bin/
fish_add_path $HOME/development/flutter/bin
# Python - Activate global venv for my user
source $HOME/personal/.venv/bin/activate.fish
# Tide
set --global tide_left_prompt_items os context pwd direnv git newline character
set --global tide_right_prompt_items status cmd_duration context jobs python go time
set --global tide_cmd_duration_decimals 1
set --global tide_cmd_duration_threshold 0
# History search with Atuin
atuin init fish | source
# Auto activate .env files
direnv hook fish | source
# 'yy' function (Terminal file explorer using yazi)
function yy
set tmp (mktemp -t "yazi-cwd.XXXXXX")
yazi $argv --cwd-file="$tmp"
if set cwd (command cat -- "$tmp"); and [ -n "$cwd" ]; and [ "$cwd" != "$PWD" ]
builtin cd -- "$cwd"
end
rm -f -- "$tmp"
end
# Aliases
function beep
afplay /System/Library/PrivateFrameworks/ScreenReader.framework/Versions/A/Resources/Sounds/AnimationFlyToDownloads.aiff >/dev/null 2>&1 &
end
# Shortcuts
alias l "eza -lah --group-directories-first"
alias o open
alias oo "open ."
alias cc "code ."
alias zz "zed ."
# Navigation shortcuts
alias "..." "cd ../.."
alias "...." "cd ../../.."
alias "....." "cd ../../../.."
alias "......" "cd ../../../../.."
# Git shortcuts
alias g git
alias ga "git add"
alias gaa "git add --all"
alias gcm "git commit -m"
alias gf "git fetch"
alias gfa "git fetch --all --tags --prune --jobs=10"
alias gl "git pull"
alias gp "git push"
function grishy-claude
docker run -it --rm \
-v $(pwd):/workspace \
-v ~/.claude:/home/ubuntu/.claude \
-v ~/.claude.json:/home/ubuntu/.claude.json \
grishy-dev claude --dangerously-skip-permissions $argv
end
function grishy-codex
docker run -it --rm \
-v $(pwd):/workspace \
-v ~/.codex:/home/ubuntu/.codex \
grishy-dev codex --search --sandbox danger-full-access $argv
end
function grishy-dev
docker run -it --rm \
-v $(pwd):/workspace \
grishy-dev
end
if status is-interactive
# Commands to run in interactive sessions can go here
end Ghostty
~/.config/ghostty/config
shell-integration = fish
font-family = JetBrainsMono Nerd Font Mono
font-feature = -calt, -liga, -dlig
theme = grishy
# Open on fullscreen
window-height = 10000
window-width = 10000
window-position-x = 0
window-position-y = 0
# Hide title bar
macos-titlebar-style = tabs
# Keybindings
keybind = shift+enter=text:\n ~/.config/ghostty/themes/grishy
# =============================================================================
# COLOR PALETTE ORGANIZATION
# =============================================================================
# The palette uses 16 colors organized as:
# palette = 0-7: Standard ANSI colors (black, red, green, yellow, blue, purple, aqua, white)
# palette = 8-15: Bright versions of the same colors
#
# Color Index Reference:
# 0, 8 = Black (normal/bright)
# 1, 9 = Red (normal/bright)
# 2, 10 = Green (normal/bright)
# 3, 11 = Yellow (normal/bright)
# 4, 12 = Blue (normal/bright)
# 5, 13 = Purple/Magenta (normal/bright)
# 6, 14 = Cyan/Aqua (normal/bright)
# 7, 15 = White/Light Gray (normal/bright)
#
# =============================================================================
# THEME SETTINGS
# =============================================================================
# background: Terminal background color
# foreground: Default text color
# cursor-color: Color of the cursor
# cursor-text: Color of text under the cursor
# selection-background: Color behind selected text
# selection-foreground: Color of selected text
# Root Loops color scheme (Initial version)
# Via https://rootloops.sh
# Basic colors
palette = 0=#222222
palette = 1=#f30052
palette = 2=#4f9a00
palette = 3=#b07700
palette = 4=#0081f8
palette = 5=#c301fb
palette = 6=#009797
palette = 7=#b9b9b9
palette = 8=#525252
palette = 9=#ff506e
palette = 10=#5cb200
palette = 11=#cc8a00
palette = 12=#4699ff
palette = 13=#d057ff
palette = 14=#00afaf
palette = 15=#f1f1f1
# Theme settings
background = #080808
foreground = #e2e2e2
cursor-color = #b9b9b9
cursor-text = #e2e2e2
selection-background = #e2e2e2
selection-foreground = #080808
Zed editor
settings.json
{
"features": {
"edit_prediction_provider": "copilot"
},
"vim_mode": false,
"theme": "One Dark",
"buffer_font_family": "JetBrainsMono Nerd Font Mono",
"confirm_quit": true,
"ui_font_family": "JetBrainsMono Nerd Font Mono",
"show_edit_predictions": true,
"telemetry": {
"metrics": false
},
"ui_font_size": 14,
"buffer_font_size": 13,
"terminal": {
"detect_venv": {
"on": {
"activate_script": "fish"
}
}
},
"lsp": {
"gopls": {
"gofumpt": true,
"initialization_options": {
"gofumpt": true
}
}
}
} Neovim
- Install LazyVim — https://www.lazyvim.org/installation
- Start using it, I tweak the config as I go.
Raycast
- Install
- Set Spotlight hotkey — https://manual.raycast.com/hotkey
Git & SSH
I keep separate Git configs for personal and work repositories and manage SSH keys accordingly. A base ~/.gitconfig conditionally includes others based on repository path.
~/.gitconfig
[filter "lfs"]
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f
process = git-lfs filter-process
required = true
[http]
version = HTTP/1.1
#
# Personal
#
[includeIf "gitdir:~/personal/"]
path = ~/personal/.gitconfig
#
# Work
#
# As we have personal
#
# Base on https://blog.gitbutler.com/how-git-core-devs-configure-git/
# clearly makes git better
[column]
ui = auto
[branch]
sort = -committerdate
[tag]
sort = version:refname
[init]
defaultBranch = main
[diff]
algorithm = histogram
colorMoved = plain
mnemonicPrefix = true
renames = true
[push]
default = simple
autoSetupRemote = true
followTags = true
[fetch]
prune = true
pruneTags = true
all = true
[help]
autocorrect = prompt
[commit]
verbose = true
[rerere]
enabled = true
autoupdate = true
[core]
excludesfile = ~/.gitignore
pager = delta
[rebase]
autoSquash = true
autoStash = true
updateRefs = true
[interactive]
diffFilter = delta --color-only
[delta]
navigate = true # use n and N to move between diff sections
dark = true # or light = true, or omit for auto-detection
[merge]
conflictStyle = zdiff3 ~/personal/.gitconfig
[user]
email = mailgrishy@gmail.com
name = Sergei G.
signingKey = /Users/grishy/.ssh/id_ed25519.pub
[gpg]
format = ssh
[commit]
gpgsign = true
[core]
sshCommand = ssh -i /Users/grishy/.ssh/id_ed25519 ~/.ssh/config
Host *
# Environment Variables
SetEnv TERM=xterm-256color # Terminal type for proper color/display rendering
SetEnv LC_ALL=en_US.UTF-8 # Locale setting for character encoding
SetEnv LANG=en_US.UTF-8 # Language setting for messages and formatting
# Key Management (macOS-specific)
AddKeysToAgent yes # Auto-add keys to ssh-agent when first used (stores in agent with default lifetime)
UseKeychain yes # Store passphrases in macOS Keychain (avoids re-entering passphrase)
IdentitiesOnly yes # ONLY use keys specified in config/command line, ignore keys in ssh-agent (prevents wrong key usage)
# Connection Keep-Alive (prevents idle timeouts)
ServerAliveInterval 30 # Send encrypted keepalive message every 30s if no data received from server
ServerAliveCountMax 3 # Disconnect after 3 failed keepalive attempts
TCPKeepAlive yes # Enable TCP-level keepalive (detects dead connections, but spoofable unlike ServerAlive) Conclusion
That's my 2025 macOS setup across two MacBooks. This year marks a shift for me - I've always run a single laptop, but now I'm juggling two machines.
Looking back at this year's changes, I'm most happy with the terminal upgrade. If it helps you set up your own Mac or discover a new tool, that's a bonus.
Thumbnail
Font: Inter
Photo by Thai Nguyen on Unsplash
