nanobrew now serves its own bottles. Covered packages download from ghcr.io/justrach/nb-bottles, our own registry, instead of leaning on Homebrew's servers. Every pinned bottle is SBOM'd and CVE-scanned, with automatic revoke-and-fallback when one goes bad.
macOS arm64 and x86_64 tarballs are Developer-ID-signed, hardened-runtime, and notarized by Apple.
nb update # to v0.1.198
Warm install resolve dropped 147ms to 1.8ms (~80x). Cached-bottle reinstall dropped 534ms to 4ms (~130x). The gap over Homebrew (119.4x on the yt-dlp target reinstall) carries over from the v0.1.192 install path and only widens with these warm-path wins.
Before and after, measured within nanobrew. macOS Apple Silicon and Linux aarch64, representative runs. Lower is better; the gold bar is v0.1.198.
Sandboxed macOS Actions benchmark. Target reinstall means dependencies and the cache/store were primed, then only yt-dlp was removed and reinstalled as nb install --shims yt-dlp. The install path is unchanged since v0.1.192, so these carry forward, and v0.1.198's warm-path wins only widen the gap.
Everything lives under ghcr.io/justrach/nb-bottles. Public GHCR is free for storage and egress, so running it costs $0. Bottles are content-addressed, so a mirror that preserves digests is transparently trustworthy: nanobrew verifies the same sha256 either way.
NANOBREW_BOTTLE_DOMAIN=https://ghcr.io/v2/justrach/nb-bottles, moves the whole fleet over.github_release binaries (ripgrep, fd, bat, jq, gh, and friends) re-laid into bottle form and published under our namespace. They carry no Homebrew placeholders, so the relocate phase does nothing and they get the fastest install path nanobrew has: blob cache, store, copy-on-write materialize, link. These pull from our registry by default.The part Homebrew does not do. Every pinned bottle gets a real supply-chain pass, and a weekly CI cron rescans the whole fleet against fresh CVE data, opening a security issue on any hit.
syft builds an SBOM for each pinned bottle (all four platforms, Linux included), grype matches it against CVE data, and the job fails at or above the gate (default high). The first full run already caught a real one: gh 2.91.0 ships a Go 1.26.2 standard library with HIGH-severity CVEs.revoke marks a bad pin and records the previous known-good version as a fallback. The resolver then installs that fallback and prints a warning naming the advisory; a revoked pin with no fallback fails closed. No binary release is needed, since revocations propagate through the registry in about six hours. nb doctor flags any machine that already installed a now-revoked version, with the exact fix.attest ranks each upstream asset by the strongest vouching available (github-attestation, then checksum-file, then pin-only) and dies on any disagreement with upstream's published checksums. Version tags are immutable: a different blob can never be re-tagged under an existing version. SBOMs and scan reports ride along on each bottle's GHCR manifest as OCI referrer artifacts, so anyone can inspect a bottle's record without trusting our CI logs.The performance work behind the bars above.
patchelf. A short /opt/nb symlink makes every @@HOMEBREW_*@@ replacement shorter than its placeholder, so RPATH/RUNPATH, DT_NEEDED, PT_INTERP, and .rodata strings are all rewritten in one pass. No subprocesses, and no apt-get install patchelf bootstrap, which alone cost about 4.8s on every fresh machine and made installs fail where no package manager existed.cert.pem for brewed openssl/gnutls so TLS verification works on fresh Linux machines · @@HOMEBREW_PERL@@ shebangs are relocated so perl-backed tools run · download retries are hardened with a transient-only whitelist and per-worker tmp paths · NB_BENCH=1 now reports per-phase timings (extract, materialize, relocate, link, postinstall) for each package.37 new verified-upstream packages with pinned bottle digests for all four platforms, on top of the 100/100 top formulae and 100/100 top casks already covered.
nginx, qemu, colima, postgresql@14, postgresql@16, postgresql@18, mysql, tailscale
node@24, rustup, gradle, poetry, composer, automake, expat, lcov
bash, zsh, eza, btop, hexyl, httpie, direnv, aria2, rsync, telnet, ghostscript
sops, gitleaks, mkcert, kubeconform, flyctl, fastlane, xclogparser, xcresultparser, whisper-cpp, summarize
nb-arm64-apple-darwin.tar.gz
signed (Developer ID Application: Rachit Pradhan, WWP9DLJ27P), hardened-runtime, notarized by Apple.
nb-x86_64-apple-darwin.tar.gz
built against minos 12.0, signed, hardened-runtime, notarized.
nb-aarch64-linux.tar.gz
statically linked single binary, no runtime deps.
nb-x86_64-linux.tar.gz
statically linked single binary, no runtime deps.
v0.1.198 is an infrastructure and security release that also lands real speed wins.
| Question | Answer |
|---|---|
| Should I upgrade from v0.1.193? | Yes. You get the own-registry mirror, CVE scanning with revoke-and-fallback, native ELF relocation, and faster warm installs. |
| Do covered packages still depend on Homebrew's servers? | No. Their bottles are mirrored byte-for-byte to ghcr.io/justrach/nb-bottles (Tier 1) or repackaged under our namespace (Tier 2). The long-tail formula metadata still falls back to the Homebrew API. |
| What happens if a pinned bottle gets a CVE? | revoke records the last known-good version, the resolver installs that fallback with a warning, and it propagates through the registry without a binary release. nb doctor flags machines already on the bad version. |
| Did anything get faster? | Yes. The Linux relocate phase is about 800x faster, warm resolve about 80x, and cached reinstalls about 130x. The lead over Homebrew (100x+) is unchanged or wider. |
| Are macOS tarballs notarized? | Yes, both arm64 and x86_64: Developer-ID-signed, hardened-runtime, notarized by Apple. |