世界を動かす技術を、日本語で。

Nanobrew: brewと互換性のある最速のmacOSパッケージマネージャー

概要

nanobrew は、 Zig製 の超高速macOS用パッケージマネージャー。 Homebrew よりも最大 7,000倍速い インストール速度を実現。 APFSの clonefile や並列処理など、速度に特化した設計。 シングルバイナリで 依存性やディスクコスト を大幅削減。 簡単なインストールと使い方で、即戦力となるツール。

nanobrew: 超高速macOSパッケージマネージャー

  • Zig言語 で実装された、macOS専用パッケージマネージャー
  • インストール方法
    • $ curl -fsSL https://nanobrew.trilok.ai/install | bash
    • ターミナル再起動または表示されるexportコマンド実行
  • Apple Silicon やmacOS 15に最適化された高速動作
  • インストール速度比較
    • tree (依存なし、キャッシュなし)
      • Homebrew: 8.99秒
      • nanobrew: 1.19秒(約7.6倍速)
    • wget (依存6つ、キャッシュなし)
      • Homebrew: 16.84秒
      • nanobrew: 11.26秒(約1.5倍速)
    • ffmpeg (依存11、キャッシュあり)
      • Homebrew: 約24.5秒
      • nanobrew: 3.5ミリ秒(約7,000倍速)

nanobrewの基本コマンド

  • パッケージインストール
    • $ nb install jq
      • 依存解決38ms
      • インストール完了まで約1,100ms
  • インストール済みパッケージ一覧
    • $ nb list
      • 例: jq 1.7.1
  • 自己アップデート
    • $ nb update
      • nanobrew自体の更新

nanobrewの仕組み

  • 依存解決
    • BFSによる並列APIコール、超高速
  • ダウンロード
    • ネイティブHTTP、SHA256ストリーミング検証
  • 展開
    • SHA256でキー管理された内容アドレスストア
  • マテリアライズ
    • APFS clonefileによるゼロディスクコストのコピーオンライト
  • シンボリックリンク
    • PATHへのリンク、ローカルDBへの記録

nanobrewが高速な理由

  • APFS clonefile
    • macOSシステムコール利用、インストールごとにディスクコストゼロ
  • 全処理並列化
    • ダウンロード、展開、依存解決などすべて同時実行
  • ネイティブHTTP実装
    • Zig標準のhttp.Client利用、curlサブプロセス不要
  • Mach-Oバイナリ解析
    • otool非依存、ヘッダ直接読み取り、バッチcodesign
  • 内容アドレスストア
    • SHA256キーによる重複排除、再インストール時はダウンロード・展開スキップ
  • シングルスタティックバイナリ
    • Ruby不要、インタプリタ起動なし、設定ファイルも最小限
    • 約2MBの単一バイナリのみ

nanobrewのメリット

  • 圧倒的なインストール速度 による開発効率向上
  • ディスクスペースの節約 とシンプルな構成
  • Homebrewの遅さや複雑さ に悩むユーザーへの最適解
  • 簡単な導入と運用 で即戦力パッケージ管理

nanobrew は、 macOSユーザー にとって、これまでにない高速・軽量なパッケージマネージャーとして注目。 Homebrew の代替や補完として、特に Apple Silicon 環境での導入を推奨。

Hackerたちの意見

これは、ホームブリューがダウンロード/インストールプロセスに採用するにはいいかもしれないけど、もしRubyインタープリターが含まれてないなら、ボトルの検索とインストール以外には互換性があるとは思えないな。俺はほとんどのパッケージをBrewfileからインストールしてるけど、それ自体がRubyコードだからね。

「ほとんどのパッケージはBrewfileからインストールしてるけど、それ自体がRubyコードだよ。」同じく。何があっても、新しいバージョンはBrewfileをサポートするはず。

Rubyを実行しないなら、ホームブリューとは互換性がないよ。「互換性」って言葉がちょっと働いてるけど、これは「ホームブリューのCDNやCI、パッケージングインフラ、そしてそれを維持しているメンテナが暗黙のうちに依存している」って意味も含んでるからね。数週間ごとに部分的な互換性と速度向上を持つ新しいホームブリューのフロントエンドが登場してるけど、ホームブリューは実際に完全な互換性を持つ公式のRustフロントエンドに取り組んでるんだ。これが広いエコシステム全体の努力を共有する助けになるといいな。

ホームブリューがRubyを直接実行せずに、役立つ方法で人々がホームブリューを構築できる十分なJSON APIを提供しているのは本当にすごいね。すべてがRuby DSLで構築されているのに、まさに「両方の良いとこ取り」って感じだし、代替クライアントがそれを活用できるのもいいね。公式のRustフロントエンドが進行中だなんて知らなかった!それはすごく興味深い。

えー、誰がHomebrewの互換性について教えてくれるの?(冗談だよ、Homebrewを作ってくれてありがとう!)

公式のRustフロントエンドを推進してくれてありがとう。個人的には、Macのソフトウェア管理にnixを使うように(ゆっくりと)移行してるけど、制限が多くて結局Homebrewに頼っちゃうんだよね。スピードアップはありがたい。

どうか、Gatekeeperにブロックされているボトルやカスクを削除しないでください。 :˜(

意味がわからない。言葉の使い方からすると、Homebrewのバックエンドを使えるってことだよね。完全にHomebrewの代わりってわけじゃない。誰も混乱してないと思うよ。

https://github.com/Homebrew/brew/tree/main/Library/Homebrew/... 参考までに

知らない人のための背景情報: コメント主のmikemcquaidはHomebrewのプロジェクトリーダーです。

Homebrewは公式のRustフロントエンドに取り組んでいて、完全な互換性がある予定です。「Rustフロントエンド」と言うと、Homebrewのフロントエンドが最終的には純粋なRustプロジェクトに移行するというビジョンですか?ポータブルRubyのエンドユーザーインストールなしで?もしそうなら(そうでないなら以下は無視して):ほとんどの「つまらない」フォーミュラに対してそれがどう機能するかは分かります。フォーミュラのJSONは公開時に事前に焼き付けられ、Rustフロントエンドがそれを引っ張ってきて、ボトル経由でインストール可能なフォーミュラを発見し、ボトルを引っ張り、Rubyを実行する必要がない。だけど、ボトルがないフォーミュラやRubyのpost_installブロックなどのエッジケースではどうなるの?(それに、ローカルフォーミュラの開発はどうやって行うの?)この取り組みの最終的な目的は、Rustフロントエンドに小さな「Formula Ruby DSL」インタープリタを組み込むことで、実際のフォーミュラのメソッドやブロックに現れるコードを実行するために必要なRubyの構文とセマンティクスをサポートすることですか?(個人的にはそれはかなり実現可能だと思うけど、あなたは違うかもしれないね。)

McQuaidは厳密には正しいけど、面白いのは実際にインストールされたフォーミュラのうち、アーカイブの抽出やパスの操作を超えてRuby DSLの機能を使っているのがどれくらいの割合かってことだと思う。俺の予想では、それはほとんどの開発者が使っているものの中では少数派だろうね。本当の互換性テストは「すべてのHomebrewフォーミュラが動く」じゃなくて、「各開発者が実際に使っている15〜20のフォーミュラが動く」ってことだと思う。これを正しく扱って、エッジケースではっきりと失敗するツールの方が、技術的には完全だけど遅い実装よりも実際には役立つ。スレッドに欠けているのは、その表面積に関するデータであって、ベンチマークの数字じゃない。

「互換性がある」というのは、HomebrewのCDN、CI、パッケージングインフラ、これを維持しているメンテナが暗黙のうちに依存していることを意味するので、ちょっと働きかけがあるね。これが「互換性がある」ということの文字通りの意味だよ。他にどうやってそれをフレーム化すると思ったの?

これは問題を探している解決策に感じるな。俺のシステムには数百のbrewパッケージがあって、アップデート中に「これが2秒早かったらな…」なんて考えたことはないよ。ホームブリューの人たちがbrewをさらに最適化するためのアイデアを得るためにこれを利用できるかもしれないけど、俺はすぐには採用しないと思う。今回は互換性の方が速度より重要だね。

Nix-Darwinのためのホームブリューモジュールを使っているなら、生成されたbrewfileに対してbrewを実行するのが、darwin-rebuild switchの中で一番遅い部分になるよ。速い場合でも、1秒で済むことが10秒かかるようになっちゃうから、何も更新しないのにそのコマンドを実行するのがプロセスの一部だと、かなりイライラするよね。変わらないBrewfileに対するホームブリューのノーオプは本当に遅い。

それぞれに合った方法があるけど、俺はbrewを使うのをやめたよ、遅すぎるからね。これがあれば戻るかも!編集:いや、戻らないな…

アップデート中に「これが2秒早かったらな…」なんて考えたことはないよ。俺は確かにそんなことを考えたことがある(特に小さなツールをインストールしようとして、最初に20分の自動アップデートにぶつかるとき)。でも、この特定の解決策は採用しないと思うな。

brewのアップデート/アップグレードが永遠にかかるんだけど。

DenoやPnpm、bunにも同じ批判があったけど、リリースから何年経っても、nodeとnpmはこの3つより遅いままだね。

同意する。俺が直面するボトルネックは、更新が必要なパッケージが多すぎて、ダウンロードする量が多いってこと。ソースからコンパイルしなきゃいけないものがあったら、その時間がかなりかかるしね(でも今使ってるやつは幸いにも全部プリビルドだと思う)。

クロスプラットフォームの開発エコシステムで別のパッケージマネージャーの話をしなきゃならないなら、マジでイライラするわ。

brewがもっと速くなってほしい。俺にとってはいいクオリティ・オブ・ライフになる。

俺は軽めのHomebrewユーザーを何年もやってる。必要なものをダウンロードしたりアップデートしたりするのは、3〜6ヶ月に1回くらいかな。人生で一番速いハードウェアを使ってるのに、ちょっとしたことをするのにこんなに時間がかかるなんて、マジで信じられない。

Brewは確かに昔はもっと遅かったし、すごく面倒だと思ってた。でも、年々改善されてきた感じがする(デフォルトでバイナリを配布するようになったのは、スピード的に大きな勝利だね)。こういうのは、昔の名残と簡単にアクセスできるコーディングツールの影響があるのかな。もしLLMコーディングが数年前に出てたら、こういうプロジェクトももっと理解できたかもしれない。

互換性と速度、どっちを選ぶ? nb info --cask codex-app nb: formula '--cask' が見つかりません nb: formula 'codex-app' が見つかりません

これがzerobrew [0] とどう違うのか説明した方がいいかもね。zerobrewも同じことをやろうとしてるし。[0] https://github.com/lucasgelfond/zerobrew

それに、zerobrewは元のHomebrewと同じくLinuxと互換性があるみたいだけど、Nanobrewはそうじゃないみたい。Linuxの小さなコンテナやVM、CIでbrewを使うときは、これらの新しいネイティブコードの軽量効率がすごく大事なんだよね。macOSの開発機よりも。

Zerobrewは成熟してるみたいだね、チェックしてみるよ。ところで、これに気づいたんだけど:> Zerobrewは実験的です。Homebrewの代わりではなく、併用することをお勧めします。Homebrewを削除してZerobrewに置き換えることは、その影響を完全に理解している場合を除いてお勧めしません。だから、Homebrewと一緒に使うのは問題ないみたいだね。

「公式の指示に従ってbrew経由でzerobrewをインストールしてみて。」 >「すぐにインストールパスが長すぎるってエラーが出て、/opt/zerobrew/prefixがバイト数オーバーだって修正が必要だって。」うん、ちょっと手間がかかりそうだね。

古いマシンのサポートを切らないHomebrew互換のシステムがあったら最高だな。3.8 GHzのクアッドコアi5のiMacを持ってるけど、まだまだ現役なのに、Homebrewはもう古くてダメって判断しちゃったみたい。仕方なくMacPortsに移行したけど、意外と使いやすい。でもやっぱりbrewが恋しい。うん、分かってる。オープンソースだから、好きにやればいいんだろうけど、やっぱり残念だな。1: https://docs.brew.sh/Support-Tiers

確かに、Appleは4年以上前にMojaveのセキュリティ修正をやめたし、それ以来7、8回新しいOSが出てるからね…。オープンソースプロジェクトにすべてをサポートしてもらうのは無理だと思う。

そう、MacPortsがいいよ。新しいMacOSが出たときに、俺のが古すぎて切り替えたんだ。brew updateで使ってたものがいくつかアンインストールされて、その後止まって知らせてきた。冒険したい人には https://github.com/dortania/OpenCore-Legacy-Patcher もあるよ。

OpenCodeレガシーパッチャーを使ってv15/Sequoiaにアップグレードできるよ: https://dortania.github.io/OpenCore-Legacy-Patcher/

それでLinuxを動かしてみて。AppleはそのOSを切り離したし、更新されるOSの方がセキュリティ的には安全だよ。

すでにインストールされているHomebrewパッケージで動くと思ってたけど、全然ダメだった。インストール後に「nb list」や「nb outdated」を実行すると、空のリストが出てくる!ほとんど互換性のある競合するHomebrewインストールなんて、全く必要ないよ。

OT: Homebrewの話だけど、間違った前提を持ってて、それが結局問題を引き起こしたんだ。自分がバカだったんだけど、他にも同じ間違いをしてる人がいると思うから、コメントしてみる。俺のミスは、2017年のiMac(Intelプロセッサ)から2024年の初めにAppleシリコンMacにアップグレードして、Time Machineで移行したときに、Homebrewのために特別なことを何もしてなかったこと。普通にHomebrewのアップデートをしてれば、Appleシリコン用のバイナリを自動で取得すると思ってたんだけど、それが間違いだった。Appleシリコン用のHomebrewはIntel用とは独立してるんだ。Intel用のHomebrewは/usr/localを使って、Appleシリコン用のHomebrewは/opt/homebrewを使う。これで、両方のHomebrewを同時にインストールできるんだ。Intel MacからAppleシリコン Macに移行する正しい方法は、新しいMacにAppleシリコン用のHomebrewをインストールして、必要なパッケージを全部インストールすること。Intel用のHomebrewはAppleシリコン Macでも問題なく動くから、Time Machineで移行したIntel用のHomebrewを使って、Appleシリコン用のHomebrewで使うパッケージリストを作れるよ(もしくは古いMacで作ってもいい)。これに気づいたのは、Homebrewでインストールしたライブラリを使ってソースから何かをビルドしようとして問題にぶつかったから。LLMが手伝ってくれて、ライブラリを/opt/homebrewからビルドプロセスが期待する場所に手動でシンボリックリンクを作る必要があるかもしれないって言われたんだけど、/opt/homebrewがなかった。ライブラリは/usr/localのどこかにあった。そしたら、そのライブラリがAppleシリコン用じゃないことに気づいて、Homebrewでインストールした他のものをチェックしたら、Appleシリコン用のものは何もなかった。間違ったHomebrewを使ってたんだって気づいた。

Brewは本当に使えないクソだ。nixが最高。マジで、brewで何かをインストールするたびに、他のものが壊れるかもしれないって思ってたから嫌いだったけど、macOSの開発にはnixpkgsを使うようになってからはずっと快適になった。

Brewがあまりにも痛いからnixに切り替えた。残念ながら、nixも独自の痛さがある。でも最近、nixのラッパーであるdevboxを見つけた。パッケージマネージャーとしては本当にうまく機能する。「devbox global add 」って実行するだけ。

このスレッドでNixに対する興味が再燃した。もうgitに保存したdotfilesの中にBrewfileがあるけど、トラックパッドの設定やドックの設定、ファイルの関連付けなど、Macの小さな設定を全部整えたいと思ってた。nix-darwinが明らかな解決策だね。ChatGPTにそのタスクを任せたら、始めるにはいい方法だって言ってきたけど、その後、設定を整えるための冪等なスクリプトの中間案を提案してきた。それを調べてみたら、数分後には.bash_profileにsetupmac()関数ができた(そう、俺はbashを使ってる)。それは主にいくつかの'defaults'コマンドと他のいくつかのことから成り立ってて、ソフトウェア管理にはbrewを使って、他の設定にはsetupmac()を使って、もちろんghostty/nvimのためにdotfilesを手動で管理してる。もっと早くこれがあればよかったな、先週の間に3台のMacを設定したばかりだから。新しい言語やツールを学ぶ必要がないのも嬉しい。全体的にはちょっとバラバラで、ちゃんとしたnixの設定ほど自動化されてないし、nixの持つ精度もないけど、シンプルで、頭の中にすんなり入るし、実行も簡単。