Website logo
Pablo Porto
Author photo
Draft

Minimal macOS development setup for 2022

Every three years or so my work laptop gets renewed. Every time I have to set it up from strach. This year I took the opportunity to look at my current setup with the pareto's principle in mind. What are the 20% of the tools and configurations that I leverage or use 80% of the time? In other words, what are the minimum vital few things I should setup to stay productive as a professional software developer.

Getting Started

If you are starting from scratch like me, I recommend starting by installing all the latest OS level updates. The first step is to install and upgrade the xcode command line tools.

xcode-select --install

The package manager

One of the frist tools we need is a package manager. For macOS I recommend brew. You can install it with a simple command.

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

Finally, update brew and make sure everything is working fine with the following commands.

brew update
brew doctor

Security

Following the principle of shifting left security, lets first configure some sensible defaults to keep our Mac protected.

  • Enable file encryption with FileVault.
  • Enable the firewall.
  • Setup a strong password for your OS user and enable touchid if required.
  • Install your password manager of choise so we can login into services and apps going forward. I use and recommend 1Password.
  • Install any pending security updates.
  • Enable automatic updates for security patches and apps installed via the App Store.

Setting up automatic updates for brew packages

Brew has a feature to enable automatic updates called autoupdate. The tool will run brew update in the background once every 24 hours. You can customize the time interval.

# Set auto-updates every 7 days
brew autoupdate start --upgrade 604800

The terminal

As developers, we spend most of the time either in the IDE, the terminal or a browser. There are two important choices to make regarding our terminal setup: the shell and the terminal app you use. Over the years I defaulted to ZSH for the shell and Hyper for the app.

Setting up Zsh

The newest versions of macOS come with Zsh installed. On top of that, I manage my Zsh configuration with OhMyZsh.

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

and I setup the following plugins and theme in .zshrc

ZSH_THEME="gallois"

plugins=(
  git
  autojump
  vagrant
)

Setting up Hyper

brew install --cask hyper

Next step is to edit the configuration. I increase the font size and leave everything else as default.

vim ~/Library/Application Support/Hyper/.hyper.js

Minimal CLI tools

  • jq
  • autojump
  • git
  • wget
  • docker
  • watch

The code editor or IDE

I use Visual Studio Code as lightweight code editor and IntelliJ as integrated developer environment (IDE).

I default to VSCode for most of my development tasks but when I have to leverage refactoring functionality (e.g. when I work in backend services with Java or Kotlin) I prefer IntelliJ and its powerful refactoring shortcuts.

Install IntelliJ Community Edition

brew install intellij-idea-ce

Disable the MacOS shortcuts Cmd+Shift+A to prevent a clash with the IntelliJ action command. Follow this guide.

Install VSCode

brew install visual-studio-code

The version control system

Git has become the standard for version control systems.

Setup your global Git config

vim ~/.gitconfig

This is how mine looks like

[user]
name = "Pablo"
email = "personal email"

[alias]
st = status
lol = log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

[core]
excludesfile = ~/.gitignore_global

[pull]
rebase = false

[includeIf "gitdir:~/Dev/work/"]
path = ~/.gitconfig-work

I also configure a globa .gitignore.

# ~/.gitignore_global

# OS generated files #
######################
.DS_Store
.DS_Store?

# IDEs #
######################
.idea

If you use your laptop for both personal and work projects, you can isolate your work config in a separate file. The statement includeIf allows you to specific a different config file that will only apply in the directory & subdirectories set with gitdir. This is an example of my separate file for work.

[user]
   name = "Pablo@work"
   email = "work@email.com"
[core]
   sshCommand = "ssh -i ~/.ssh/work.ssh.key"

SSH

Create a ssh config to simplify how you connect to remote machines (and how you pull code from Github & co).

vim ~/.ssh/config
Include ssh_config_work

Host github.com
	IdentityFile ~/.ssh/personal_private_key

Host bitbucket.org
	IdentityFile ~/.ssh/personal_private_key

As we did for the Git config, you can isolate your work config into a separate file using Include. This is how my work ssh config looks like.

#Work

Host github.com-work
	HostName github.com
	AddKeysToAgent yes
	UseKeychain yes
	IdentityFile ~/.ssh/work_private_key

Host work-machine.training
    User ec2-user

Runtime version manager

Dealing with multiple versions of language runtimes is painful. When you work on different projects, you will need to switch versions of the different runtimes: node, java, etc. Installing version managers for each runtime will make your life easier.

Node

Node Version Manager or NVM is my preferred choice to manage active Node.js versions.

brew install nvm

After installing nvm we need to add the following piece of configuration in our ZSH config file.

# ~/.zshrc

export NVM_DIR="$HOME/.nvm"
  [ -s "/opt/homebrew/opt/nvm/nvm.sh" ] && \. "/opt/homebrew/opt/nvm/nvm.sh"  # This loads nvm

Java

Coming soon..

Python

I use Pyenv to manage the different Python versions I install on my Mac. I install Pyenv with Brew.

brew install pyenv

Configure the shell environment.

echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.zshrc
echo '[[ -d $PYENV_ROOT/bin ]] && export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.zshrc
echo 'eval "$(pyenv init -)"' >> ~/.zshrc

Poetry is my preferred build tool for Python. Here is how I install it with Brew and pipx.

brew install pipx
pipx ensurepath
pipx install poetry

Ruby

I use rbenv to manage the different Ruby versions I install on my Mac. I install rbenv with Brew.

brew install rbenv ruby-build
rbenv init

Configure the shell environment.

echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc

And finally, set a default Ruby version for your machine.

rbenv global 3.3.0

Docker as container runtime

Since Docker Desktop change its licensing in mid 2021, several alternatives to run Docker in macOS popped up. My favourite so far is Colima.

With the following steps we can have a fully working Colima-based Docker setup in our Mac:

brew install colima
brew install docker
brew install docker-compose

API explorer

Bruno. Coming soon..

MacOS configuration

Coming soon..

Productivity apps

Other apps that I use to stay productive.

Application Purporse
Rectangle Window manager
Flux Screen eye protection
1password Password manager
Mural Online whiteboarding
Figma Prototyping
Todoist Task manager
Notion Knowledge base / digital garden
Spotify Music
Chrome Browser
Slack Communication and communities
AppCleaner Managing MacOS apps not installed by brew
Obsidian Secure notes

If you are curious what are my default choices for building frontend, backend and data applications you can check my prefered tech stack.

Conclusions

This is my current minimal macOS developer setup. I will keep updating this post as I finish setting up my laptop. Stay tuned!