StartseiteArtikel

Die aufsehenerregendste KI-Neuinterpretation aller Zeiten: Claude hat Bun in 11 Tagen fertiggestellt, der Gründer brauchte einen Monat, um es endlich offen zu legen

极客邦科技InfoQ2026-07-09 16:30
Es ist ein Monat vergangen – endlich kommt der Rückblick des Gründers von Bun!

Im Mai 2026 führte das Bun-Projekt eine in der Geschichte der Softwareentwicklung beispiellose groß angelegte Code-Migration durch.

Diese Migration startete am 3. Mai und wurde am 14. Mai offiziell in den Hauptzweig zusammengeführt – sie dauerte nur 11 Tage. Die eigentliche Codierungsarbeit beanspruchte lediglich 6 Tage, und der gesamte Prozess verlief öffentlich. Dennoch verbrachte Jarred Sumner fast einen vollen Monat damit, die Ergebnisse in einem Blogbeitrag zusammenzufassen – deutlich länger als die reine Codierungszeit.

Diese JavaScript-Laufzeitumgebung umfasste ursprünglich 535.496 Zeilen Zig-Code ohne Kommentare. Gleichzeitig waren etwa 20 % des Codes in C++ geschrieben, und mehrere C/C++-Bibliotheken waren integriert. Bei dieser KI-gestützten Neufassung in Rust wurden mehr als 1 Million Codezeilenänderungen und 6778 Commits verarbeitet, wobei etwa 50 dynamische Workflows in Claude Code ausgeführt wurden.

Laut den von Sumner veröffentlichten Daten verbrauchte diese Neufassung auf API-Ebene 5,9 Milliarden nicht zwischengespeicherte Eingabe-Token, 690 Millionen Ausgabe-Token und 72 Milliarden gelesene zwischengespeicherte Eingabe-Token. Nach aktuellen API-Preisen beliefen sich die Kosten auf etwa 165.000 US-Dollar.

Sumner betonte, dass dies die derzeit erreichbare Spitzenleistung darstellt. Er schätzt, dass drei Ingenieure, die mit der Bun-Codebasis vollständig vertraut sind, etwa ein Jahr für die manuelle Durchführung dieser Migration benötigt hätten – und in diesem Jahr hätte das Team kaum Fortschritte bei der Entwicklung neuer Funktionen, der Behebung von Fehlern und der Umsetzung von Sicherheitsupdates machen können.

Nach dieser Neufassung ist Bun v1.3.14 die letzte Zig-Version, während Bun v1.4.0 die erste Rust-Version darstellt.

1  Ergebnisse: Von 6,7 GB Speicherleck zu stabilen 609 MB

Ursprünglich war Bun ein Zig-Projekt mit einem sehr breiten Aufgabenspektrum: Es fungiert gleichzeitig als JavaScript- und TypeScript-Transpiler, Paketbündler, Paketmanager, Testläufer, Modulauflöser, HTTP- und WebSocket-Client und implementiert die Node.js-API-Schicht. Genau diese Vielseitigkeit hat dazu geführt, dass Buns CLI monatlich über 22 Millionen Mal heruntergeladen wird und Unterstützung von Projekten und Unternehmen wie Vercel, Railway, DigitalOcean, Claude Code und OpenCode erhält.

Doch genau diese Breite brachte Bun auch einige Herausforderungen mit sich.

Insbesondere in Bun v1.3.14 gab es ein langwieriges Problem: Bei aufeinanderfolgenden Aufrufen von Bun.build() sammelte sich der Speicher kontinuierlich an und wurde nie freigegeben. Bei jedem Build gingen etwa 3 MB verloren – was zunächst wenig erscheint. Doch wenn ein Entwicklungsserver betrieben wird, der bei jeder Anfrage einen Build auslöst, wird der Speicher nach und nach aufgebraucht, bis der Prozess abstürzt.

In praktischen Tests betrug die Speicherauslastung nach 500 Builds 1,9 GB, nach 1000 Builds 3,5 GB, nach 1500 Builds 5,1 GB und nach 2000 Builds sogar 6,7 GB.

Dies war nur die Spitze des Eisbergs bei vielen Speicherproblemen. In der Fehlerbehebungsliste für v1.3.14 listete Sumner eine lange Reihe von Problemen auf:

Wenn im zlib-Modul .reset() aufgerufen wird, während ein asynchroner .write()-Vorgang im Thread-Pool ausgeführt wird, stürzt der Prozess mit dem Fehler „Verwendung nach Heap-Freigabe“ ab. Im http2-Modul führt ein verschachtelter JavaScript-Callback zu einer erneuten Hash-Berechnung der Hash-Tabelle, wodurch interne Stream-Zeiger ungültig werden. Bei UDPSocket.sendMany() tritt während der Iteration ein Schreibvorgang außerhalb der Grenzen auf, wenn der Benutzercode über die Callbacks valueOf oder toString den Verbindungsstatus des Sockets ändert. Bei crypto.scrypt werden der Callback und der geschützte Passwort-Puffer nie freigegeben, wenn die Zuweisung des Ausgabepuffers fehlschlägt …

Diese Fehler weisen alle eine klare Gemeinsamkeit auf: Sie gehen fast alle auf dieselbe Ursache zurück – die Vermischung von Garbage Collection (GC) und manueller Speicherverwaltung in derselben Software.

Moderne Engines wie JavaScriptCore (und V8) haben äußerst strenge Regeln für Ausnahmebehandlung und GC, während Zig wie die Sprache C den Speicher nicht automatisch verwaltet. Wenn diese beiden Paradigmen in demselben Prozess koexistieren, muss jede Speicherzuweisung Zeile für Zeile überprüft werden: Wo werden diese Bytes freigegeben? Wie wird sichergestellt, dass sie nur einmal freigegeben werden? Wurden JavaScript-Ausnahmen ordnungsgemäß überprüft? Ist dieser von der GC verwaltete Zeiger für den konservativen Stack-Scanner sichtbar? Handelt es sich um GC-Speicher oder manuell verwalteten Speicher?

Besonders besorgniserregend ist, dass das Team nicht untätig war. Es hat den Zig-Compiler modifiziert, um die Unterstützung für AddressSanitizer (ASAN) hinzuzufügen. Bei jedem Commit werden ASAN-Tests in der CI ausgeführt, unter Windows wird eine ReleaseSafe-Build verwendet, Fuzzilli wird rund um die Uhr für Fuzz-Tests eingesetzt, und es gibt zahlreiche End-to-End-Tests für Speicherlecks. Trotzdem gingen die Absturzberichte weiter.

„Unsere Fehlerbehebungsliste sieht deprimierend aus. Ich habe es satt, mit der Sorge vor einem Bun-Absturz schlafen zu gehen“, schrieb Sumner. Er macht Zig dafür nicht verantwortlich – andere Zig-Nutzer stoßen nicht auf solche Probleme, da die Vermischung von GC und manueller Speicherverwaltung eine extrem seltene Anforderung ist, für die kaum eine Sprache ausgelegt ist.

Die Rust-Version hingegen lieferte folgendes Ergebnis: Bei 2000 aufeinanderfolgenden Bun.build()-Aufrufen blieb der Speicher stabil bei 609 MB.

Neben der grundlegenden Behebung der Speicherlecks brachte die Rust-Neufassung weitere Verbesserungen in mehreren Dimensionen.

In Bezug auf die Stabilität behebt v1.4.0 128 reproduzierbare Fehler aus v1.3.14 – von Speicherlecks über Abstürze bis hin zu falsch farblich hervorgehobenen Hilfetexten.

Bezüglich der Größe wurde die Binärdateigröße von Bun unter Linux und Windows durch die Rust-Neufassung, Änderungen an ICU und konsistente Code-Faltung um etwa 20 % reduziert.

In der Leistung wurde eine allgemeine Steigerung von 2 % bis 5 % erreicht. Bun.serve stieg von 169.600 Anfragen/s auf 177.700 Anfragen/s, node:http von 103.800 auf 108.500. In praktischen Anwendungen sank die Ausführungszeit von next build von 13,62 Sekunden auf 13,03 Sekunden, und die Batch-Kompilierung mit tsc von 0,94 Sekunden auf 0,89 Sekunden.

Nach der Veröffentlichung von Claude Code auf Basis von Rust-Bun sank die Startzeit unter Linux von 517 ms auf 464 ms – eine Beschleunigung von etwa 10 %.

2  Methode: 64 Claude-Instanzen, 11 Tage, 50 Workflows

Wie Sumner dies erreicht hat, ist der wohl bemerkenswerteste Teil – denn seine Methode unterscheidet sich von dem herkömmlichen Ansatz, bei dem man „die KI einfach Code schreiben lässt“.

Sumner unterteilte den gesamten Prozess in etwa 50 dynamische Workflows, von denen jeder eine Schleife darstellt. In seinem Blog beschrieb er dieses Muster mit Pseudocode:

Jede Aufgabe verfügt über einen Kontext (z. B. ein Jira-Ticket oder ein GitHub-Issue). Claude schreibt Code auf Basis dieses Kontexts, anschließend prüfen zwei weitere Reviewer (ebenfalls Claude) den Code, und schließlich wird das Feedback umgesetzt. Nach Abschluss wird die nächste Aufgabe übernommen.

Dieses Muster durchzog den gesamten Neufassungsprozess. Jeder Workflow verfolgte ein spezifisches Ziel:

  • Erstellung einer Portierungsanleitung, die Muster und Typen von Zig auf entsprechende Entsprechungen in Rust abbildet;
  • Mechanische Portierung jeder .zig-Datei in eine .rs-Datei unter Berücksichtigung von PORTING.md und LIFETIMES.tsv;
  • Behebung der Kompilierungsfehler jedes Crates;
  • Inbetriebnahme von Unterbefehlen wie bun test oder bun build;
  • Sicherstellen, dass jeder Test in der gesamten Bun-Testsuite erfolgreich durchläuft; Durchführung mehrerer großer Refaktorisierungs- und Bereinigungsrunden.

In Spitzenzeiten führte Sumner 4 Workflows gleichzeitig aus, wobei jeder Workflow 16 Claude-Instanzen umfasste – insgesamt 64 Claude-Instanzen, die parallel in 4 Arbeitsbereichen arbeiteten und jeweils Dateien committeten und pushten. Auf dem Höhepunkt generierte Claude etwa 1300 Codezeilen pro Minute.

Diese Trennung zwischen „Implementierer“ und „Reviewer“ war der Schlüssel. Der Claude, der den Code schreibt, neigt wie menschliche Ingenieure dazu, dass sein Code akzeptiert wird. Deshalb sind Reviewer und Implementierer vollständig getrennt: Die Reviewer betrachten nur die Code-Diffs, nicht die Denkprozesse des Implementierers, und werden ausdrücklich angewiesen, „davon auszugehen, dass der Code fehlerhaft ist“. Jedem Implementierer sind zwei oder mehr gegnerische Reviewer zugeordnet, deren einzige Aufgabe es ist, Fehler zu finden.

Das Schreiben des Codes war nur der erste Schritt. Der Zig-Code bildete eine einzelne Kompilierungseinheit, während Rust in etwa 100 Crates unterteilt werden musste, um die Kompilierungsgeschwindigkeit zu erhöhen. Zirkuläre Abhängigkeiten führten dazu, dass cargo check auf einmal etwa 16.000 Kompilierungsfehler ausgab. Für einen einzelnen Menschen wäre das eine Katastrophe, aber für 64 parallel arbeitende Claude-Instanzen war dies eine handhabbare Aufgabenwarteschlange. Die Workflows gruppierten die Fehler nach Crates: Für jedes Crate wurde cargo check ausgeführt, ein Claude reparierte die Fehler, zwei überprüften die Änderungen und einer wandte sie an.

Anschließend wurde zuerst bun --version zum Laufen gebracht, dann bun test. Der Test-Workflow führte jedes Mal zufällig 100 Testdateien aus und verteilte sie auf 4 Arbeitsbereiche. Die Testsuite umfasste verschiedene Arten von Tests: Einige liefen länger als eine Minute, andere erschöpften die Anzahl der TCP-Verbindungen des Systems, und wieder andere fork-ten etwa 10.000 Prozesse. Sumner nutzte systemd-run, um Cgroups zur Ressourcenbegrenzung zu erstellen – trotzdem stürzte der Rechner mehrmals aufgrund unzureichenden Speicherplatzes auf der Festplatte ab.

Zwei Tage später sank die Anzahl fehlgeschlagener Tests unter Linux von 972 auf 23. Nach anderthalb Tagen waren alle Tests unter Linux erfolgreich. Fünf Tage später bestanden alle sechs Plattformen – Linux x64, Linux arm64, macOS x64, macOS arm64, Windows x64 und Windows arm64 – sämtliche Tests.

Am 14. Mai wurde PR #30412 offiziell zusammengeführt; die gesamte Testsuite durchlief erfolgreich, ohne dass ein Test übersprungen oder gelöscht werden musste.

3  Bedenken: 13.000 unsafe-Schlüsselwörter und Code, der nicht Zeile für Zeile überprüfbar ist

Sumner räumt jedoch ein, dass diese Arbeit noch nicht wirklich abgeschlossen ist.

Bislang befinden sich etwa 4 % des Rust-Codes von Bun in unsafe-Blöcken – das entspricht rund 13.000 unsafe-Schlüsselwörtern, verteilt auf etwa 27.000 Codezeilen, bei einem gesamten Rust-Codeumfang von etwa 780.000 Zeilen. 78 % dieser unsafe-Blöcke umfassen nur eine Zeile, in der Regel einen Zeiger aus C++ oder einen Aufruf einer C-Bibliothek.

Er erwartet, dass nachfolgende Refaktorisierungen diesen Anteil senken werden. Dennoch hat jemand nachgerechnet: uv umfasst etwa 350.000 Codezeilen und weist nur 73 unsafe-Aufrufe auf. Die Anzahl der unsafe-Vorkommen bei Bun ist das 178-fache von der bei uv