sandwich recipe
Prime’s My Dev Setup Is Better Than Yours stuck with me when I watched it last year. Moral of the course (which is more a demo) is – your setup is best for you because it’s yours - custom built for how you work. I tried mocking it with sparse commits here and there. The real kick was changing jobs last year which means new laptop and new vigor to create my “dev setup”. Instead of bikeshedding and analysis paralysis, I went brrr and built a workflow on shoulders of giants. This is production grade software where production is “works on my machine :P”.
Hence, with an obligatory XKCD reference, I tagged 1.0 for
sudo make me a sandwich i.e. my “dev setup”
which is working really well (for now). Hence, future Harman will thank current
epoch: 1769955510 Harman, for organizing the dev setup and writing a few words
about it. In a nutshell:
brew bundlemanages the bottles and casks that I needjustreduces the number of bash script neededstowmanages the dotfiles
choosing Homebrew and brew bundle
The first version of dev repo had install scripts which will pull the binaries
from internet and install them based on the type of binary that I would get. And
I was in for a treat when I was trying to install a .dmg or a .pkg file!
MacOS doesn’t have an inbuilt programmatic approach to install compared to
dpkg or apt which I’m well versed with. MacOS wants its users to
deliberately do clickops to install and configure stuff. It was a jarring
experience overall and suddenly the script started looking crazy long full of
different conventions (a) no checksum (b) managing versions (c) validating
install after copying stuff (d) handle .app bundles or manage .pkg
installers. This reminded me of Flatpak/AppImage drama on Linux minus the
traction.
Meanwhile, on a daily basis I was still going strong with brew install ...
which was ergonomic, clean and simple. Although, there is a different issue with
Homebrew (a) I need to install that first (b) I had to create a mental model
around brew commands. I found myself using the manpage and brew --help too
often. brew bundle however can be used to install most tools - tui, cli, or
gui.
Homebrew isn’t perfect - it’s another dependency, and I need to memorize commands - but wins on pragmatism: declarative and “it just (TM) works”. Nix seems to be the closest thing to “proper package management” on MacOS, but it’s solving a problem Apple doesn’t want to solved, and has friction. Also, a steep learning curve for me.
just vs make
For this project, just and make are task-runners. I pick a project, work on
it and then leave it as is for months; when I come back, I’ve forgotten how to
do chores e.g. following. Task runners solve this problem.
- Do I need to update
Brewfilefirst? - Or should I install the tool with
brew install ...and then check ifBrewfileis updated? - That other time, I just installed
jqand myBrewfiledoesn’t know I need it always! - How to bootstrap this new macbook? What steps did I take last time?
make is a build system which happens to work as a task runner. And for most
developer machines make is always present. For MacOS, make is present after
xcode-select --install — which is the first thing most developers do after
getting a new Mac. Despite these merits, I didn’t invest a lot of time and
effort into learning make. just was simple, easier and I had used it in
past. So, I went with just for this repo even though it requires an install.
In recent future, I wish to spend a weekend and learn make and its quirks
(I know some!) and ditch just for this project.
stumbling upon stow
I’ve seen countless option for dotfile management. And I’ve seen so many
handrolled solutions to manage dotfiles. My requirement for dotfiles is very
simple i.e. copy the files to XDG_CONFIG_HOME (in my case ~/.config dir). I
found stow in a HN thread and earmarked it to try when I want to do dotfiles.
I don’t use 90% of things stow can do but what I needed was good enough and
very ergonomic.
desires and wishes
There are many improvements which I’ve not detailed out quite. 2025 Harman would have created a list of TODOs which would give him “Phantom Obligation”1. Today, however, I’m choosing to dump my raw thoughts here and address it when it becomes imminent.
Improvement 1: simpler bootstrap steps
As of 02d2867, the bootstrap requires me to install homebrew, install
just and stow using homebrew, clone this repo, define XDG_CONFIG_HOME2,
and install required software using brew bundle and configure most of them
with stow. That leaves out folder structure for Git and SSH key generation for
Github.
I want to learn make, and handroll a shell script to symlink .config as
first improvement. This would allow me to clone (public) Github repo with HTTPS
link in /tmp directory and go brr… with the setup. Since I don’t buy a
Macbook so often, this improvement doesn’t provide the ROI required.
Improvement 2: make it work for my servers too
I don’t buy Macbooks too often, but I create and delete Linux servers couple of times in a month. Right now, my setup implies only local setup and not servers. I tried Claude Code on my server with a prompt to setup most common tools and it did a good job of setting everything up. But it is non-deterministic and I get a setup which is different from Macbook in different ways (each time) with same prompt. Solving this problem would make me saner. In last 2 weeks, I’ve seen several new services surface up providing ephemeral machines3 providing amazing method to create and test a llm-based deterministic dev setup which can merge with this repo.
Improvement 3: master more tools
I use ripgrep, fzf, direnv and many other applications but I use them raw.
I’ve not learnt all my tools. Good thing is the boilerplate for adding their
configuration already exists and when I become power-tool-ninja, I can start
managing them with current workflow.
Improvement 4: smaller neovim configuration
Right now, I use kickstart.nvim and I’ve been using it for some time. It is a
remnant of time when I was starting with neovim and was spending a lot of time
to make basic stuff work on vim. I understand neovim configuration enough now
that I don’t need a monolith neovim configuration. However, I don’t wish to make
neovim modular at first; I want to strip out all the unnecessary stuff out of
kickstart and get a feel for managing a config that I own and maintain. Again,
the ROI on this is not large and I don’t want to do this right now.
Improvement 5: Nix for package management
I’m parking Nix until I have a stronger reason to invest the learning time — or until I switch to Arch.
EOF
I read this amazing article about feed readers UX creating a sense of urgency to read an article and coin the word that suits this behavior I’ve demonstrated in past. Phantom Obligation ↩︎
While writing this post I learned that, Apple/NeXTSTEP conventions (circa:1989) predate XDG Base Directory specifications (circa:2003) and latter was created to solve the chaos in Linux ecosystem and has community-driven voluntary enforcement. I always found XDG Base Directory spec to be very intuitive and wondered this is a MacOS quirk. Since, I run Linux on servers and I’m forced to use MacOS at work, I want to follow this convention through and through to reduce cognitive load. ↩︎
exe.dev and Sprites are among few such projects that seem super interesting to run (and re-run) dev setup scripts and refine with ease. ↩︎