mac setup guide for web development
-- As of this writing, I can confirm that all of these tools work on M1+ and intel based macs.
After going through this setup on multiple machines over the years, I’m finally taking the time to write it down and I'll try to update it as my workflow and technology preferences change. Most of these steps and tools are very personal to me and how I like to work but you might find gems for yourself.
Assumes
- MacOS Monterrey or newer
- Package management with homebrew. I’ll do a separate post on nix one day 🤞🏽
- iterm2 + zsh
- doom emacs. No strong opinions here, just less heavy than spacemacs
- (caveat: I don’t use emacs regularly, but I learned some of the most useful keybindings so I’m stuck with it for now).
- node.js via NVM, better version management for node.js
- fzd as fuzzy finder
- Rectangle as window manager
- Clippy as copy / paste buffer extension tool
Applications
via package manager
# window manager
brew install --cask rectangle
# increase your paste buffer stack length from 1 to n
brew install --cask clipy
brew install --cask visual-studio-code
# github sign-in to sync settings
Dependencies
Breaking these up into individual commands helps with some of the setup after (as suppose to doing a big brew install x y z
).
brew install emacs
brew install nvm
# after
export NVM_DIR="$HOME/.nvm"
[ -s "/usr/local/opt/nvm/nvm.sh" ] && . "/usr/local/opt/nvm/nvm.sh" # This loads nvm
[ -s "/usr/local/opt/nvm/etc/bash_completion.d/nvm" ] && . "/usr/local/opt/nvm/etc/bash_completion.d/nvm"
brew install fzf
# after
[ -f ~/.fzf.zsh ] && source ~/.fzf.zsh
brew install z
# after
. /usr/local/etc/profile.d/z.sh
brew install direnv
# after
eval "$(direnv hook zsh)"
Environment Variables
Direnv is a great way to keep your environment variables relatively close to the project that needs them. Example from project page:
# Create a new .envrc. This file is bash code that is going to be loaded by
# direnv.
$ echo export FOO=foo > .envrc
.envrc is not allowed
# allow it
$ direnv allow .
direnv: reloading
direnv: loading .envrc
direnv export: +FOO
# Show that the FOO environment variable is loaded.
$ echo ${FOO-nope}
foo
# Exit the project
$ cd ..
direnv: unloading
# And now FOO is unset again
$ echo ${FOO-nope}
nope
Terminal PS1 Decorator
- p10k is all i need these days, it is nice, concise and easy to setup.
echo $PS1
Terminal Navigation
fzd
Fuzzy finding is an absolute must these days as the command line args for different languages are getting increasingly complex.
I'm looking at you Clojure! with stuff like clj -A:dev -M -m project.web.server.dev-main
:angry-fist-emoji:.
Use ctrl + r
to engage fuzzy finding.
Z
I use z frequently to jump between different directories. It works by building up a small database based on how frequently you visit those directories. Once it's learned enough about your project, it can become quite easy for z to know where you wanna go next.
❯ z -l
0.255153 /Users/dav/foo
0.268972 /Users/dav/bar
0.276813 /Users/dav/war
...
next time you wanna go to a directory, all you have to do is
z foo
pwd
-> /Users/dav/foo
Iterm2 key preferences
In iterm, go to profiles > keys > key mappings
and select Natural text editing. This makes it so that you can use arrow keys in terminal navigation and a bunch of other useful keybindings come with it.
Bash Functions
function gitinit(){
git init && git add . -v && git commit -am 'init'
}
function masterToMain(){
git branch -m master main
git fetch origin
git branch -u origin/main main
git remote set-head origin -a
}
SSH
For "silky smooth hopping" ;)
$ cat <<EOF > ~/.ssh/config
Host kimchitaco
HostName 127.0.0.1
User root
IdentityFile ~/.ssh/id_rsa
EOF
now everytime you wanna hop to 127.0.0.1 all you have to do is ssh kimchitaco
Git Config
$ cat <<EOF > ~/.gitconfig
[user]
name = David A. Viramontes
email = <email>
[color]
ui = true
[core]
editor = emacs
excludesfile = /Users/$HOME/.gitignore_global
[alias]
co = checkout
cm = commit
s = status
b = branch
up = push origin HEAD
cp = cherry-pick
hist = log --pretty=format:\"%h %ad | %s%d [%an]\" --graph --date=short
[init]
defaultBranch = main
[pull]
ff = true
[credential]
helper = store
EOF
Global Gitignore
$ cat <<EOF > ~/.gitignore_global
.idea
*.iml
.DS_Store
.java-version
.elixir_ls
.tool-versions
EOF
Takes effect after running:
git config --global core.excludesfile ~/.gitignore_global
Golang
After 1.8 this became much easier.
mkdir ~/go
And then add this to your ~/.zshrc
export GOPATH=$HOME/go
export GOBIN=$GOPATH/bin
export PATH=$PATH:$GOBIN
verify
go env GOBIN
go env GOPATH
Elixir & Erlang
Other ways to get erlang and elixir into your system are more convenient but this is the setup i've found to be most reliable
- install adsf
- Add plugins
-
asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git
-
asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir.git
asdf install erlang 25.0.3
asdf install elixir 1.14.0-rc.0-otp-25
asdf global erlang 25.0.3
asdf global elixir 1.14.0
asdf reshim
- add shims bin to path
-
export PATH="$HOME/.asdf/shims:$PATH"
Aliases
alias zshedit="emacs ~/.zshrc"
alias ll="ls -lh"
That's it for now. I'll update this post as I go, so check back!