### CHANGELOG # Changelog All notable changes to zerobrew will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] ### Changed - Bump MSRV to 1.96, required to build the latest `cargo-audit` in CI ([#393](https://github.com/lucasgelfond/zerobrew/pull/393)) - Refresh `Cargo.lock` for audit findings: `crossbeam-epoch` (RUSTSEC-2026-0204), `quinn-proto` (RUSTSEC-2026-0185), and `anyhow` (RUSTSEC-2026-0190) ([#393](https://github.com/lucasgelfond/zerobrew/pull/393)) ### Fixed - Relink on upgrade/reinstall: symlinks owned by another version of the same formula — including dangling links left behind by removed kegs — are now replaced during linking instead of failing the link step as conflicts with the formula itself, which left `bin`/`opt` pointing at the old version while the DB reported the new one ([#393](https://github.com/lucasgelfond/zerobrew/pull/393)) ## [0.3.2] - 2026-06-11 ### Security - Verify SHA-256 checksums for resource and URL patch downloads in the formula build shim before extraction or application (CVE-2026-53970) ## [0.3.1] - 2026-05-30 ### Fixed - Centralize a single, sandbox-tolerant rustls `ClientConfig` in `network::tls`: prefer native roots, and fall back to the bundled webpki-roots Mozilla roots when no system trust store is available ([#375](https://github.com/lucasgelfond/zerobrew/pull/375)) - Correct migration behavior on unplannable formulas ([#380](https://github.com/lucasgelfond/zerobrew/pull/380)) ### Changed - Clarify standalone installer shell setup and update flow: surface `zb init` output, print shell-specific reload commands after shell config changes, print exact `export`/fish commands for `--no-modify-path`, report installed/updated/already-current status on reruns, and warn when an older `zb` still appears earlier in `PATH` ([#381](https://github.com/lucasgelfond/zerobrew/pull/381)) - Clarify `zb update` help/output and README update docs so users know `zb update` refreshes package metadata while the installer or Homebrew updates the `zb` binary itself ([#381](https://github.com/lucasgelfond/zerobrew/pull/381)) ## [0.3.0] - 2026-05-29 ### Added - Eleventy-based homepage with responsive styling, interactive panels, benchmark/install content, and site assets ([#309](https://github.com/lucasgelfond/zerobrew/pull/309)) - `zb doctor` command with `--repair` flag for state diagnosis, recovery, orphaned store entries, and broken symlinks ([#314](https://github.com/lucasgelfond/zerobrew/pull/314)) - Chinese translation of the README ([#316](https://github.com/lucasgelfond/zerobrew/pull/316)) - `zb upgrade` command to upgrade installed packages, with `--build-from-source` and `--no-link` flags; supports upgrading all outdated packages or specific ones by name ([#369](https://github.com/lucasgelfond/zerobrew/pull/369)) ### Fixed - Validate root/prefix paths before passing to sudo to prevent shell injection ([#311](https://github.com/lucasgelfond/zerobrew/pull/311)) - Regex matches only version segments within Cellar-style paths when patching Mach-O binary strings ([#317](https://github.com/lucasgelfond/zerobrew/pull/317)) - Update vulnerable `aws-lc-sys`, `aws-lc-rs`, and `rustls-webpki` dependencies ([#318](https://github.com/lucasgelfond/zerobrew/pull/318)) - Make `just fmt` apply formatting and document the workflow ([#319](https://github.com/lucasgelfond/zerobrew/pull/319)) - Resolve formula aliases and oldnames after API 404s ([#332](https://github.com/lucasgelfond/zerobrew/pull/332)) - Skip linking `libexec` Python `site-packages` paths to avoid conflicts ([#368](https://github.com/lucasgelfond/zerobrew/pull/368)) - Make `zb upgrade` clean old cellar metadata, stay idempotent after download failures, and exit non-zero for missing requested packages ([#369](https://github.com/lucasgelfond/zerobrew/pull/369)) - Ignore stale macOS prefix environment defaults when initializing or resolving paths ([#372](https://github.com/lucasgelfond/zerobrew/pull/372)) - Resolve Linux `uses_from_macos` dependencies, rewrite Linuxbrew bottle paths, and restrict Linux bottle fallback by architecture ([#373](https://github.com/lucasgelfond/zerobrew/pull/373)) ### Changed - Split monolithic install module into focused submodules ([#312](https://github.com/lucasgelfond/zerobrew/pull/312)) - Split monolithic download module into focused submodules ([#313](https://github.com/lucasgelfond/zerobrew/pull/313)) - Document Homebrew tap installation as an alternative install method ([#325](https://github.com/lucasgelfond/zerobrew/pull/325)) - Refresh dependency lockfile entries ([#330](https://github.com/lucasgelfond/zerobrew/pull/330)) - Make migration install only leaf formulae from Homebrew ([#333](https://github.com/lucasgelfond/zerobrew/pull/333)) - Prefer direct Homebrew install instructions in README files ([#337](https://github.com/lucasgelfond/zerobrew/pull/337)) - Refresh `Cargo.lock` for audit findings ([#345](https://github.com/lucasgelfond/zerobrew/pull/345), [#363](https://github.com/lucasgelfond/zerobrew/pull/363)) - Pin release workflow Ubuntu runners to 22.04 for stability ([#352](https://github.com/lucasgelfond/zerobrew/pull/352)) - Add CLI help text for command arguments and flags ([#355](https://github.com/lucasgelfond/zerobrew/pull/355)) - Add and then revert the security scanning workflow ([#354](https://github.com/lucasgelfond/zerobrew/pull/354), [#358](https://github.com/lucasgelfond/zerobrew/pull/358)) ## [0.2.1] - 2026-03-14 ### Fixed - Fix `zb outdated` panic caused by clap type mismatch between global `verbose` (u8 count) and subcommand `verbose` (bool) flags ([#308](https://github.com/lucasgelfond/zerobrew/pull/308)) ## [0.2.0] - 2026-03-12 ### Added - Batch processing for `zb migrate` command ([#285](https://github.com/lucasgelfond/zerobrew/pull/285)) - `zb outdated` command with `--quiet`/`--verbose`/`--json` output modes ([#266](https://github.com/lucasgelfond/zerobrew/pull/266)) - `zb update` command ([#266](https://github.com/lucasgelfond/zerobrew/pull/266)) - Tracing-based internal logging with `-v`/`--verbose` and `-q`/`--quiet` flags ([#275](https://github.com/lucasgelfond/zerobrew/pull/275)) - Configurable UI theme and writer-based output layer ([#274](https://github.com/lucasgelfond/zerobrew/pull/274)) - Fuzzy formula suggestions on missing package errors ([#279](https://github.com/lucasgelfond/zerobrew/pull/279)) - `ZEROBREW_API_URL` support and persistent API cache ([#252](https://github.com/lucasgelfond/zerobrew/pull/252)) - Build provenance attestation in release workflow ([#247](https://github.com/lucasgelfond/zerobrew/pull/247)) ### Fixed - Added SQLite schema versioning with sequential migrations and downgrade protection([#305](https://github.com/lucasgelfond/zerobrew/pull/305)) - Global lock on installer to prevent concurrent install corruption ([#304](https://github.com/lucasgelfond/zerobrew/pull/304)) - Strip zerobrew's bin paths from `PATH` during install to prevent dyld errors on re-install ([#289](https://github.com/lucasgelfond/zerobrew/pull/289)) - Warn when Mach-O in-place patching is skipped due to prefix length mismatch (Intel Mac) ([#286](https://github.com/lucasgelfond/zerobrew/issues/286)) - Prefer compatible macOS bottle tags over newer ones ([#283](https://github.com/lucasgelfond/zerobrew/pull/283)) - Ruby syntax backwards compatibility for source builds ([#282](https://github.com/lucasgelfond/zerobrew/pull/282)) - Skip extraction on raw binaries and copy to keg bin dir directly ([#278](https://github.com/lucasgelfond/zerobrew/pull/278)) - Chunked download robustness and memory efficiency ([#270](https://github.com/lucasgelfond/zerobrew/pull/270)) - Skip libexec virtualenv metadata links to avoid cross-formula conflicts ([#248](https://github.com/lucasgelfond/zerobrew/pull/248)) - Link formulas on Linux when Homebrew marks them keg-only ([#249](https://github.com/lucasgelfond/zerobrew/pull/249)) - Preprocess resolver before parsing ([#244](https://github.com/lucasgelfond/zerobrew/pull/244)) ### Changed - Eliminate unwraps, reduce allocations, decompose install path ([#292](https://github.com/lucasgelfond/zerobrew/pull/292)) - Removed `--yes` alias from global `--auto-init` flag ([#287](https://github.com/lucasgelfond/zerobrew/pull/287)) ## [0.1.2] - 2026-02-15 ### Added - Local source build fallback — compile packages from source when no bottle is available ([#212](https://github.com/lucasgelfond/zerobrew/pull/212)) - `--build-from-source` / `-s` flag for `zb install` ([#212](https://github.com/lucasgelfond/zerobrew/pull/212)) - External tap and cask support with safer install/uninstall behavior ([#203](https://github.com/lucasgelfond/zerobrew/pull/203)) - GitHub release installs with clone fallback ([#198](https://github.com/lucasgelfond/zerobrew/pull/198)) - Source-only tap formula support with scoped parsing ([#232](https://github.com/lucasgelfond/zerobrew/pull/232)) - Resolve tap formulas from `Formula/`, `HomebrewFormula/`, and repo root ([#231](https://github.com/lucasgelfond/zerobrew/pull/231)) - `zb bundle dump` subcommand with Brewfile syntax support ([#218](https://github.com/lucasgelfond/zerobrew/pull/218)) ### Fixed - Include zbx binaries in GitHub releases ([#229](https://github.com/lucasgelfond/zerobrew/pull/229)) - Preserve execute bit when patching Mach-O binary strings ([#228](https://github.com/lucasgelfond/zerobrew/pull/228)) - Skip patching when new prefix is longer than old ([#227](https://github.com/lucasgelfond/zerobrew/pull/227)) - Prevent bricked installs from link conflicts, respect keg-only formulas ([#207](https://github.com/lucasgelfond/zerobrew/pull/207)) - Default macOS prefix to `/opt/zerobrew` to stay within the 13-char Mach-O path limit ([#206](https://github.com/lucasgelfond/zerobrew/pull/206)) - Shell init management and fish support ([#200](https://github.com/lucasgelfond/zerobrew/pull/200)) - Remove `-D` flag from install since directories are already created ([#221](https://github.com/lucasgelfond/zerobrew/pull/221)) - Force static liblzma linking and verify macOS binaries ([#222](https://github.com/lucasgelfond/zerobrew/pull/222)) - Formula token normalization across crates ([#230](https://github.com/lucasgelfond/zerobrew/pull/230)) - Default macOS prefix to root on install scripts ([#239](https://github.com/lucasgelfond/zerobrew/pull/239)) ### Changed - Refreshed README with banner and star history ([#224](https://github.com/lucasgelfond/zerobrew/pull/224)) ## [0.1.1] - 2026-02-08 Initial release of zerobrew - a fast, modern package manager. We're excited for our pilot release and want to thank all of the support from all channels, as well as all of our contributors up to this point. To get an idea of the initial features zerobrew supports, take a look at the [README](https://github.com/lucasgelfond/zerobrew#readme). See the [full commit history](https://github.com/lucasgelfond/zerobrew/commits/v0.1.1) for more details. [Unreleased]: https://github.com/lucasgelfond/zerobrew/compare/v0.3.2...HEAD [0.3.2]: https://github.com/lucasgelfond/zerobrew/compare/v0.3.1...v0.3.2 [0.3.1]: https://github.com/lucasgelfond/zerobrew/compare/v0.3.0...v0.3.1 [0.3.0]: https://github.com/lucasgelfond/zerobrew/compare/v0.2.1...v0.3.0 [0.2.1]: https://github.com/lucasgelfond/zerobrew/compare/v0.2.0...v0.2.1 [0.2.0]: https://github.com/lucasgelfond/zerobrew/compare/v0.1.2...v0.2.0 [0.1.2]: https://github.com/lucasgelfond/zerobrew/compare/v0.1.1...v0.1.2 [0.1.1]: https://github.com/lucasgelfond/zerobrew/releases/tag/v0.1.1 --- ### CONTRIBUTING # Contributing to zerobrew Thanks for your interest in contributing to zerobrew! This document provides guidelines for contributing to the project. ## Licensing By contributing to zerobrew, you agree your contributions will be dual-licensed under either [Apache](./LICENSE-APACHE.md) OR [MIT](./LICENSE-MIT.md), at the licensee's choice. ## Soft Prerequisites - Rust 1.90 or later - Access to either a macOS or Linux machine ## A note on LLM usage While we encourage the use of LLM's for thinking through problems, helping with tests, and even writing code, we simply cannot accept or tolerate PRs with no clear guidance or thought put into them. **_Please understand_** that we reserve the right to simply close your PR if it exhibits clear indicators of heavy LLM usage. We understand you are excited to contribute but the code must reach a level of quality that's typically achieved through thoughtful engagement in the community and the issues/agenda of zerobrew- NOT by throwing a prompt into an LLM and opening a PR with no direction. If you ever need help or want to walk through an issue or idea that you have with one of the maintainers, feel free to join the [community discord](https://discord.gg/TVatsQBFJt); we would be more than happy to assist you. ## Project Structure zerobrew is organized as a Cargo workspace with three crates: - `zb_core`: Core data models and domain logic (formula resolution, bottle selection) - `zb_io`: I/O operations (API client, downloads, extraction, installation) - `zb_cli`: Command-line interface Any changes you make that touch several crates should be organized properly. See [commit hygiene](#commit-hygiene) ## General Development Workflow We prefer that a PR is linked to an open issue or previously discussed through other channels. If you are introducing changes that aren't otherwise reported or tracking please either reach out in the Discord to give us a heads up or open an issue first to discuss your changes. **General flow:** 1. Fork the repo 2. Make your changes and ensure, at the _least_: - Code is formatted: `cargo fmt --all` - No clippy warnings: `cargo clippy --workspace --all-targets -- -D warnings` - Unit tests pass: `cargo test --workspace` - Integration tests pass: `cargo test --workspace -- --ignored` (or `just test` for all tests) > [!NOTE] > These will run in CI but it's best you clean up your code _before_ opening a PR to ensure a quick > turnaround! ### Using Just This project includes a `Justfile`, Install [just](https://github.com/casey/just) and use these commands instead of `cargo` (for ease of development): - `just build` Check formatting, lint, then build the binary (Builds debug binary) - `just install` Build and install zb to $HOME/.local/bin (Customizable with `$ZEROBREW_BIN`) - `just uninstall` Remove all zerobrew installations and configurations - `just fmt` Format code with rustfmt - `just fmt-check` Check code formatting - `just lint` Run clippy with strict warnings - `just test` Run all workspace tests (unit & integration) Before creating a PR make sure you `build` your changes and `test` them. 3. Write tests for new functionality. Each module should have accompanying tests. 4. Commit your changes with clear, descriptive commit messages (see below) 5. Push to your fork and submit a pull request. ## Commit hygiene We ask that you follow the format below for commits: ```bash [fix / feat]($crate): description ``` for instance: ```bash fix(zb_cli): foo bar moo baz ``` Allowed prefixes: ```bash fix # -> fixes a bug or regression feat # -> new feature chore # -> housekeeping (deps, typos in docs, etc.) tests # -> added, changed or removed tests ci # -> changes to ci refactor # -> refactored code perf # -> performance related build # -> changes to build system (i.e. ext deps, tooling, scripts, etc) ``` Generally speaking, we also ask that you please write isolated, [atomic commits](https://en.wikipedia.org/wiki/Atomic_commit). This means if you are approaching a PR that touches various parts of the codebase for example, ensure that your commits are contained and cleanly seperated, properly describing/notating which commits belong where. ## Testing - Unit tests should be colocated with the code in `mod tests` blocks - Use `tempfile` for filesystem tests - Use `wiremock` for HTTP mocking in integration tests - Tests should be deterministic and not rely on external network access ## Running Benchmarks To benchmark performance: ```bash just bench --full ``` This runs a 100-package installation suite comparing zerobrew to Homebrew. This is especially crucial to run if you are planning on contributing to performance/optimization related changes. Useful options: ```bash just bench --quick just bench --dry-run just bench --full results/ just bench --format csv --output benchmark.csv just bench --log bench.log ``` Notes: - Defaults to the quick package list (22 packages); use `--full` for all 100. - `--full [dir]` writes all formats (txt/json/csv/html) to the directory. - `--output` infers format from file extension when `--format` is omitted. - Output includes cold + warm cache speedups per package. ### macOS Homebrew permissions On macOS, Homebrew should be installed with a user-writable prefix. If `just bench` fails with a permission error, fix it by running: ```bash sudo chown -R "$(whoami)" "$(brew --prefix)" ``` ## Questions? For further questions, open an issue on GitHub. --- ### README

zerobrew

English · 中文

[](https://github.com/lucasgelfond/zerobrew/actions/workflows/ci.yml) [](https://github.com/lucasgelfond/zerobrew/actions/workflows/test.yml) [](https://github.com/lucasgelfond/zerobrew/releases) [](https://discord.gg/ZaPYwm9zaw) [](./LICENSE-MIT.md) [](./LICENSE-APACHE.md) zerobrew demo

zerobrew brings uv-style architecture to Homebrew packages on macOS and Linux.

## Install ```bash curl -fsSL https://zerobrew.rs/install | bash ``` The installer updates your shell config. After it finishes, restart your terminal or run the `source` command it prints. Or via Homebrew: ```bash brew install lucasgelfond/zerobrew/zerobrew ``` ## Update zerobrew If you used the standalone installer, rerun it: ```bash curl -fsSL https://zerobrew.rs/install | bash zb --version ``` If you installed with Homebrew: ```bash brew update && brew upgrade zerobrew ``` ## Quick start ```bash zb install jq # install one package zb install wget git # install multiple zb bundle # install from Brewfile zb bundle install -f myfile # install from custom file zb bundle dump # export installed packages to Brewfile zb bundle dump -f out --force # dump to custom file (overwrite) zb uninstall jq # uninstall one package zb outdated # list packages with newer versions zb upgrade # upgrade all outdated packages zb upgrade jq wget # upgrade specific packages zb reset # uninstall everything zb gc # garbage collect unused store entries zbx jq --version # run without linking ``` ## Performance snapshot
| Package | Homebrew | ZB (cold) | ZB (warm) | Cold Speedup | Warm Speedup | |---------|----------|-----------|-----------|--------------|--------------| | **Overall (top 100)** | 452s | 226s | 59s | **2.0x** | **7.6x** | | ffmpeg | 3034ms | 3481ms | 688ms | 0.9x | 4.4x | | libsodium | 2353ms | 392ms | 130ms | 6.0x | 18.1x | | sqlite | 2876ms | 625ms | 159ms | 4.6x | 18.1x | | tesseract | 18950ms | 5536ms | 643ms | 3.4x | 29.5x |
## Relationship with Homebrew zerobrew is more of a performance-optimized client for the Homebrew ecosystem. We rely on: - Homebrew's formula definitions (homebrew-core) - Homebrew's pre-built bottles when available - Homebrew's package metadata and infrastructure Our innovations focus on: - Content-addressable storage for deduplication - APFS clonefiles for zero-overhead copying - Source build fallback using Homebrew's Ruby DSL zerobrew is experimental. We recommend running it alongside Homebrew rather than as a replacement, and do _not_ recommend purging homebrew and replacing it with zerobrew unless you are absolutely sure about the implications of doing so. ## Project status
Star History Chart
- **Status:** Experimental, but already useful for many common Homebrew formulas. - **Feedback:** If you hit incompatibilities, please open an issue or PR. - **License:** Dual-licensed under [Apache 2.0](./LICENSE-APACHE.md) OR [MIT](./LICENSE-MIT.md), at your choice. --- ### SECURITY # Security Policy ## Supported Versions We take security seriously and provide security updates for the latest version zerobrew. We strongly recommend keeping your zerobrew dependencies up to date. ## Reporting a Vulnerability **Please do not report security vulnerabilities through public GitHub issues.** If you discover a security vulnerability in nmrs or any of the related crates, please report it privately by emailing **lucas.gelfondATgmail.com**. Please include the following information in your report: - A clear description of the vulnerability - Steps to reproduce the issue - Potential impact and attack scenarios - Any suggested fixes or mitigations - Your contact information for follow-up questions ### What constitutes a security vulnerability? For zerobrew, security vulnerabilities may include but are not limited to: - **Package substitution**: Ability to install malicious packages by manipulating formula resolution or tap priority - **Privilege escalation**: Unauthorized access to system directories or operations that should require elevated permissions - **Credential exposure**: Leaking API tokens, tap credentials, or other sensitive data through logs, errors, or memory - **Path traversal**: Malicious bottle archives that could write files outside the intended cellar/store directories - **Denial of service**: Crashes, hangs, or resource exhaustion that prevent legitimate package management - **Information disclosure**: Exposing installed packages, store paths, or system configuration to unauthorized processes - **Input validation failures**: Improper handling of malformed formula names, tap references, or bottle data leading to undefined behavior - **Race conditions**: Timing vulnerabilities in concurrent downloads, extraction, or linking that could lead to security issues - **Checksum bypass**: Ability to install packages without proper SHA256 verification or with manipulated checksums - **Symlink attacks**: Malicious symlinks in bottles that could overwrite system files during materialization or linking - **Dependency confusion**: Installing malicious packages by exploiting tap resolution order or dependency specifications - **Supply chain attacks**: Compromised taps or formula sources serving backdoored bottles - **Arbitrary code execution**: Malicious bottles containing executables that run with user privileges during installation - **Dependency vulnerabilities**: Security issues in upstream crates (reqwest, tokio, tar, etc.) that affect zerobrew For the CLI specifically: - **Command injection**: Malicious formula names or tap references that could execute unintended shell commands - **File system access**: Unauthorized reading or writing of files outside the intended root/prefix directories ## Response Timeline We are committed to responding to security reports promptly: - **Acknowledgment**: We will acknowledge receipt of your vulnerability report within **24 hours** - **Initial assessment**: We will provide an initial assessment of the report within **5 business days** - **Regular updates**: We will provide progress updates at least every **7 days** until resolution - **Resolution**: We aim to provide a fix or mitigation within **30 days** for critical vulnerabilities Response times may vary based on the complexity of the issue and availability of maintainers. ## Disclosure Policy We follow a coordinated disclosure process: 1. **Private disclosure**: We will work with you to understand and validate the vulnerability 2. **Fix development**: We will develop and test a fix in a private repository if necessary 3. **Coordinated release**: We will coordinate the public disclosure with the release of a fix 4. **Public disclosure**: After a fix is available, we will publish a security advisory We request that you: - Give us reasonable time to address the vulnerability before making it public - Avoid accessing or modifying data beyond what is necessary to demonstrate the vulnerability - Act in good faith and avoid privacy violations or destructive behavior ## Security Advisories Published security advisories will be available through: - GitHub Security Advisories on the [zerobrew repository](https://github.com/lucasgelfond/zerobrew/security/advisories) - [RustSec Advisory Database](https://rustsec.org/) - Release notes and changelog entries ## Recognition We appreciate the security research community's efforts to improve the security of zerobrew. With your permission, we will acknowledge your contribution in: - Security advisories - Release notes - Project documentation If you prefer to remain anonymous, please let us know in your report. ## Scope This security policy covers zerobrew wholly. ## Additional Resources - [Contributing Guidelines](CONTRIBUTING.md) - [Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct) - [Rust Security Policy](https://www.rust-lang.org/policies/security) Thank you for helping to keep zerobrew and the Rust ecosystem secure! ---