β Distributing my own scripts via homebrew
β’ 404 words β’ 2 min
Thanks Justin Searls for the idea:
I use Homebrew all the time. Whenever I see a new CLI that offers an npm or uv install path alongside a brew one, I choose brew every single time.
Me too.
And yet, when it comes time to publish a CLI of my own, I usually just ship it as a Ruby gem or an npm package, because I had (and have!) no fucking clue how Homebrew works. I’m not enough of a neckbeard to peer behind the curtain as soon as root directories like /usr and /opt are involved, so I never bothered before today.
I understand how package managers work, and I’m even a package maintainer in Alpine Linux and Arch Linux, but until now I never bothered to package my own projects for others to consume.
Previously I talked about my new pancake repository. It consists of miscellaneous self-contained executables. As such, it is a great candidate for packaging.
I won’t submit it to upstream homebrew because it is overly specific, but that doesn’t prevent me from packaging it in a standalone repository.
In order to do so, I simply created a pancake.rb Formula:
class Pancake < Formula
desc "A collection of useful shell scripts"
homepage "https://github.com/thiagowfx/pancake"
head "https://github.com/thiagowfx/pancake.git"
def install
# keep-sorted start
bin.install "aws_china_mfa/aws_china_mfa.sh" => "aws_china_mfa"
bin.install "op_login_all/op_login_all.sh" => "op_login_all"
bin.install "pritunl_login/pritunl_login.sh" => "pritunl_login"
bin.install "sd_world/sd_world.sh" => "sd_world"
# keep-sorted end
end
test do
# Basic test to ensure the scripts are installed and executable.
# keep-sorted start
assert_predicate bin/"aws_china_mfa", :executable?
assert_predicate bin/"aws_china_mfa", :exist?
assert_predicate bin/"op_login_all", :executable?
assert_predicate bin/"op_login_all", :exist?
assert_predicate bin/"pritunl_login", :executable?
assert_predicate bin/"pritunl_login", :exist?
assert_predicate bin/"sd_world", :executable?
assert_predicate bin/"sd_world", :exist?
# keep-sorted end
end
endTo install it, first tap the repository1:
% brew tap thiagowfx/pancake https://github.com/thiagowfx/pancake.gitThen install it, from HEAD because it is not currently versioned:
% brew install --HEAD pancakeList all package contents:
% brew ls pancake
/opt/homebrew/Cellar/pancake/HEAD-1a58c53/bin/aws_china_mfa
/opt/homebrew/Cellar/pancake/HEAD-1a58c53/bin/op_login_all
/opt/homebrew/Cellar/pancake/HEAD-1a58c53/bin/pritunl_login
/opt/homebrew/Cellar/pancake/HEAD-1a58c53/bin/sd_world
/opt/homebrew/Cellar/pancake/HEAD-1a58c53/sbom.spdx.jsonThere’s no need to fiddle with $PATH, as this is already handled by homebrew:
% which aws_china_mfa
/opt/homebrew/bin/aws_china_mfa
% ls -al /opt/homebrew/bin/aws_china_mfa
lrwxr-xr-x@ - thiago.perrotta 13 Oct 14:43 /opt/homebrew/bin/aws_china_mfa -> ../Cellar/pancake/HEAD-1a58c53/bin/aws_china_mfa*Backlinks
- homebrew: turn go install into a formula (Aug 10, 2026)
- cco: claude condom (sandbox) (Feb 26, 2026)
- brew: upgrade HEAD formulas (Oct 23, 2025)