Bun завершил 11-дневную миграцию кода, основанную на ИИ, с Zig на Rust

iconMetaEra
Поделиться
AI summary iconСводка
Bun объявил о запуске проекта в мае 2026 года, завершив 11-дневную миграцию кода, управляемую ИИ, с Zig на Rust. В работу было вовлечено более 1 миллиона строк кода, 6 778 коммитов и 64 параллельных экземпляра Claude, что стоило $165 000. Использование памяти снизилось с 6,7 ГБ до 609 МБ после 2 000 сборок, при этом производительность выросла на 2–5%. В коде теперь содержится 13 000 ключевых слов unsafe и 19 регрессий. Проект теперь принадлежит Anthropic. Это обновление новостей об ИИ и криптовалюте подчеркивает значительные изменения в инфраструктуре проекта.
Проект Bun завершил крупномасштабный миграционный переход с Zig на Rust в мае 2026 года, в течение 11 дней внесено более 1 миллиона строк кода и 6778 коммитов. Для миграции использовались 64 экземпляра Claude, что потребовало затрат на API в размере 165 000 долларов США. После миграции были полностью устранены утечки памяти: после 2000 сборок объем памяти снизился с 6,7 ГБ до стабильных 609 МБ, производительность повысилась на 2–5%, а размер бинарных файлов сократился примерно на 20%. Однако в коде осталось около 13 000 ключевых слов unsafe — в 178 раз больше, чем у аналогичных проектов; выявлено 19 известных регрессионных проблем, и 1 миллион измененных строк кода не может быть проверен человеком построчно. В настоящее время проект Bun приобретен компанией Anthropic.

Автор статьи, источник: InfoQ

В мае 2026 года проект Bun завершил масштабную миграцию кода, которая является почти редкостью в истории разработки программного обеспечения.

Этот миграционный процесс начался 3 мая и был официально объединён с основной веткой 14 мая, заняв всего 11 дней. Написание кода заняло 6 дней, и весь процесс был открыт для публики. Однако Джаррету Сомеру потребовалось почти месяц, чтобы написать блог-пост с обзором — значительно дольше, чем на написание кода.

Эта среда выполнения JavaScript изначально содержала 535 496 строк кода на Zig без учёта комментариев; приблизительно 20% кода были написаны на C++ и включали несколько библиотек C/C++. В ходе переписывания с использованием AI на Rust было внесено более 1 миллиона изменений строк кода, выполнено 6778 коммитов и запущено около 50 динамических рабочих процессов в Claude Code.

Согласно данным, раскрытым Сомером, это переписывание потребовало 5,9 миллиарда некэшированных входных токенов, 690 миллионов выходных токенов и 72 миллиарда чтений кэшированных входных токенов, что по ценам API составило примерно 165 000 долларов США.

Самнер сказал, что это предел того, чего можно достичь с помощью текущих технологий. Он оценил, что если бы три инженера, полностью знакомые с кодовой базой Bun, выполнили этот миграционный процесс вручную, это заняло бы около года, и за это время команда практически не смогла бы продолжать разработку новых функций, исправление ошибок и устранение уязвимостей.

После этого обновления Bun v1.3.14 станет последней версией на Zig, а Bun v1.4.0 — первой версией на Rust.

1. Результат: от утечки памяти 6,7 ГБ до стабильных 609 МБ

Bun изначально был проектом на Zig и охватывал широкий спектр задач: он является транспайлером для JavaScript и TypeScript, сборщиком, менеджером пакетов, запускателем тестов, разрешителем модулей, а также клиентом для HTTP и WebSocket и реализует API-уровень Node.js. Именно такая широта функционала обеспечила Bun более 22 миллионов скачиваний CLI в месяц и поддержку таких проектов и компаний, как Vercel, Railway, DigitalOcean, Claude Code и OpenCode.

Но та же самая ширина создала некоторые вызовы для Bun.

В частности, в Bun v1.3.14 существует проблема, которая долго беспокоила пользователей: при последовательных вызовах Bun.build() память накапливается и никогда не освобождается. Каждая сборка приводит к утечке примерно 3 МБ — это кажется незначительным, но если вы запускаете сервер разработки, где каждый запрос инициирует сборку, память постепенно поглощается, пока процесс не аварийно завершится.

В реальных тестах потребление памяти составило 1,9 ГБ после 500 сборок, 3,5 ГБ после 1000, 5,1 ГБ после 1500 и резко выросло до 6,7 ГБ после 2000.

Это лишь вершина айсберга множества проблем с памятью. В списке исправлений ошибок в версии v1.3.14 Sumner перечислил длинный список проблем:

При вызове .reset() в модуле zlib, если асинхронный .write() все еще выполняется в пуле потоков, процесс аварийно завершается из-за «использования после освобождения кучи»; в модуле http2 вложенные JavaScript-колбэки вызывают повторное хеширование хеш-таблицы, что приводит к недействительности внутренних указателей потоков; при вызове UDPSocket.sendMany() в процессе итерации, если пользовательский код изменяет состояние подключения сокета через колбэки valueOf или toString, происходит запись за пределами буфера; при неудачном выделении буфера вывода в crypto.scrypt колбэк и защищенный буфер пароля никогда не освобождаются;......

Общая черта этих ошибок очевидна — они почти все указывают на одну и ту же причину: сочетание GC и ручного управления памятью в одном программном обеспечении.

Современные движки, такие как JavaScriptCore и V8, имеют крайне строгие правила обработки исключений и сборки мусора, в то время как Zig, как и C, не управляет памятью автоматически. Когда эти две парадигмы работают в одном процессе, каждое выделение памяти должно быть проверено построчно: где освобождаются эти байты? Как обеспечить, чтобы они были освобождены только один раз? Правильно ли проверяются JavaScript-исключения? Виден ли этот указатель, управляемый сборщиком мусора, для консервативного сканера стека? Это память, управляемая сборщиком мусора, или память, управляемая вручную?

Еще более тревожно то, что команда не была бездействующей. Они внесли изменения в компилятор Zig, добавили поддержку Address Sanitizer (ASAN), запускали тесты ASAN в CI при каждом коммите, собирали ReleaseSafe на Windows, проводили 24/7-фаззинг с помощью Fuzzilli и выполнили множество энд-ту-энд тестов на утечки памяти. Тем не менее, отчеты о сбоях продолжают поступать без остановки.

«Наш список исправлений багов вызывает плохое впечатление, я устал спать с мыслью о возможном сбое Bun», — написал Сомер. Он не винит Zig — другие пользователи Zig не сталкиваются с подобными проблемами, поскольку сочетание GC с ручным управлением памятью — крайне редкий случай, для которого почти ни один язык не был разработан.

А версия на Rust показала следующий результат: при выполнении 2000 вызовов Bun.build() память стабильно удерживается на уровне 609 МБ.

Помимо фундаментального устранения проблемы утечки памяти, переписывание на Rust принесло улучшения в нескольких других аспектах.

В плане стабильности версия v1.4.0 устранила 128 воспроизводимых ошибок из v1.3.14, включая утечки памяти, сбои и ошибки отображения цвета в справочных текстах.

За счет объединения переписывания на Rust, изменений ICU и той же свертки кода размер бинарных файлов Bun сократился примерно на 20% в Linux и Windows.

В плане производительности наблюдается общее улучшение на 2–5%. Bun.serve вырос с 169 600 req/s до 177 700 req/s, node:http — с 103 800 до 108 500. В реальных сценариях использования next build сократился с 13,62 секунды до 13,03 секунды, а пакетная компиляция tsc — с 0,94 секунды до 0,89 секунды.

После выпуска Claude Code на основе Rust Bun время запуска на Linux сократилось с 517 мс до 464 мс, что на 10% быстрее.

2 метода: 64 Claude, 11 дней, 50 рабочих процессов

Как Сомеру это удалось — это, пожалуй, самая важная часть, ведь он использовал метод, отличный от традиционного «заставить ИИ писать код».

Самнер разбил весь процесс на примерно 50 динамических рабочих потоков, каждый из которых представляет собой цикл. Он описал эту модель в блоге с использованием псевдокода:

Каждая задача имеет контекст (например, Jira-тикет или GitHub-issue), Claude пишет код на основе этого контекста, затем два рецензента (также Claude) проверяют код, и наконец применяется обратная связь. После завершения берется следующая задача.

Этот подход пронизывает весь процесс переписывания. Каждый рабочий процесс отвечает за конкретную цель:

  • Создайте руководство по миграции, сопоставляющее шаблоны и типы Zig с шаблонами и типами Rust;
  • Механически перенесите каждый файл .zig в файл .rs, соответствующий PORTING.md и LIFETIMES.tsv;
  • Исправьте ошибки компиляции для каждого crate;
  • Запустите такие подкоманды, как bun test или bun build;
  • Пройдите все тесты в тестовом наборе Bun; проведите несколько циклов крупномасштабной рефакторинга и очистки.

В пиковый момент Сумнер одновременно запускал 4 рабочих потока, каждый из которых содержал 16 Claude, в общей сложности 64 Claude работали параллельно в 4 рабочих деревах, отправляя и пуша файлы. В пике Claude писал около 1300 строк кода в минуту.

Это разделение между «реализатором» и «рецензентом» является ключевым. Claude, пишущий код, стремится к тому, чтобы код был принят, как и человеческие инженеры, и поэтому подвержен предвзятости. Поэтому рецензенты и реализаторы полностью разделены — рецензенты видят только различия в коде, но не видят рассуждений реализатора, и им прямо сообщают: «Предположите, что код неверен». На каждого реализатора приходится более двух противодействующих рецензентов, чья единственная задача — находить ошибки.

Написание кода — это только первый шаг. Код на Zig представляет собой единый компилируемый модуль, тогда как код на Rust пришлось разбить на около 100 crate, чтобы ускорить компиляцию; циклические зависимости привели к тому, что cargo check выдал около 16 000 ошибок за один раз. Для одного человека это катастрофа, но для 64 параллельно работающих Claude это просто управляемая очередь задач. Рабочий процесс группирует ошибки по crate, запускает cargo check для каждого crate, один Claude исправляет ошибки, два проверяют, один применяет изменения.

Далее запускается bun --version, а затем bun test. Тестовый рабочий процесс каждый раз случайным образом запускает 100 тестовых файлов, распределяя их на 4 рабочих дерева. Тестовый набор также включает несколько типов: некоторые тесты выполняются более минуты, некоторые исчерпывают системное количество TCP-соединений, некоторые fork-ают около 10 000 процессов. Sumner использует systemd-run для создания cgroup для ограничения ресурсов, но машина несколько раз аварийно завершала работу из-за нехватки места на диске.

Через два дня количество неудачных тестов на платформе Linux снизилось с 972 до 23. Через полтора дня тесты на Linux прошли успешно во всех случаях. Через пять дней все шесть платформ — Linux x64, Linux arm64, macOS x64, macOS arm64, Windows x64, Windows arm64 — прошли тестирование.

14 мая PR #30412 был официально объединен, все тесты в тест-сайте прошли успешно, ни один тест не был пропущен или удален.

3 Тревожный момент: 13 000 небезопасных и не поддающихся построчному анализу строк кода

Однако Сомер также признал, что эта работа еще не завершена.

На данный момент около 4% кода Bun на Rust находятся внутри unsafe-блоков, около 13 000 ключевых слов unsafe распределены примерно по 27 000 строкам кода, а общий объем кода на Rust составляет около 780 000 строк. 78% unsafe-блоков содержат только одну строку, обычно это указатель из C++ или вызов библиотеки C.

Он ожидает, что последующая реорганизация снизит этот показатель. Однако кто-то провел расчет: около 350 000 строк кода uv содержат всего 73 вызова unsafe, тогда как количество unsafe в Bun в 178 раз больше, чем в uv. Этот разрыв трудно объяснить просто необходимостью вызывать C-библиотеки.

И затем неопределенное поведение также было обнаружено в безопасном коде на Rust. Это сложнее отлаживать, чем в C++, потому что вы считаете, что безопасный код не может содержать ошибок.

Затем команда Bun изменила PathString::init в этом вопросе на unsafe fn.

Сам Сомер признал, что это переосмысление ввело 19 известных регрессионных проблем, и отметил, что большинство регрессионных проблем возникли из-за кода с одинаковой грамматикой, но разным смыслом.

Например, эти два фрагмента кода выглядят похоже, но ведут себя совершенно по-разному. В Zig assert — это функция, поэтому её параметры выполняются при каждой сборке. В Rust debug_assert! — это макрос, поэтому в релизной версии всё выражение (включая вызов функции) удаляется insert_stale.

Хотя все проблемы уже устранены, это не означает, что в миллионах строк кода ИИ нет других ошибок.

Кто вообще в здравом уме перенесет свое производственное приложение сразу после полной перезаписи среды выполнения? Считать, что версия 1.4 не добавила новых багов или не изменила поведение, — слишком наивно.

Еще одним неотъемлемым аспектом является проверка кода. Просмотреть 1 миллион строк изменений вручную практически невозможно — даже если тратить по минуте на каждую строку, потребуется непрерывно работать 11,7 дней; при реальной скорости проверки кода (200 строк в час) на это уйдет более двух лет.

Основными рецензентами этого PR были claude[bot] и coderabbitai[bot]. Сам Сомер признал, что его подход к рецензированию заключается в «проверке того, правильно ли агент противодействующего рецензирования зафиксировал различия, обеспечении соблюдения руководства по преобразованию, а также ручном чтении значительного объема кода». Однако он не уточнил, что именно подразумевается под «значительным объемом».

Еще один неизбежный вопрос: Bun был приобретен Anthropic в декабре 2025 года, и единственным инструментом, способным эффективно поддерживать эту кодовую базу, является сам Claude. Некоторые в сообществе считают, что это уже не можно назвать открытым проектом в традиционном смысле — чтобы отправить PR в Bun, вам нужно сначала подписаться на Anthropic или полагаться на несколько ключевых участников, которые уже разобрались в коде, сгенерированном ИИ.

Стоит ли 165 000 долларов США за год работы?

Саммер также раскрыл в блоге, что стоимость переписывания API составила около 165 000 долларов США, что эквивалентно объему работы трех инженеров за год. Это число вызвало оживленные дискуссии на Hacker News.

Некоторые считают, что эта затрата на самом деле очень выгодна. За 165 000 долларов США в Силиконовой долине невозможно нанять даже несколько полных штатных инженеров, не говоря уже об инженерах компании уровня Anthropic. Согласно данным о зарплатах на levels.fyi, общий пакет вознаграждения инженера Anthropic, скорее всего, достигает 500 000 долларов США или даже больше. Даже при грубом расчете средней годовой зарплаты в 336 000 долларов США для 50 инженеров, это составляет примерно 1292 доллара США в день. Затраты на оплату труда 50 человек, работающих непрерывно 11 дней, уже приближаются к 710 000 долларов США, не считая льгот, аренду офисных помещений, оборудования и других административных расходов.

Однако Сомер использовал предварительную версию Claude Fable 5 — продвинутую модель, которая еще не доступна для публики и может подпадать под экспортные ограничения. Таким образом, цена API — это лишь цифра, которую видят конечные пользователи, а за ней скрываются огромные инвестиции Anthropic в исследования и разработки. Некоторые отмечают, что сведение затрат к цене API намеренно преуменьшает реальные вложения. Если учесть затраты на разработку модели, обучение, вычислительные ресурсы и инженерные трудозатраты, общая стоимость, безусловно, будет очень высокой — вполне возможно, превысит 1,5 миллиона долларов.

И на первый взгляд, обмен 165 000 долларов на год работы выглядит выгодно.

Но настоящая стоимость не отражена в этом счете. В этом репозитории 6778 коммитов, и никто не прочитал его целиком с начала до конца. Хотя сейчас всё работает нормально, а что будет через шесть месяцев? Когда в три часа ночи вдруг возникнет странный проблема с конкурентным доступом, инженер на дежурстве столкнется с системой, логику которой даже он сам не может четко объяснить. В будущем ее придется поддерживать с помощью ИИ — как подсчитать стоимость поддержки? На самом деле, это довольно сложно.

Отказ от ответственности: Информация на этой странице может быть получена от третьих лиц и не обязательно отражает взгляды или мнения KuCoin. Данный контент предоставляется исключительно в общих информационных целях, без каких-либо заверений или гарантий, а также не может быть истолкован как финансовый или инвестиционный совет. KuCoin не несет ответственности за ошибки или упущения, а также за любые результаты, полученные в результате использования этой информации. Инвестиции в цифровые активы могут быть рискованными. Пожалуйста, тщательно оценивайте риски, связанные с продуктом, и свою устойчивость к риску, исходя из собственных финансовых обстоятельств. Для получения более подробной информации, пожалуйста, ознакомьтесь с нашими Условиями использования и Уведомлением о риске.