If you’ve built a command-line tool and want to make it easy for users to install, Homebrew is one of the best distribution methods available. In this guide, I’ll walk you through creating your own Homebrew tap—a custom repository that allows users to install your software with a simple brew install command.

Steps Overview

  1. Prepare Your Binary Releases
  2. Create Your Tap Repository
  3. Write Your Formula
  4. Get SHA256 Checksums
  5. Push Your Formula
  6. Test Your Tap
  7. Share Your Tap

What is Homebrew?

Homebrew is the most popular package manager for macOS, and it also works on Linux. It allows users to install software from the command line with simple commands like brew install wget. Think of it as an app store for command-line tools and applications.

Understanding Homebrew Vocabulary

Before we dive in, let’s clarify some key terms:

  • Formula: A Ruby script that tells Homebrew how to download, build, and install a piece of software. It’s essentially a recipe for installing your application.

  • Tap: A third-party repository of formulas. While Homebrew has a main repository (homebrew-core) with thousands of formulas, taps allow anyone to create their own custom repository. The name comes from the idea of “tapping a keg”—you’re adding a new source of software.

  • Bottle: A pre-compiled binary version of software. Instead of compiling from source, users can download a ready-to-use binary, making installation much faster.

  • Cask: A formula specifically for installing GUI applications (like browsers or editors) rather than command-line tools.

  • Cellar: The directory where Homebrew installs software (/usr/local/Cellar on Intel Macs, /opt/homebrew/Cellar on Apple Silicon).

Why Create a Tap?

Creating your own tap is perfect when:

  • You want to distribute your own CLI tools or applications
  • Your software isn’t popular enough (yet!) for homebrew-core
  • You need faster iteration without going through the homebrew-core review process
  • You want to maintain multiple versions or experimental releases

Prerequisites

Before starting, make sure you have:

  • A GitHub account
  • A CLI tool or application you want to distribute
  • Binary releases of your application (we’ll cover this)
  • Basic familiarity with Git and GitHub

Step 1: Prepare Your Binary Releases

Homebrew formulas need downloadable binaries. The most common approach is to use GitHub Releases.

Using GoReleaser (for Go projects)

If your project is written in Go, GoReleaser makes this incredibly easy. Add a .goreleaser.yml file:

builds:
  - env:
      - CGO_ENABLED=0
    goos:
      - linux
      - darwin
    goarch:
      - amd64
      - arm64

archives:
  - format: tar.gz
    name_template: >-
      {{ .ProjectName }}_{{ .Version }}_
      {{- title .Os }}_
      {{- if eq .Arch "amd64" }}x86_64
      {{- else }}{{ .Arch }}{{ end }}

checksum:
  name_template: "checksums.txt"

Then create a release:

git tag -a v1.0.0 -m "First release"
git push origin v1.0.0
goreleaser release --clean

Manual Binary Releases

If you’re not using Go or GoReleaser, you’ll need to:

  1. Build binaries for different platforms (macOS Intel, macOS ARM, Linux x86_64, Linux ARM64)
  2. Package them as .tar.gz archives
  3. Upload them to a GitHub release
  4. Generate SHA256 checksums

Example for generating checksums:

shasum -a 256 your-app-darwin-arm64.tar.gz
shasum -a 256 your-app-darwin-amd64.tar.gz
shasum -a 256 your-app-linux-amd64.tar.gz

Step 2: Create Your Tap Repository

Your tap must be a GitHub repository with a specific naming convention:

  1. Create a new repository named homebrew-<your-tap-name>

    • For example: homebrew-tools or homebrew-myapp
    • The homebrew- prefix is required
  2. Create the directory structure:

mkdir -p Formula

That’s it! Homebrew only needs the Formula directory.

Step 3: Write Your Formula

Create a file at Formula/<your-app>.rb. Here’s a complete example for a CLI tool called “sky”:

class Sky < Formula
  desc "A powerful CLI tool for cloud management"
  homepage "https://github.com/yourusername/sky-cli"
  version "1.0.0"

  on_macos do
    if Hardware::CPU.arm?
      url "https://github.com/yourusername/sky-cli/releases/download/v1.0.0/sky_1.0.0_Darwin_arm64.tar.gz"
      sha256 "abc123...your-arm64-sha256-here"
    else
      url "https://github.com/yourusername/sky-cli/releases/download/v1.0.0/sky_1.0.0_Darwin_x86_64.tar.gz"
      sha256 "def456...your-x86_64-sha256-here"
    end
  end

  on_linux do
    if Hardware::CPU.arm?
      url "https://github.com/yourusername/sky-cli/releases/download/v1.0.0/sky_1.0.0_Linux_arm64.tar.gz"
      sha256 "ghi789...your-linux-arm64-sha256-here"
    else
      url "https://github.com/yourusername/sky-cli/releases/download/v1.0.0/sky_1.0.0_Linux_x86_64.tar.gz"
      sha256 "jkl012...your-linux-x86_64-sha256-here"
    end
  end

  def install
    bin.install "sky"
  end

  test do
    system "#{bin}/sky", "--version"
  end
end

Understanding the Formula

Let’s break down each section:

  • class Sky < Formula: The class name must match your filename (sky.rb → Sky class), capitalized
  • desc: A short, one-line description of your tool
  • homepage: Your project’s website or GitHub repository
  • version: The version number
  • on_macos / on_linux: Platform-specific configurations
  • Hardware::CPU.arm?: Detects ARM architecture (M1/M2 Macs, ARM Linux)
  • url: The download URL for your binary
  • sha256: The checksum to verify download integrity
  • install: Instructions for installing your binary (typically just copying to the bin directory)
  • test: A simple test to verify the installation works

Step 4: Get SHA256 Checksums

You need SHA256 checksums for each binary. The easiest way:

# Download and checksum in one command
curl -sL https://github.com/yourusername/app/releases/download/v1.0.0/app_Darwin_arm64.tar.gz | shasum -a 256

# Or if you have the file locally
shasum -a 256 app_Darwin_arm64.tar.gz

Copy these checksums into your formula where indicated.

Step 5: Push Your Formula

git add Formula/your-app.rb
git commit -m "Add formula for your-app v1.0.0"
git push origin main

Step 6: Test Your Tap

Now you can test your tap locally:

# Add your tap
brew tap yourusername/your-tap-name

# Install your application
brew install your-app

# Test it works
your-app --version

Step 7: Share Your Tap

Users can now install your application with just two commands:

brew tap yourusername/your-tap-name
brew install your-app

Or in a single command:

brew install yourusername/your-tap-name/your-app

Updating Your Formula

When you release a new version:

  1. Create a new GitHub release with updated binaries
  2. Get the new SHA256 checksums
  3. Update your formula with new version, URLs, and checksums
  4. Commit and push

Users can then update with:

brew update
brew upgrade your-app

Advanced Tips

Auto-update with Dependabot

Add .github/dependabot.yml to your tap repository:

version: 2
updates:
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"

Adding Dependencies

If your app requires other software:

depends_on "[email protected]"
depends_on "git"

Multiple Binaries

If your release contains multiple executables:

def install
  bin.install "main-app"
  bin.install "helper-tool"
  bin.install "utility"
end

Configuration Files

Install configuration or documentation files:

def install
  bin.install "your-app"
  etc.install "config.yml" => "your-app/config.yml"
  doc.install "README.md"
end

Troubleshooting Common Issues

“Formula not found” error

Make sure your repository name starts with homebrew- and your formula is in the Formula/ directory.

SHA256 mismatch

If you get a checksum error, recalculate your SHA256:

curl -sL YOUR_URL | shasum -a 256

Cached formula not updating

Force Homebrew to refresh:

brew untap yourusername/your-tap
brew tap yourusername/your-tap

Or clear the cache:

rm -rf $(brew --repository)/Library/Taps/yourusername/homebrew-your-tap
brew tap yourusername/your-tap

Downloads failing with 404

Verify your release assets are publicly accessible. Go to your GitHub release page and try downloading the files manually. If your repository is private, the assets won’t be accessible via Homebrew.

Best Practices

  1. Test before publishing: Always test your formula locally before pushing
  2. Use semantic versioning: Follow semver (1.0.0, 1.1.0, 2.0.0)
  3. Keep formulas simple: Don’t add unnecessary complexity
  4. Document installation: Add installation instructions to your project’s README
  5. Maintain checksums: Always verify SHA256 checksums match your binaries
  6. Support multiple platforms: Provide binaries for both Intel and ARM architectures
  7. Add a test block: Include a simple test to verify installation

Next Steps

Now that you have your tap set up, consider:

  • Adding your tap to awesome lists and directories
  • Writing documentation for your users
  • Automating formula updates with CI/CD
  • Eventually submitting to homebrew-core once your project gains traction

Have questions or run into issues? Check out the official Homebrew documentation.