Setting up a Mac for Development

October 30, 2021

Overview

I thought it would be useful to document my step-by-step guide to get my laptop setup for development (Macbook Air 2019 Intel i5).

Factory Reset

Follow the steps to perform a factory reset.

Command Line Tools

Install Apple's command line developer tools:

xcode-select --install

To confirm installation:

xcode-select -p

Applications

There's a variety of applications that I use everyday, some for development and some for fun.

Homebrew

Install the Homebrew package manager.

/bin/bash -c "$(curl -fsSL [https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"](https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)")

Make sure Homebrew is up-to-date before installing packages:

brew update

Install applications:

brew install \
  git \
  make \
  rich-cli \
  postgresql &&
 
brew install --cask \
  1password \
  anki \
  discord \
  docker \
  google-chrome \
  iterm2 \
  itsycal
  postico \
  postman
  rectangle \
  slack \
  spotify \
  todoist \
  visual-studio-code \
  vlc \
  zoom

--cask is an extension to brew that allows management of graphical GUI applications.

Other

Shell and Terminal

For ultimate hacker productivity, I use Zsh (with Oh-My-Zsh) as my shell and iTerm2 as my terminal.

Zsh and Oh-My-Zsh

macOS Monterey ships with Zsh as the default shell. Install Oh-My-Zsh for a variety of plugins, themes, and options:

sh -c "$(curl -fsSL [https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"](https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)")

This will create configuration locations at ~/.oh-my-zsh and ~/.zshrc.

Install zsh-autosuggestions:

git clone [https://github.com/zsh-users/zsh-autosuggestions](https://github.com/zsh-users/zsh-autosuggestions) ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-autosuggestions

Install zsh-syntax-highlighting:

git clone [https://github.com/zsh-users/zsh-syntax-highlighting.git](https://github.com/zsh-users/zsh-syntax-highlighting.git) ${ZSH_CUSTOM:-~/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting

Add relevant plugins to ~/.zshrc:

plugins=(git web-search copydir copyfile copybuffer history osx)

Basic Usage

  • copyfile - copy file content in current working directory
    • copyfile <filename>
  • copybuffer - copy content that is currently typed in the terminal
    • Ctr + o
  • history
    • h - view command history
    • hs - search command history
    • hsi - search command history (case insensitive)
  • osx
    • ofd - open current working directory in finder
    • hidefiles - hide hidden files in Finder
    • showfiles - show hidden filed in Finder

iTerm2

iTerm2 is a modern terminal for the Mac. There are a few settings to configure to make it work with Apple shortcuts.

Default Apple shortcuts:

  • ⌥ + ← - move one work backward (hold for selection)
  • ⌥ + → - move one word foreward (hold for selection)
  • ⌘ + ← - move to beginning of line (hold for selection)
  • ⌘ + → - move to end of line (hold for selection)

To use these shortcuts in Zsh and iTerm2, you will need to update your ~/.zshrc configuration file and terminal with relevant keybindings:

Add relevant keybindings to Zsh:

bindkey "[D" backward-word
bindkey "[C" forward-word
bindkey "^[a" beginning-of-line
bindkey "^[e" end-of-line

Add relevant keybindings to iTerm2:

⌥ + ⇧ + ← | Action: Move start of selection left by word
⌥ + ⇧ + → | Action: Move end of selection right by word
⌥ + ⌘ + ← | Action: Move start of selection left by line
⌥ + ⌘ + → | Action: Move end of selection right by line

Git

Setup your global git configuration by adding a configuration file:

touch ~/.gitconfig

Add relevant config and aliases:

[user]
    name   = Luke Miloszewski
    email  = lukemiloszewski@gmail.com
[github]
    user   = lukemiloszewski
[init]
    defaultBranch = main
[core]
    pager = cat
    editor = code --wait
[color]
    ui = auto
[color "branch"]
    upstream = cyan
[log]
    abbrevCommit = true
    follow       = true
    decorate     = false
[tag]
    sort = version:refname
[alias]
    aliases  = !git config --get-regexp alias | sed -re 's/alias\\.(\\S*)\\s(.*)$/\\1 = \\2/g'
    a        = add
    cm       = commit -m
    s        = status
    p        = push
    pom      = push -u origin main
    puom     = pull origin main
    co       = checkout
    cob      = checkout -b
    fp       = fetch --prune --all
    lg       = log --graph --date=relative --pretty=format:'%Cred%h%Creset -%C(auto)%d%Creset %s %Cgreen(%an %ad)%Creset'
    reword   = commit --amend
    uncommit = reset --soft HEAD~1
    untrack  = rm --cache --

Python, Pyenv, Poetry and Pipx

Pyenv

I use pyenv to manage multiple Python versions. This makes it easy to switch between versions and manage dependencies without breaking things.

Install Python build dependencies:

brew install openssl readline sqlite3 xz zlib

Install pyenv:

brew install pyenv

You may receive the following warning (don't worry about it):

... is keg-only, which means it was not symlinked into /usr/local, because macOS already provides this software and installing another version in parallel can cause all kinds of trouble.

Configure pyenv with Zsh and restart your shell:

echo 'eval "$(pyenv init --path)"' >> ~/.zprofile
echo 'eval "$(pyenv init -)"' >> ~/.zshrc

Basic Usage

pyenv commands # list all commands
pyenv versions # list versions currently installed
pyenv install --list # list versions available to install
pyenv install <version> # install specific version
pyenv uninstall <version> # uninstall specific version
pyenv local <version> # set local python version
pyenv global <version> # set global python version

Poetry

I use Poetry for dependency management and packaging.

Install Poetry:

curl -sSL [https://install.python-poetry.org](https://install.python-poetry.org) | python3 -

Configure Zsh with the following:

export PATH="~/.local/bin:$PATH"

Pipx

I use pipx to install python applications in isolated environments, make them available globally and run them from the shell.

Install pipx:

brew install pipx

Node and NVM

NVM

I use nvm to manage multiple node versions. This makes it easy to switch between versions and manage dependencies without breaking things.

Install NVM:

curl -o- [https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh](https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh) | bash

Basic Usage

nvm ls # list versions currently installed
nvm ls-remote # list versions available to install
nvm install node # install latest version
nvm install <version> # install specific version
nvm use node # set latest node version
nvm use <version> # set specific node version
nvm alias default <version> # set specific version as default

Yarn

If you want to use yarn instead of npm, you can add the configuration file ~/.nvm/default-packages and include yarn in the list of packages to install. Now, whenever a different version of node is installed and used, yarn will be installed and ready to use by default.

yarn

Basic Usage

When installing yarn through npm, it will install version 1.xx as the global version. To use the latest release of yarn in your project, you can use the following command:

yarn set version berry
yarn --version

This will download the current, actively developed version of yarn, called berry, save it to a .yarn/releases/ directory in your project, and set up a .yarnrc.yml configuration file.

Update your project's .gitignore file:

.yarn/*
!.yarn/patches
!.yarn/releases
!.yarn/plugins
!.yarn/sdks
!.yarn/versions
.pnp.*

SSH Keys

Create an SSH configuration file to help manage connecting to multiple remote servers (so you don't have to worry about different IP addresses, usernames, ports etc.).

mkdir ~/.ssh && touch ~/.ssh/config
Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_ed25519

As new remote servers are used, you can update the configuration file to include those details.

GitHub SSH Key

Once you've setup your SSH configuration file, you can add an SSH key to GitHub for authentication.

Create new SSH key:

ssh-keygen -t ed25519 -C "lukemiloszewski@gmail.com"

Add SSH key to keychain:

eval "$(ssh-agent -s)"
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

Add SSH key to GitHub, following the steps outlined in the docs.

Fonts

I use Fira Code as my development font and FiraCode Nerd Font Mono as my terminal font.

Fira Code

The Fira Code font is battle-tested and has good support for ligatures.

To install:

  • download the font bundle from GitHub
  • inside the downloaded folder, select all font files in the tff folder
  • right click and select Open
  • install into Font Book

To configure in VS Code:

  • add the following config to settings.json:
{
  "editor.fontFamily": "Fira Code",
  "editor.fontLigatures": true
}

FiraCode Nerd Font Mono

The FiraCode Nerd Font Mono is monospace and has good support for glyphs, symbols and icons.

To install:

  • download the font bundle from Nerd Fonts
  • inside the downloaded folder, select all font files with the name Fira Code <type> Nerd Font Complete Mono.ttf (where type is any of light, medium, regular, bold, retina)
  • right click and select Open
  • install into Font Book

To configure in iTerm2:

  • go to iTerm2 > Preferences > Profiles > Text > Font (set as default)

To configure in VS Code:

  • add the following config to settings.json:
{
  "terminal.integrated.fontFamily": "FiraCode Nerd Font Mono"
}

System Settings

Display

  • Schedule Night Shift from 8PM to 6AM

Dock and Menu Bar

  • Automatically hide and show the Dock
  • Automatically hide and show the menu bar on desktop
  • Automatically hide and show the menu bar in full screen
  • Show battery status in menu bar

Finder

  • Search in current folder (Finder > Preferences > Advanced)

Keyboard

  • Use Fn key as the emoji keyboard shortcut (System Preferences > Keyboard > “Press fn key to… Show Emoji and Symbols”)

Trackpad

  • Set scroll direction to Natural

Application Settings

VS Code

Turn on Settings Sync to allow devices to authenticate with GitHub and synchronise settings, keybindings and extensions.

Google Chrome

Extensions:

Good luck! 🚀