nanobrew v0.1.198

Our own bottle registry. Scanned for CVEs.
Still 100x+ faster than Homebrew.

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
231 Homebrew bottles mirrored byte-for-byte to our own GHCR registry, across all four platforms
~800x faster ELF relocate phase on Linux (4,777ms to 6ms) with native in-place rewriting
37 new verified packages with pinned bottle digests for every platform

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.

This release vs recent nanobrew

Before and after, measured within nanobrew. macOS Apple Silicon and Linux aarch64, representative runs. Lower is better; the gold bar is v0.1.198.

ELF relocate phase Linux, fresh machine
~800x faster
before (patchelf)
4,777ms
v0.1.198 native
6ms
cached-bottle reinstall macOS
~130x faster
before
534ms
v0.1.198
4ms
warm install resolve non-registry token
~80x faster
before
147ms
v0.1.198
1.8ms
Linux cold install hexyl, fresh machine
~5x faster
before
5,876ms
v0.1.198
1,110ms

vs Homebrew and zerobrew: yt-dlp on a clean macOS runner

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.

target reinstall lower is better
119.4x faster than Homebrew
Homebrew 5.1.7
5827.7ms
zerobrew 0.2.1
1830.7ms
nb v0.1.198
48.8ms
already installed no-op lower is better
158x faster than Homebrew
zerobrew 0.2.1
1083.2ms
Homebrew 5.1.7
916.9ms
nb v0.1.198
5.8ms

New: our own bottle registry

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.

Tier 1: mirror
Byte-identical copies of all 231 Homebrew bottles we already pin, four platforms each. Digests are unchanged, so existing registry records work against the mirror with zero edits. This is insurance against upstream garbage-collection, renames, and outages. One env var, NANOBREW_BOTTLE_DOMAIN=https://ghcr.io/v2/justrach/nb-bottles, moves the whole fleet over.
Tier 2: repackage
Upstream 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.
Why it matters
A metadata mirror is not independence. The bottle, the bytes you actually install and run, is the real dependency. For covered packages, those bytes now come from infrastructure we control, digest-verified identical to what Homebrew pins. Homebrew's bottle host can go down and your covered installs keep working.

Supply-chain security

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.

CVE scanning
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 and fallback
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.
Provenance and immutability
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.

What got faster

The performance work behind the bars above.

Native ELF relocation
Linux relocation is now native and in-place instead of shelling out to 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.
Warm resolve: 147ms to 1.8ms
Resolving any package outside the verified-upstream registry used to re-download the roughly 650KB registry from GitHub on every resolve. A fresh registry cache is now authoritative for misses too, and a fetched registry is cached even when the requested token is not in it, so non-registry resolves stop re-paying the remote fetch on every call.
Cached-bottle reinstall: 534ms to 4ms
The batch-shared GHCR bearer token was being fetched whenever any package had a ghcr.io bottle URL, even when every blob was already in the local cache. It is now fetched only when at least one bottle actually needs downloading.
TLS out of the box, and more
A native post-install step wires 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.

Coverage this release

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.

Servers and infra

nginx, qemu, colima, postgresql@14, postgresql@16, postgresql@18, mysql, tailscale

Languages and build

node@24, rustup, gradle, poetry, composer, automake, expat, lcov

CLI and shells

bash, zsh, eza, btop, hexyl, httpie, direnv, aria2, rsync, telnet, ghostscript

Security and devops

sops, gitleaks, mkcert, kubeconform, flyctl, fastlane, xclogparser, xcresultparser, whisper-cpp, summarize

Release artifacts

arm64

macOS arm64

nb-arm64-apple-darwin.tar.gz
signed (Developer ID Application: Rachit Pradhan, WWP9DLJ27P), hardened-runtime, notarized by Apple.

x86_64

macOS x86_64

nb-x86_64-apple-darwin.tar.gz
built against minos 12.0, signed, hardened-runtime, notarized.

arm64

Linux aarch64-musl

nb-aarch64-linux.tar.gz
statically linked single binary, no runtime deps.

x86_64

Linux x86_64-musl

nb-x86_64-linux.tar.gz
statically linked single binary, no runtime deps.

How to read this release

v0.1.198 is an infrastructure and security release that also lands real speed wins.

QuestionAnswer
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.