MacOS Development workspace 2023
Tags: productivity, showdev, setup, 2023
Published: 2021-03-08 17:31:33

It is a fact that there are many guides out there about how to set up a dev workspace, however, some of them are outdated or no longer fit my needs, I have collected a lot of information from some of them and created a new guide that I want to share.

As developers we need to install almost always the same set of tools for our daily basis, so this guide will go throught a list of apps, sdks, commands and many others tools that I found useful. 

I have created a repository on [GitHub](https://github.com/jflorez29/dotfiles) to store the dotfiles and the installation script in case anyone wants to go straight to use it,  I recommend to read the guide before though.

With this guide we will assume a clean installation of MacOs and go step by step through the installation process and a short description of each app/command/tool. 

Let's open a new terminal and get started ...

## [Xcode](https://developer.apple.com/xcode/features/)

Xcode is a large suite of software development tools and libraries from Apple, even if we are not iOS/MacOs developers, this step is necessary to install **Xcode command line tools** which includes MacOs SDK, and many other common tools, compilers, and commands that we will need in the whole guide.

1. Input the following command in a Terminal

```shell
xcode-select --install
```

2. A system popup will appear to confirm the installation, click **Install** and agree the terms.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c9p2a033gsrsjfgu9346.png)

3. After the process is finished, the pop-up window will look like this. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/n43lxftyfnh23da3rzvx.png)

## [Homebrew](https://brew.sh/)

Homebrew is in general words a package manager for MacOs that allow us to install software that does not come installed by default. It works as a command tool, although there are some apps to use it with a graphical user interface like [Cakebrew](https://www.cakebrew.com/). 

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

Furthermore the default formulae, `brew` is able to track and use third parties repos, we need to add some repos and we can do it using the `brew tap 'repo'` command. 

```shell
brew tap homebrew/cask
brew tap homebrew/cask-fonts
```

* [homebrew/cask](https://github.com/Homebrew/homebrew-cask) brings simplicity, and speed to the installation and management of GUI macOS applications such as Atom and Google Chrome.
* [homebrew/cask-fonts](https://github.com/Homebrew/homebrew-cask-fonts) As we can imagin it contains free distributed fonts

I recommend visiting and reading [Hombew documentation page](https://docs.brew.sh/) to solve any doubt about brew.

Let's move to install brew packages

### Fonts

```shell
brew install font-meslo-lg-nerd-font
```

This font comes from the awesome fonts package [Nerd fonts](https://www.nerdfonts.com/) that includes developer targeted fonts such as Font Awesome, Powerline, and others. We will use this one to make our terminal pretty using icons.

By the way, we can search which fonts are included in this package by `brew search nerd` and then install any other we want just changing the name of the font in the command used before. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cc0uiww8pvnukkvf04cg.png)

### GNU Utilities 

MacOs command line tools are based on FreeBSD instead of GNU, so this could be a challenge when we want to script something supported by both platforms or if we are used to gnu commands. brew can help us installing the GNU tools, however, they come with a prefixed `g` by default. We will install following tools [coreutils](https://www.gnu.org/software/coreutils/), [moreutils](https://joeyh.name/code/moreutils/), [findutils](https://www.gnu.org/software/findutils/), [gnu-sed](https://www.gnu.org/software/sed/), [gawk](https://www.gnu.org/software/gawk/), [gnu-tar](https://www.gnu.org/software/tar/), [grep](https://www.gnu.org/software/grep/), [make](https://www.gnu.org/software/make/), check their pages and decide if you want/need all of them. 

```shell
brew install coreutils moreutils findutils gnu-sed gawk gnu-tar grep make
```

### Other Command Utilities

In this section we will install other commands and utilities. 

- [htop](https://www.geeksforgeeks.org/htop-command-in-linux-with-examples/): A better option than top to monitor the system.
- [tree](https://www.geeksforgeeks.org/tree-command-unixlinux/) It's useful to list directories and files recursively.
- [exa](https://github.com/ogham/exa): It's an alternative to the default listing command `ls`.
- [cowsay](https://alligator.io/workflow/cowsay/): Generates an ASCCI picture of a cow with a message passed by string.
- [bat](https://github.com/sharkdp/bat): A cat clone with syntax highlighting and Git integration.
- [clementtsang/bottom/bottom](https://github.com/ClementTsang/bottom): A graphical process/system monitor with a customizable interface and a multitude of features.
- [tldr](https://tldr.sh/): It's an option to get the the command options and practical examples.
- [jid](https://github.com/simeji/jid): An utility to view and interact JSON content with a terminal.
- [hiperfine](https://github.com/sharkdp/hyperfine): A command-line benchmarking tool.
- [highlight](http://www.andre-simon.de/doku/highlight/en/highlight.php): Converts sourcecode to HTML, XHTML, RTF, LaTeX, TeX, SVG, BBCode and terminal escape sequences with coloured syntax highlighting.
- [nvim](https://neovim.io/): It's an alternative vim-based editor with lots of plugins and programming languages supported.
- [youtube-dl](https://ytdl-org.github.io/youtube-dl/): A command-line program to download videos from YouTube and other sites.
- [autojump](https://github.com/wting/autojump): A faster way to navigate your filesystem
- [httpie](https://httpie.io/): It's a user-friendly command-line HTTP client, it comes with JSON support, syntax highlighting, persistent sessions, wget-like downloads, plugins, and more.
- [thefuck](https://github.com/nvbn/thefuck): It's an app able to correct errors in previous console commands.
- [golang](https://golang.org/), [python](https://www.python.org/), [python3](https://www.python.org/): Programming languages.
- [kap](https://getkap.co/): It's an screen recorder built with web technology.

```shell
brew install htop tree exa cowsay bat clementtsang/bottom/bottom \
vim tldr jid hyperfine highlight nvim youtube-dl autojump \
httpie thefuck golang python python3 git kap
```

### GUI Apps 

Some of the applications that we will install do not need a description, we will explain those that are probably not common or deserve to be listed. 

- [iterm2](https://iterm2.com/): An alternative to the default terminal app brings an amazing performance and customization.
- [expressvpn](https://www.expressrefer.com/refer-friend?locale=es&referrer_id=47839744&utm_campaign=referrals&utm_medium=copy_link&utm_source=referral_dashboard): It's the best vpn service I have tried with lot of servers around the world and good performance.
- [alfred](https://www.alfredapp.com/): An app that allow to be more efficient with shortcuts, searches and own workflows.
- [bitwarden](https://bitwarden.com): Service of security for passwords, files, credit cards, it has a nice integration and synchronization in wide list of devices.
- [stats](https://github.com/exelban/stats): A pretty macOS system monitor in the menu bar, includes CPU, Memory, disk, network, fans.
- [notion](https://www.notion.so/): The app to create boards, take notes, track tasks, get organized and many othe features.
- [ticktick](https://www.ticktick.com/home): A To-do and habit tracker app.
- [authy](https://authy.com/): 2nd Factor authentication app, it's able to get syncronized in cloud.
- [dash](https://kapeli.com/dash): Useful to download and store api documentation sets.
- [insomnia](https://insomnia.rest/): An alternative to postman for design and test apis.
- [kawa](https://github.com/hatashiro/kawa): A macOS input source switcher with user-defined shortcuts.
- [copyq](https://hluk.github.io/CopyQ/): CopyQ is advanced clipboard manager with editing and scripting features.
- [calibre](https://calibre-ebook.com/): It's an open source e-book manager.

```shell
brew install --cask firefox spotify iterm2 expressvpn \
alfred the-unarchiver visual-studio-code docker \
postman atom stats notion telegram ticktick zoom vlc \
intellij-idea whatsapp authy \
dash insomnia kawa copyq calibre \
microsoft-office brave-browser discord virtualbox skype
```

## Iterm 2

Iterm2 provides a lot of features and customization is one of them, for people who have gotten used to dark mode like me, we have a lot of themes to choose from.

We will use [dracula theme](https://draculatheme.com/iterm), for that we need to download the `.itermcolors` file either by cloning the repo or downloading the zip.

Once we have the file in our filesystem we need to open Iterm2 preferences -> profile ->  colors

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gy8qcmuv09wv00k0mxt7.png)

Import the `Dracula.itermcolors` downloaded before and then choose Dracula as theme

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6zeo1wv9xyrvz3o5qu7j.png)

Now we will change the font to **MesloLGS Nerd Font Mono** the one installed in a previous step to make iterm able to show icons with powerline fonts. 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zv2fz5sklzvau9uwv6uh.png)

P.S. Oh-my-zsh and powerlevel10k still need to be installed for Iterm to look like this.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1mms898qbc5d7fdv911m.png)

## [Oh-My-Zsh](https://ohmyz.sh/)

Since MacOs Catalina, zsh is the default shell on MacOs, zsh provides over 200 plugin integrations and is very similar to bash. There is a good comparison between the two [here](https://sunlightmedia.org/bash-vs-zsh/).

Oh-my-zsh is an open source and powerful community framework for managing zsh.

We can install oh-my-zsh with following command

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

Or this one if we like wget

```shell
sh -c "$(wget https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh -O -)" 
```

### Plugins

Oh-my-zsh provides [too many useful plugins](https://github.com/ohmyzsh/ohmyzsh/wiki/Plugins), we are going to install a few of them. 

* [zsh-autosuggestion](https://github.com/zsh-users/zsh-autosuggestions): It suggests commands as you type based on history and completions.
* [zsh-syntax-highlighting](https://github.com/zsh-users/zsh-syntax-highlighting.git): provides syntax highlighting for command type in the prompt of zsh terminal. 
* [fzf](https://github.com/junegunn/fzf.git): It's a powerful command line finder. 
* [powerlevel10k](https://github.com/romkatv/powerlevel10k.git): It's a theme for Zsh. It emphasizes speed, flexibility and out-of-the-box experience.

```shell
### Install zsh-autosuggestions
git clone --depth=1 https://github.com/zsh-users/zsh-autosuggestions ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/zsh-autosuggestions
### Install zsh-syntax-highlighting
git clone --depth=1 https://github.com/zsh-users/zsh-syntax-highlighting.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/plugins/zsh-syntax-highlighting
### Install fzf
git clone --depth 1 https://github.com/junegunn/fzf.git ~/.fzf
~/.fzf/install
### Install powerlevel10k theme
git clone --depth=1 https://github.com/romkatv/powerlevel10k.git ${ZSH_CUSTOM:-$HOME/.oh-my-zsh/custom}/themes/powerlevel10k
```

Once the plugins are installed, we must activate them by modifying the `~/.zshrc` file wich is the zsh configuration file. 

```bash:.zshrc
....
plugins=(git zsh-syntax-highlighting zsh-autosuggestions fzf)
....
```

And this will activate powerlevel10k theme

```bash:.zshrc
ZSH_THEME="powerlevel10k/powerlevel10k"
```

Finally the `.zshrc` file should looks like this.

```bash:.zshrc
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
  source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi

export ZSH="/Users/user/.oh-my-zsh"

ZSH_THEME="powerlevel10k/powerlevel10k"

plugins=(git zsh-syntax-highlighting zsh-autosuggestions fzf)

source $ZSH/oh-my-zsh.sh

# fzf plugin
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh

# To customize prompt, run `p10k configure` or edit ~/.p10k.zsh.
[[ ! -f ~/.p10k.zsh ]] || source ~/.p10k.zsh
```

We need to restart the terminal and then the powerlevel10k configuration wizard will start. 


## [NVM](https://github.com/nvm-sh/nvm)

Nvm is a version manager for node js, it helps us to install different versions of node and change it easily. 

We will install it by executing next command in the terminal

```shell
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.0/install.sh | bash
```

During the installation process it will try to add some exports to `.zshrc` file to be able to use it. the file should include some lines like this: 

```bash
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"  # This loads nvm
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"  # This loads nvm bash_completio
```

Once we have verified that the lines are included, we should reload the session with `source ~/.zshrc` or open a new terminal window.

Now we can install any node version we want, in this case we will install the most recent lts version released

```shell
nvm install node lts
```

then we can check that node is installed properly

```shell
node --version
```

## [SDKMAN](https://sdkman.io/)

SDKMAN is a tool for managing parallel versions of multiple Software Development Kits on most Unix based systems, It provides a convenient Command Line Interface (CLI) and API for installing, switching, removing and listing Candidates.

To install sdkman input the following command in a new terminal

P.S. In this case we don't want to let it modify our bash files because we will do it by ourself for that we add the query param `rcupdate=false`, we can remove it if we want update the files with the installation. 

```shell
curl -s "https://get.sdkman.io?rcupdate=false" | bash
```

After the process is finished we need to add the following lines to our `~/.zshrc` file and reload the shell by `source ~/.zshrc` to be able to use it.

```bash
export SDKMAN_DIR="$HOME/.sdkman"
[[ -s "$SDKMAN_DIR/bin/sdkman-init.sh" ]] && source "$SDKMAN_DIR/bin/sdkman-init.sh"
```

Now we can install any sdk availble into sdman. We will install JDK, to know which versions are available we can use the `list` option `sdk list java`

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ejap51fz50im6sldwua3.png)

With the list obtained before we should use the column **Identifier** to indicare what version we want.

```shell
sdk install java 11.0.10.j9-adpt
```

Now we should be able to use java JDK.

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fikq27l1a580b76q6ycp.png)

There are many other sdks, we can check them here https://sdkman.io/sdks 

## dotfiles

These dotfiles consist of 7 files, each one with an specific purpose. 

- [`.aliases`](https://github.com/kmiloflorez2/dotfiles/blob/master/.aliases): All the shortcuts for most used commands.
- [`.functions`](https://github.com/kmiloflorez2/dotfiles/blob/master/.functions): A set of useful bash functions.
- [`.exports`](https://github.com/kmiloflorez2/dotfiles/blob/master/.exports): All the exports needed for the software installed in this guide.
- [`.gitconfig`](https://github.com/kmiloflorez2/dotfiles/blob/master/.gitconfig): Git configuration
- [`.gitignore`](https://github.com/kmiloflorez2/dotfiles/blob/master/.gitignore): General git ignore configuration.
- [`.p10k.zsh`](https://github.com/kmiloflorez2/dotfiles/blob/master/.p10k.zsh): powerlevel10k theme configuration, this is the file generated by the theme installation.
- [`.zshrc`](https://github.com/kmiloflorez2/dotfiles/blob/master/.zshrc): zsh file configuration, includes plugins declaration, theme, and imports of other dotfiles.

## Defaults write commands

Commands for change default MacOs preferences

### Finder

```shell
# Show file extensions 
defaults write NSGlobalDomain AppleShowAllExtensions -bool true
# Disable the warning before emptying the Trash
defaults write com.apple.finder WarnOnEmptyTrash -bool false
# Use list view in all Finder windows by default
# Four-letter codes for the other view modes: `icnv`, `clmv`, `Flwv`
defaults write com.apple.finder FXPreferredViewStyle -string "Nlsv"
# When performing a search, search the current folder by default
defaults write com.apple.finder FXDefaultSearchScope -string "SCcf"
# Disable the warning when changing a file extension
defaults write com.apple.finder FXEnableExtensionChangeWarning -bool false
```

### Dock

```shell
# Set the icon size of Dock items to 48 pixels
defaults write com.apple.dock tilesize -int 48
# Show indicator lights for open applications in the Dock
defaults write com.apple.dock show-process-indicators -bool true
# Speed up Mission Control animations
defaults write com.apple.dock expose-animation-duration -float 0.1
# Remove the auto-hiding Dock delay
defaults write com.apple.dock autohide-delay -float 0
# Remove the animation when hiding/showing the Dock
defaults write com.apple.dock autohide-time-modifier -float 0.1
# Automatically hide and show the Dock
defaults write com.apple.dock autohide -bool true
```

### Activity Monitor 

```shell
# Show the main window when launching Activity Monitor
defaults write com.apple.ActivityMonitor OpenMainWindow -bool true
# Visualize CPU usage in the Activity Monitor Dock icon
defaults write com.apple.ActivityMonitor IconType -int 5
# Show all processes in Activity Monitor
defaults write com.apple.ActivityMonitor ShowCategory -int 0
# Sort Activity Monitor results by CPU usage
defaults write com.apple.ActivityMonitor SortColumn -string "CPUUsage"
defaults write com.apple.ActivityMonitor SortDirection -int 0
```

### Others
```shell
# Disable the sound effects on boot
sudo nvram SystemAudioVolume=" "
# Don’t display the annoying prompt when quitting iTerm
defaults write com.googlecode.iterm2 PromptOnQuit -bool false
```

## Other Apps

- [Total finder](https://totalfinder.binaryage.com/): Plugin for add tabs, tags and other features to finder.
- [Clean my mac](https://cleanmymac.com): Cleaner app for MacOs.
- [Pocket](https://getpocket.com): App to save content to check later.
- [Magnet](https://apps.apple.com/es/app/magnet/id441258766): Window manager app.

## References 

- [donnemartin - dev setup](https://github.com/donnemartin/dev-setup)
- [Awesome Mac](https://github.com/jaywcjlove/awesome-mac)
- [rgomezcasas - dotfiles](https://github.com/rgomezcasas/dotfiles)
- [alrra - dotfiles](https://github.com/alrra/dotfiles)
- [setup zsh environment on Mac](https://abawchen.gitlab.io/chore/2018/03/28/setup-zsh-environment-on-mac.html)
- [personal workspace setup](https://hackernoon.com/personal-macos-workspace-setup-adf61869cd79)
- [using GNU command line tools in Mac](https://ryanparman.com/posts/2019/using-gnu-command-line-tools-in-macos-instead-of-freebsd-tools/)