Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AntiBrow Homebrew Tap

Official Homebrew tap for AntiBrow. Install and update the macOS desktop app with brew.

brew tap antibrow/tap
brew install --cask antibrow

Or in one line:

brew install --cask antibrow/tap/antibrow

Update and remove:

brew upgrade --cask antibrow
brew uninstall --cask antibrow          # removes the app, keeps your data
brew uninstall --zap --cask antibrow    # also removes data and caches, see below

Since Homebrew 6.0, the first install from a third-party tap asks for confirmation once. Answer yes; the decision is recorded in ~/.homebrew/trust.json and you are not asked again. To trust the whole tap up front:

brew trust --tap antibrow/tap

What this cask installs

Download https://download.antibrow.com/desktop/AntiBrow-<version>.dmg
Installs to /Applications/AntiBrow.app
Bundle ID com.antibrow.desktop
Architecture Universal binary (x86_64 + arm64), one build for Intel and Apple Silicon
Minimum macOS 11 Big Sur
Notarization Notarized by Apple (spctl reports Notarized Developer ID)
Self-update Ships electron-updater, so the app also updates itself

Because the app carries its own updater, both brew upgrade and the in-app updater work. The version in the cask mainly serves first-time installs and brew info.

If you already installed AntiBrow manually

A plain brew install conflicts with an existing /Applications/AntiBrow.app. Two ways out:

# Same version as the cask: take over the existing app without re-downloading
brew install --cask --adopt antibrow/tap/antibrow

# Different version, or you just want a clean reinstall
brew install --cask --force antibrow/tap/antibrow

What --zap deletes

zap is opt-in. A plain uninstall never touches any of this.

~/Library/Application Support/anti-detect-desktop     # profiles and fingerprints
~/Library/Caches/anti-detect-desktop-updater          # updater downloads, can be hundreds of MB
~/Library/Caches/com.antibrow.desktop
~/Library/Caches/com.antibrow.desktop.ShipIt
~/Library/HTTPStorages/com.antibrow.desktop
~/Library/Preferences/com.antibrow.desktop.plist
~/Library/Saved Application State/com.antibrow.desktop.savedState

The first entry is user data. Use brew uninstall without --zap to keep it.

Maintenance

Bumping the version by hand

./scripts/bump-cask.sh --check   # check only; exit 0 = up to date, 10 = update available
./scripts/bump-cask.sh           # rewrite version + sha256 from the manifest

Where the version and checksum come from

One source: https://download.antibrow.com/desktop/latest-mac.yml, the electron-builder manifest the app's own updater reads. livecheck uses it too, via strategy :electron_builder.

The manifest carries the version and, per artifact, both a sha512 and a sha256. A cask needs the sha256, so a bump reads it straight out and touches nothing else. Measured on 2026-08-17: about 1 second, versus roughly 2 minutes and a 220 MB download back when the sha256 had to be computed locally.

Two things the parsing has to get right:

  • Read the sha256 from the DMG's entry, not the top level. The manifest repeats sha512/sha256 at the top level for whatever path: points at, which is the .zip, and those lines sit after the DMG's entry in the file. A naive "first sha256 after the dmg url" silently picks up the .zip's hash whenever the DMG entry lacks the field, and produces a cask that fails to install with a checksum mismatch. dmg_field() scopes to the entry and returns nothing instead.
  • Keep a fallback. If a future manifest omits the DMG's sha256, the script downloads the DMG, checks it against the manifest's sha512, and hashes it locally. Both paths are exercised; point the script at a test manifest with ANTIBROW_FEED=http://... ./scripts/bump-cask.sh.

Nothing here trusts the manifest blindly at the end: CI performs a real brew install --cask, so a wrong sha256 fails the job before anything is committed.

Bumping automatically

.github/workflows/bump.yml runs the script daily at 06:17 UTC. When a new version appears it runs brew style, brew audit --new --strict --online and an install/uninstall smoke test in the same job, and only commits to main if all of them pass.

Verifying inside the bump workflow is deliberate. Commits pushed with GITHUB_TOKEN do not trigger other workflows, so expecting ci.yml to run after the push would not work.

Verifying the cask locally

Symlink this repo into Homebrew's Taps directory so edits here take effect immediately:

mkdir -p "$(brew --repository)/Library/Taps/antibrow"
ln -s "$PWD" "$(brew --repository)/Library/Taps/antibrow/homebrew-tap"

brew style antibrow/tap
brew audit --new --strict --cask --online antibrow/tap/antibrow
brew fetch --cask antibrow/tap/antibrow      # checks url + sha256, leaves /Applications alone
brew livecheck --cask antibrow/tap/antibrow  # checks that livecheck reads upstream correctly

Things that will trip you up:

  • brew style does not only check .rb files. It runs shfmt and shellcheck over scripts/ too, and shfmt wants then on its own line. brew style --fix antibrow/tap fixes it automatically.
  • Do not embed multi-line Python (or any indentation-sensitive heredoc) inside a shell script here. brew style --fix reindents such strings and silently changes the block structure, and neither bash -n nor brew style flags the result. It happened once during development and broke parsing with no error at all. Keep anything indentation-sensitive in its own file.
  • The string comparison form of depends_on macos: (">= :big_sur") is deprecated. Use the bare symbol :big_sur, which already means "that version or newer". Note the underscore; :big-sur is not a valid symbol.
  • The verified: parameter on url is deprecated. Do not add it, or --new --strict fails.
  • In zsh, do not write brew audit $flags. zsh does not word-split unquoted variables, so the whole string arrives as a single argument.

Repository naming, and adding more products later

Homebrew resolves brew tap <owner>/<name> to the GitHub repository <owner>/homebrew-<name>; internally it is literally "homebrew-#{repository}". So the only hard rule is the homebrew- prefix. The part after it is arbitrary and becomes the short name users type:

GitHub repository Tap command
antibrow/homebrew-tap brew tap antibrow/tap
antibrow/homebrew-antibrow brew tap antibrow/antibrow
antibrow/homebrew-cask brew tap antibrow/cask

homebrew-tap is just the shortest and the most common convention.

The local working directory name is irrelevant. Homebrew only cares about the path Library/Taps/<owner>/homebrew-<name>, which is a clone or a symlink it controls. This repo lives in a directory named antibrow-tap and resolves as antibrow/tap without issue.

For further products, one tap per GitHub owner is the cleaner split:

antibrow/homebrew-tap    -> brew tap antibrow/tap   -> Casks/antibrow.rb
otherproduct/homebrew-tap -> brew tap otherproduct/tap -> Casks/otherproduct.rb

Each product's install command then carries its own brand, and each repo has its own CI and release cadence. Locally, name the directories <product>-tap so they do not collide.

The alternative, one personal tap holding every product, works too. Just drop more files into Casks/ (or Formula/ for command-line tools) of a single repo, and give ci.yml a matrix over them. The cost is that the install command shows an account name unrelated to the product being installed, which reads as unofficial. Only worth it if several products share one GitHub account.

CI derives the tap owner from GITHUB_REPOSITORY, so moving this repo to another account or org needs no workflow changes. Only the antibrow/tap strings in this README need updating.

On submitting to official homebrew/cask

Not yet. Homebrew's Package Acceptance Policy judges a project's notability by stars, forks and watchers on the canonical upstream repository, and states that projects less than 30 days old are generally ineligible. As of 2026-08-14, github.com/antibrow/antibrow had 2 stars, 0 forks and 0 watchers and was created on 2026-07-29, so it fails both. Submitting now would very likely be rejected, and rejections leave a record.

Notability is the only thing missing. The distribution requirements are already met: hosted on a developer-owned domain, versioned URL, no account needed to download, signed and notarized, and an electron-builder manifest that livecheck can follow.

Casks/antibrow.rb also already clears the bar an official submission has to meet. Measured on 2026-08-17, brew audit --new --strict --cask --online exits 0 with zero offenses. Once notability is there, this exact file can be moved into homebrew-cask as a PR with no rewriting.

The point of running it in an own tap first is that the eventual submission is a file CI has validated repeatedly across several releases, rather than something written the day of the PR.

License

BSD-2-Clause, see LICENSE.

About

Official Homebrew tap for AntiBrow, an antidetect browser with a patched Chromium kernel

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages