Если вы когда-нибудь сидели перед терминалом и смотрели, как Homebrew неторопливо тянет зависимости, прогоняет формулы через Ruby-интерпретатор, а потом ещё минуту что-то «линкует» — вы знаете эту боль. Один разработчик по имени Rach решил, что с него хватит, и написал на Zig альтернативный клиент к экосистеме Homebrew. Результат — nanobrew, штука размером 1.2 МБ, которая делает brew install морально устаревшей командой.
Что вообще произошло
Nanobrew — это не форк Homebrew и не отдельная экосистема пакетов. Это быстрый клиент для той же самой инфраструктуры: тех же формул, тех же «бутылок» (bottles — предкомпилированные бинарники), тех же касков (casks). Просто вместо Ruby-рантайма весом под 57 МБ вы получаете один статический бинарник на Zig, который стартует мгновенно и делает всё параллельно.
Цифры из бенчмарков (Apple Silicon, macOS 15, автоматически обновляемые через GitHub Actions):
⏱️ tree (0 зависимостей, холодный старт): Homebrew — 5.5 сек, nanobrew — 0.68 сек. Разница в 8 раз.
⏱️ wget (6 зависимостей, тёплый кеш): Homebrew — 5.8 сек, nanobrew — 0.033 сек. Разница в 175 раз.
⏱️ ffmpeg (11 зависимостей, тёплый кеш): Homebrew — 19.6 сек, nanobrew — 0.56 сек. А на «горячем» пути, когда всё уже в сторе — 3.5 миллисекунды. Это быстрее, чем echo выводит текст в терминал.
Ключевое слово тут — «тёплый кеш». Nanobrew спроектирован так, что повторная установка уже загруженного пакета — это фактически бесплатная операция. И вот тут начинается самое интересное.
Как это устроено под капотом
Давайте разберём, за счёт чего достигается такая скорость. Тут нет магии — есть грамотная инженерия.
APFS clonefile — козырь, который мало кто использует
Начиная с macOS High Sierra (2017), файловая система APFS поддерживает системный вызов clonefile(). Суть простая: вместо того чтобы физически копировать данные с одного места диска на другое, система создаёт ссылку на те же блоки. Реальное копирование происходит только когда один из файлов изменяется (copy-on-write). На практике это означает, что «скопировать» гигабайтный пакет из кеша в рабочую директорию занимает микросекунды и не стоит ни одного дополнительного байта на диске.
Homebrew этим не пользуется — он честно копирует файлы при установке. Nanobrew делает clonefile() из контентно-адресуемого хранилища (content-addressable store) в Cellar. Вот откуда берутся эти 3.5 мс.
Контентно-адресуемое хранилище
Все скачанные и распакованные пакеты хранятся в директории /opt/nanobrew/store/, где ключом является SHA256-хеш содержимого. Если вы удалили пакет и ставите его заново — загрузка и распаковка полностью пропускаются, нужно только «клонировать» файлы из стора. Тот же принцип, что в Git или Docker — дедупликация через хеши.
Параллельность везде
Homebrew скачивает зависимости последовательно. Nanobrew:
🔀 Резолвит зависимости через параллельные API-вызовы (BFS-обход графа зависимостей).
🔀 Скачивает все бутылки одновременно через нативный HTTP-клиент Zig (никаких subprocess-вызовов curl).
🔀 Верифицирует SHA256-хеш потоково, прямо во время загрузки, без второго прохода по файлу.
🔀 Распаковывает и релоцирует Mach-O заголовки параллельно.
Нативный парсинг бинарников
Homebrew использует otool (внешнюю утилиту) для чтения Mach-O заголовков исполняемых файлов. Это значит — spawn нового процесса на каждый бинарник. Nanobrew читает load commands из заголовков напрямую, на уровне байтов. Плюс батчевый codesign вместо вызова по одному файлу.
Почему именно Zig?
Zig — это язык, который часто описывают как «C, но без исторического багажа». Нет сборщика мусора, нет скрытых аллокаций, ручное управление памятью, но с более безопасным и современным API. Для системных утилит, где важна скорость старта и минимальный размер бинарника, Zig — почти идеальный выбор. Бинарник nanobrew весит 1.2 МБ — это в 6.8 раз меньше, чем аналогичный zerobrew (ещё один быстрый менеджер пакетов, написанный на Go), и в 47 раз меньше, чем сам Homebrew с его Ruby-рантаймом.
Не только macOS
Отдельная и неожиданная фича — nanobrew умеет работать с .deb-пакетами на Linux. В Docker-контейнере с Ubuntu он устанавливает curl с 32 зависимостями за 12 секунд вместо 34 у apt-get (ускорение в 2.8 раза). Для сборки Docker-образов, где каждая секунда CI-пайплайна — это деньги, это существенно.
При этом nanobrew парсит .deb-архивы нативно: разбирает ar-формат, распаковывает zstd/gzip без внешних утилит. Единственная внешняя зависимость — tar.
Поддержка сторонних тапов — и это важно
Одна из ключевых фич, которая выделяет nanobrew среди конкурентов, — поддержка third-party taps. Команда вроде nb install steipete/tap/sag скачивает Ruby-формулу напрямую с GitHub, парсит её и устанавливает пакет — без предварительного brew tap. Это заявлено как уникальная возможность среди быстрых альтернатив Homebrew.
Стоит ли пробовать прямо сейчас?
Тут нужно честно обозначить контекст. Проект имеет статус Experimental. На GitHub — 14 звёзд, 1 контрибьютор (не считая бота). Это буквально стадия «один человек написал крутую штуку».
Что это означает на практике:
⚠️ Для повседневного use-case (поставить jq, wget, ffmpeg, ripgrep) — скорее всего будет работать отлично.
⚠️ Для экзотических формул с кастомными патчами и сборкой из исходников — могут быть нюансы.
⚠️ Стабильность API и команд может меняться между версиями.
⚠️ Долгосрочная поддержка пока под вопросом — это проект одного энтузиаста.
Но установка — одна строчка в терминале, и она не трогает ваш существующий Homebrew. Два менеджера живут параллельно и не конфликтуют. Так что попробовать — нулевой риск.
Мой взгляд: почему это важнее, чем кажется
На первый взгляд — ну подумаешь, пакеты ставятся быстрее. Но если копнуть глубже, nanobrew — это симптом более широкого тренда.
Во-первых, это очередное подтверждение того, что Zig начинает занимать свою нишу в системном программировании. Bun (JavaScript-рантайм), Tigerbeetle (база данных), а теперь пакетный менеджер — всё это проекты, где Zig выбирают за предсказуемую производительность и крошечные бинарники.
Во-вторых, nanobrew показывает, насколько Homebrew тормозит не из-за сети, а из-за архитектуры. Ruby-рантайм, последовательная обработка, игнорирование возможностей файловой системы — всё это отнимает секунды, которые складываются в минуты и часы по ходу рабочего дня. Когда один статический бинарник оказывается в тысячи раз быстрее — это сигнал, что пора пересматривать подход.
И в-третьих, сама идея контентно-адресуемого хранилища с clonefile — это то, что Homebrew мог бы реализовать у себя уже много лет назад. APFS доступна с 2017 года. Прошло 9 лет. Иногда нужен маленький проект со стороны, чтобы большие проекты задумались об оптимизации.
Nanobrew вряд ли «убьёт» Homebrew — у brew огромная экосистема, комьюнити и отработанные годами пайплайны. Но он задаёт планку производительности, которую будет сложно игнорировать. А для тех, кто работает в терминале каждый день — это уже готовый инструмент, который экономит реальное время.
Источники
🔗 Официальный сайт nanobrew: https://nanobrew.trilok.ai/
🔗 GitHub-репозиторий: https://github.com/justrach/nanobrew
🔗 Оригинальная публикация: https://telegra.ph/nanobrew-tihaya-revolyuciya-v-mire-macOS-paketov-ili-pochemu-Homebrew-pora-na-pensiyu-03-24