Help us improve
Share bugs, ideas, or general feedback.
From homebrew-dev
Creates, tests, and maintains Homebrew formulas via JSON Schema to Mustache templates. Use for custom taps, debugging builds/tests, brew audit, livecheck automation, and language-specific installs (Go, Rust, Python).
npx claudepluginhub arustydev/agents --plugin homebrew-devHow this skill is triggered — by the user, by Claude, or both
Slash command
/homebrew-dev:pkgmgr-homebrew-formula-devThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Guide for researching, creating, testing, and maintaining Homebrew formulas in a custom tap.
README.mdjustfilepackage-lock.jsonpackage.jsonreference/Brewfilereference/checklists/add-language.mdreference/checklists/local-validation.mdreference/faq/common.mdreference/langs/c.mdreference/langs/clojure.mdreference/langs/cpp.mdreference/langs/custom.mdreference/langs/dart.mdreference/langs/dotnet.mdreference/langs/elixir.mdreference/langs/erlang.mdreference/langs/fortran.mdreference/langs/gleam.mdreference/langs/go.mdreference/langs/groovy.mdProvides expertise in Justfile syntax, recipe development, parameters, shebangs for multi-language scripts, and cross-platform task automation with naming conventions and CI/CD integration.
Publishing to package managers. Homebrew, apt/deb, winget, Scoop, Chocolatey manifests.
Manages Ruby gems and Bundler: writes Gemfiles with version constraints and groups, runs bundle commands, creates gem structures and gemspecs, handles Gemfile.lock.
Share bugs, ideas, or general feedback.
Guide for researching, creating, testing, and maintaining Homebrew formulas in a custom tap.
This skill includes a JSON Schema → Mustache template pipeline for generating formulas from structured data.
scripts/formula.schema.tsjust template-formula <path-to-json> to validate and render| File | Purpose |
|---|---|
scripts/formula.schema.ts | JSON Schema (draft-2020-12) defining formula structure |
scripts/formula.helper.ts | Preprocessing: PascalCase, license rendering, install flattening, partials loading |
reference/templates/main.mustache | Main template — renders all shared fields, dispatches to language partials |
reference/templates/langs/*.mustache | Language-specific install partials (go, rust, python, zig, cmake, autotools, meson) |
test/data/*.json | Test fixtures covering each scenario |
test/cases/*.sh | Test cases that validate rendered output |
# Render a formula from JSON
just template-formula path/to/formula.json
# Run all tests
just test
install-<lang> definition to scripts/formula.schema.tsallOf entry in the formula definitionreference/templates/langs/<lang>.mustache partial"<lang>" to the language enumtest/data/ and test case in test/cases/Before creating a formula, gather this information:
| Field | How to Find |
|---|---|
| Latest version | gh api repos/owner/repo/releases/latest --jq '.tag_name' (404 → HEAD-only) |
| License | Check LICENSE file or repo metadata (use SPDX identifier) |
| Build system | Look at Makefile, go.mod, Cargo.toml, pyproject.toml, etc. |
| Dependencies | Check build docs, CI files, or dependency manifests |
| Default branch | Check repo settings — may be main or master |
| Binary name | May differ from formula name — check Cargo.toml [[bin]], Go cmd/, or pyproject.toml [projectcli] |
| Scenario | Type | Has url/sha256? | Has livecheck? |
|---|---|---|---|
| Tagged releases | Standard | Yes | Yes |
| No releases | HEAD-only | No | No |
| Monorepo subdirectory | Standard | Yes | Yes |
curl -sL "https://github.com/owner/repo/archive/refs/tags/vX.Y.Z.tar.gz" | shasum -a 256
hex-patch, jwt-ui)HexPatch, JwtUi)Formulas are organized alphabetically: Formula/<first-letter>/<name>.rb
| Element | Purpose |
|---|---|
desc | Short description (~80 chars) for brew info |
homepage | Project homepage URL |
url | Source tarball URL (omit for HEAD-only) |
sha256 | Checksum (omit for HEAD-only) |
license | SPDX identifier |
head | Git URL for --HEAD installs |
livecheck | Auto-detect new versions (omit for HEAD-only) |
depends_on | Build or runtime dependencies |
test | Verification block |
| License | SPDX |
|---|---|
| MIT | "MIT" |
| Apache 2.0 | "Apache-2.0" |
| GPL 3.0 (only) | "GPL-3.0-only" |
| GPL 3.0 (or later) | "GPL-3.0-or-later" |
| BSD 2-Clause | "BSD-2-Clause" |
| BSD 3-Clause | "BSD-3-Clause" |
Always specify -only or -or-later for GPL/LGPL/AGPL.
Each language has a reference doc with install patterns, schema fields, and common issues:
reference/langs/go.mdreference/langs/rust.mdreference/langs/python.mdAdditional languages supported by the template pipeline (cmake, autotools, meson, zig) — see their Mustache partials in reference/templates/langs/.
| Topic | Location |
|---|---|
| Local validation steps | reference/checklists/local-validation.md |
| Common issues & FAQ | reference/faq/common.md |
| Test block patterns | reference/testing/patterns.md |
| Generated formula examples | reference/templates/formulas/*.rb |
| JSON Schema definition | scripts/formula.schema.ts |
| Bottle attestation & provenance | reference/security/attestation.md |
When creating many formulas at once:
curl | shasum calls concurrentlyruby -c *.rb to syntax-check all formulas before pushingWhen a project provides pre-built binaries for different architectures:
Preferred: Build from source (avoids architecture complexity)
If pre-built binaries required: Use resource blocks, NOT url/sha256 in on_arm/on_intel:
on_arm do
resource "binary" do
url "https://github.com/org/repo/releases/download/vX.Y.Z/tool-darwin-arm64.tar.gz"
sha256 "..."
end
end
on_intel do
resource "binary" do
url "https://github.com/org/repo/releases/download/vX.Y.Z/tool-darwin-amd64.tar.gz"
sha256 "..."
end
end
def install
resource("binary").stage do
bin.install "tool"
end
end
See reference/faq/common.md for details on deprecated patterns.
| Problem | Symptom | Solution |
|---|---|---|
| Missing runtime dependency | brew linkage --test shows broken deps | Add dependency globally, not just in on_linux |
| Wrong dependency order | brew style fails with ordering error | Build deps (=> :build) before runtime deps, alphabetically within each |
| Rust + OpenSSL linkage | Linkage test shows libssl.3.dylib broken | Add depends_on "openssl@3" globally (not just Linux) if binary links dynamically |
| Problem | Symptom | Solution |
|---|---|---|
pip_install buildpath missing deps | ModuleNotFoundError at runtime | Use pip_install "package==#{version}" to install from PyPI |
| PyPI name differs from repo | pip can't find package | Check pyproject.toml for actual name field (e.g., ktool → k2l) |
| Missing setuptools | No module named 'pkg_resources' | Add venv.pip_install "setuptools" before main package |
| Wrong pip invocation | Failed to execute: .../libexec/bin/pip | Use venv.pip_install, not system libexec/"bin/pip" |
| Problem | Symptom | Solution |
|---|---|---|
| Binary name mismatch | Test can't find binary | Check Cargo.toml [[bin]] or pyproject.toml [projectcli] for actual name |
| Help text mismatch | assert_match fails | Run binary locally to verify actual output before writing test |
| Output to stderr | shell_output returns empty | Add 2>&1 redirect: shell_output("#{bin}/tool --help 2>&1") |
See reference/faq/common.md for detailed explanations and additional issues.
Formula/<letter>/<name>.rbruby -c passes (syntax check)brew audit --new passesbrew style passes (or issues addressed)brew install --build-from-source succeedsbrew test passes