Info
In 2021, I returned to macOS after several years on ChromeOS. I made these notes during setup. Some things have changed by 2024 and this document needs revision.
First, install software updates, migrate from another computer, etc.
System Preferences → Sharing → Computer Name → Edit… to set hostname to something short. Uncheck “Use dynamic global hostname”
Console setup
Install Homebrew from https://brew.sh/
Install iTerm2 https://iterm2.com/. The default dark colour palette is somewhat low contrast. Install a custom colour scheme such as Material Design colours. Update: Prefer Ghostty now.
Default shell in Big Sur is already zsh
. Install oh-my-zsh
https://ohmyz.sh/
brew install coreutils findutils
, then set paths in ~/.oh-my-zsh/custom/path.zsh
:
export PATH="/opt/homebrew/opt/coreutils/libexec/gnubin:/opt/homebrew/opt/findutils/libexec/gnubin:$PATH"
Install powerlevel10k for terminal prompt: brew install romkatv/powerlevel10k/powerlevel10k
, follow instructions for oh-my-zsh, and use p10k configure
to set up prompt
Colorize console commands. Make ~/.oh-my-zsh/colors.zsh
:
export CLICOLOR=1 # This is for BSD ls (macOS default)
alias ls='gls --color=auto' # This is for GNU ls
export LESS='-R'
export LESSOPEN='|pygmentize -g %s'
export GREP_OPTIONS='--color=auto'
brew install zsh-fast-syntax-highlighting
then make ~/.oh-my-zsh/zsh-syntax-highlighting.zsh
:
source /opt/homebrew/opt/zsh-fast-syntax-highlighting/share/zsh-fast-syntax-highlighting/fast-syntax-highlighting.plugin.zsh
Setup autocomplete: First, brew install zsh-completions
, then add this to ~/.zprofile
(brew provides its own autocompletions, so there are two folders):
FPATH="$(brew --prefix)/share/zsh/site-functions:$(brew --prefix)/share/zsh-completions:$FPATH"
Additional instructions at https://docs.brew.sh/Shell-Completion
Install bat
as a replacement for cat
and less
with colour output: brew install bat
Install mosh: brew install mosh
and Eternal Terminal: brew install MisterTea/et/et
. Both require server-side installation too.
Install non-system Python: brew install python
(is 3.13 at the time of writing) and virtualenvwrapper (pip3 install virtualenvwrapper
), then setup virtualenvs for projects (using mkvirtualenv name
and workon name
). While modern Python workflows seem to have migrated to Pipenv and Poetry, I haven’t got my head around it yet.
Install direnv: brew install direnv
, add it to plugin list in ~/.zshrc
then setup for managing virtualenvs:
- Add to
~/.direnvrc
:
layout_virtualenv() {
local venv_path="$1"
source ${venv_path}/bin/activate
}
layout_virtualenvwrapper() {
local venv_path="${WORKON_HOME}/$1"
layout_virtualenv $venv_path
}
- In the project folder, add a
.envrc
containing:
layout virtualenvwrapper my-project-virtualenv-name
unset PS1
- Bless the file to enable it:
direnv allow .
Install zoxide
with brew install zoxide
and enable oh-my-zsh plugin. Use z folder-name
to rapidly jump between folders.
Enabled plugins in ~/.zshrc
: git direnv colorize zoxide
Enable Touch ID for sudo
With macOS Sonoma (macOS 14)
cd /etc/pam.d
sudo cp sudo_local.template sudo_local
vi sudo_local
Then uncomment the line that contains auth sufficient pam_tid.so
:
# sudo_local: local config file which survives system update and is included for sudo
# uncomment following line to enable Touch ID for sudo
auth sufficient pam_tid.so
Use sudo-touchid prior to macOS Sonoma
brew install artginzburg/tap/sudo-touchid
sudo brew services start sudo-touchid
Even older instructions
Install pam_reattach: brew install fabianishere/personal/pam_reattach
sudo vim /etc/pam.d/sudo
and add the first two lines here to the top:
# sudo: auth account password session
auth optional /opt/homebrew/lib/pam/pam_reattach.so
auth sufficient pam_tid.so
auth sufficient pam_smartcard.so
auth required pam_opendirectory.so
account required pam_permit.so
password required pam_deny.so
session required pam_permit.so
External keyboard
If you have an external keyboard, macOS may insist the function keys (F1-F12) are mapped to the same shortcuts as on the in-built keyboard, blocking access to actual function keys. To override, install Karabiner-Elements, accept all permission requirements (Accessibility, Extension) and use these settings:
- Function keys → For all devices: Map all F1-F12 keys to function keys, not the (default) shortcuts
- For the in-built keyboard, map them back to media keys.
- If you have a newer Mac, F6 may be mapped to a DND shortcut (🌙 icon) that Karabiner doesn’t recognise (issues #2901 and #3851). If you don’t need Karabiner for anything other than function keys, the easy fix is to go to Settings → Devices and remove the internal keyboard (turn off “modify events”).
Terminal
If you prefer Kitty or Ghostty for your terminal, they set custom identifiers in $TERM
that can mess up SSH connections. Remote connections won’t have their xterm-kitty
and xterm-ghostty
in their terminfo databases. You’ll need additional configuration (see for Kitty and for Ghostty).
If you don’t need their special terminal features on a remote host, you reset $TERM
instead. Add to ~/.ssh/config
:
Host *
SetEnv TERM=xterm-256color
Eternal Terminal doesn’t support setting $TERM, so add an alias to ~/.oh-my-zsh/custom/aliases.zsh
:
[[ "$TERM" =~ "xterm-(ghostty|kitty)"]] && alias et='TERM=xterm-256color et'
GUI
Install Multitouch, Rectangle Pro, Charmstone (optional) and Raycast.
System Preferences → Trackpad → More Gestures → Swipe between full-screen apps = change to use four fingers
Setup Multitouch:
- Three finger tap = middle click
- Three finger click = middle click
- Three finger swipe left = apps with tabs, switch tab left
- Three finger swipe right = apps with tabs, switch tab right
Setup Rectangle Pro: mostly default settings, start at login
Setup Raycast: mostly default settings, maybe swap shortcut with Spotlight
Fix keyboard navigation to be a bit more Windows-like. Make ~/Library/KeyBindings/DefaultKeyBinding.dict
containing:
{
"\UF729" = (moveToBeginningOfLine:); // home
"\UF72B" = (moveToEndOfLine:); // end
"$\UF729" = (moveToBeginningOfLineAndModifySelection:); // shift-home
"$\UF72B" = (moveToEndOfLineAndModifySelection:); // shift-end
"^\UF729" = (moveToBeginningOfDocument:); // ctrl-home
"^\UF72B" = (moveToEndOfDocument:); // ctrl-end
"^$\UF729" = (moveToBeginningOfDocumentAndModifySelection:); // ctrl-shift-home
"^$\UF72B" = (moveToEndOfDocumentAndModifySelection:); // ctrl-shift-end
"^\UF702" = (moveWordBackward:); // ctrl-left
"^$\UF702" = (moveWordBackwardAndModifySelection:); // ctrl-shift-left
"^\UF703" = (moveWordForward:); // ctrl-right
"^$\UF703" = (moveWordForwardAndModifySelection:); // ctrl-shift-right
}
Console dev setup
Postfix
Postfix is pre-installed, but has to be configured to (a) relay email and (b) auto-start SMTP server.
Setup relayhost. Add to /etc/postfix/main.cf
:
relayhost = [smtp.myserver.tld]:587
smtp_generic_maps = hash:/etc/postfix/generic
# Use TLS/SASL authentication
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_security_options = noanonymous
smtp_sasl_mechanism_filter = plain
smtp_use_tls = yes
smtp_tls_security_level = encrypt
Add to /etc/postfix/generic
:
my-username@my-laptop-host [email protected]
sudo postmap /etc/postfix/generic
Add to /etc/postfix/sasl_passwd
:
[smtp.myserver.tld]:587 login:password
Then:
sudo chmod 600 /etc/postfix/sasl_passwd
sudo postmap /etc/postfix/sasl_passwd
Next, setup Postfix to auto-start. Make /Library/LaunchDaemons/org.postfix.custom.plist
:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "[http://www.apple.com/DTDs/PropertyList-1.0.dtd](http://www.apple.com/DTDs/PropertyList-1.0.dtd)">
<plist version="1.0">
<dict>
<key>Label</key>
<string>org.postfix.custom</string>
<key>Program</key>
<string>/usr/libexec/postfix/master</string>
<key>ProgramArguments</key>
<array>
<string>master</string>
</array>
<key>QueueDirectories</key>
<array>
<string>/var/spool/postfix/maildrop</string>
</array>
<key>AbandonProcessGroup</key>
<true/>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
Then sudo launchctl load /Library/LaunchDaemons/org.postfix.custom.plist
PostgreSQL, Redis, NodeJS
PostgreSQL: brew install postgresql
and brew services start postgresql
Postgres.app is no longer recommended. They haven’t released M1 or Universal binaries yet (July 2021).
Your user account will be the root user of PostgreSQL in this setup, while in production it won’t be. The CREATE EXTENSION
command is straightforward when root, but in production will require switching privileges, such as with a sudo su - postgres -c "psql database < commands.sql"
Redis: brew install redis
and brew services start redis
NodeJS: brew install node
GUI dev setup
Install VS Code, GitHub Desktop, Sublime Text, Sublime Merge