- Als es in Zig ohne Speichersicherheit weiterhin zu Lecks und Abstürzen kam, migrierte Bun 535.496 Zeilen Code mit 64 AI-Agenten nach Rust und verkürzte eine auf 1–2 Jahre geschätzte Arbeit auf 11 Tage
- Ausgangspunkt des Erfolgs war ein 600 Zeilen langes
PORTING.md; danach folgten dateiweises paralleles Konvertieren, zwei adversarielle Reviews, das Beheben von Compilerfehlern, lokale Tests und das Bestehen von CI in dieser Reihenfolge - Für 6.500 Commits wurden laut API-Preisen 165.000 US-Dollar sowie 5,9 Milliarden nicht gecachte Input-, 690 Millionen Output- und 72 Milliarden gelesene Cache-Input-Token verbraucht
- Bei manueller Arbeit hätten vermutlich drei Ingenieure mit tiefem Wissen über die Codebasis etwa ein Jahr lang Produktverbesserungen, Bug- und Security-Fixes sowie die Entwicklung neuer Features stoppen müssen, weshalb die Neuschreibung selbst schwer umsetzbar gewesen wäre
- Um denselben Ansatz zu wiederholen, braucht es Ingenieure mit tiefem Verständnis der Codebasis, eine starke Test-Suite, deren Ergebnisse vertrauenswürdig sind, und die Bereitschaft, trotz ungewissem Erfolg Token-Kosten zu tragen
Warum Bun sich für eine Rust-Neuschreibung entschieden hat
- Bun ist ein komplexes Produktionsprojekt, das über eine JavaScript-Runtime hinaus viele Funktionen bietet
- JavaScript-, TypeScript- und CSS-Transformation, Bundling, Minifizierung
- Test-Runner und npm-kompatibler Paketmanager
- Modulauflösung, WebSocket-Client, Node.js-Implementierung und verschiedene Module
- Die monatlichen Downloads liegen bei 22 Millionen; Claude Code und OpenCode hängen davon ab, und Vercel, Railway und DigitalOcean unterstützen es direkt
- Zig ist keine speichersichere Sprache, daher treten auch in aktuellem Bun weiterhin Memory Leaks, speicherbedingte Abstürze und Schreibzugriffe außerhalb des Heap-Bereichs auf
- Das Bun-Team patchte den Zig-Compiler und führte End-to-End-Tests für Memory Leaks ein, konnte die Probleme aber nicht beseitigen
- Beim gleichzeitigen Umgang mit den Lebensdauern von Garbage-Collected-Werten und manuell verwalteten Werten entstanden kleine Lecks und sporadische Abstürze
- Bei jeder Speicherallokation mussten Freigabestelle und mögliche doppelte Freigabe, JavaScript-Exception-Handling sowie die Pointer-Sichtbarkeit des konservativen Stack-Scanners geprüft werden
- In sicherem Rust werden use-after-free und double-free zu Compilerfehlern, und fehlende Freigaben auf Fehlerpfaden lassen sich über automatische Bereinigung auf Basis von
Dropbehandeln - Es wurde auch geprüft, Rust-artige Smart Pointer direkt in Bun einzuführen, aber das hätte gegenüber Rust eine schlechtere Ergonomie bei fehlenden gleichwertigen Garantien geboten
Warum bestehende Rewrite-Projekte lange dauern
- Während der Neuschreibung werden der ursprünglichen Codebasis weiter Features hinzugefügt, weshalb sich der Fertigstellungstermin oft immer weiter verschiebt
- Eine auf 9 Monate geschätzte Arbeit kann nach 9 Monaten noch etwa 6 weitere Monate benötigen
- Selbst nach 15 Monaten können wegen des Nachziehens neuer Features noch mehrere Monate Arbeit übrig sein
- Selbst mit Glück endet es erst nach einem zweimonatigen Feature-Freeze in etwa 18 Monaten, sodass eine anfängliche Schätzung von 9 Monaten auf mehr als 2 Jahre anwachsen kann
- Buns Zig-Code umfasst ohne Kommentare 535.496 Zeilen, daher wurde geschätzt, dass ein kleines Ingenieurteam etwa ein Jahr brauchen würde, um ihn in eine andere Sprache zu übertragen
- Ein Jahr ohne sichtbare Verbesserungen für Nutzer war keine realistische Option, daher sollte mit Fable geprüft werden, ob sich die Rust-Portierung innerhalb einer Woche validieren lässt
Vorabdesign und Validierung für die Portierung
- Im ersten Schritt wurde etwa 3 Stunden lang mit Claude besprochen, wie Zig-Patterns Rust-nah abgebildet werden können; das wurde in einem 600 Zeilen langen
PORTING.mdfestgehalten - Die Portierungsrichtlinien enthalten konkrete Einschränkungen, um Buns bestehende Ausführungsstruktur zu erhalten
tokio,rayon,hyper,async-trait,futureswerden nicht verwendet- Module mit I/O-Zugriff wie
std::fs,std::net,std::processsind verboten - Da Bun seinen eigenen Event Loop und die System Calls kontrolliert, werden statt
async fnwie im bisherigen Zig Callbacks und State Machines verwendet - Wenn Konflikte mit dem Borrow Checker auftreten, werden nötige skalare Werte in lokalen Variablen gespeichert, das Borrow beendet und danach erneut geborgt
- Die Verwendung roher Pointer zur Umgehung des Borrow Checkers ist verboten; an Stellen mit Strukturänderungen werden Portierungsnotizen hinterlassen
- Von insgesamt 1.448 Dateien wurden zunächst 3 Dateien neu geschrieben; danach führte Claude in einer von der Implementierung getrennten Session zwei adversarielle Reviews durch
Parallelarbeit mit 64 AI-Agenten
- Die Arbeit wurde so aufgeteilt, dass Dateien unabhängig voneinander bearbeitet werden konnten, und 64 AI-Agenten liefen parallel
- Anfangs entstanden Konflikte, weil mehrere Agenten denselben Repository-Stand bearbeiteten
- Ein Agent führte
git stashaus, danach führten andere Agentengit stash popundgit reset HEAD --hardaus - Jedem Agenten ein eigenes Worktree zuzuweisen scheiterte am Speicherplatz wegen der Größe des Bun-Repositories; zudem mussten die Änderungen am Ende ohnehin gemeinsam kompiliert werden
- Ein Agent führte
- Der Workflow wurde angepasst: Mit Ausnahme von Befehlen zum sofortigen Committen bestimmter Dateien wurden Git-Befehle wie
git stashundgit resetverboten; auchcargound lang laufende Befehle durften nicht verwendet werden - Am Ende wurde die Arbeit auf 4 Worktrees verteilt, in denen jeweils 16 Claude-Instanzen Dateien committen und pushen sollten
- In zwei Tagen übertrugen die Agenten 535.496 Zeilen Zig-Code; jeder Commit durchlief vor der Übernahme zwei adversarielle Reviews
Compilerfehler und Test-Fixes
- Die erste Konvertierung war abgeschlossen, aber der Code kompilierte nicht; daher ließ Bun Claude die Fehler pro Crate, also pro oberster Rust-Kompilationseinheit, beheben
- Im Abschnittstitel ist von etwa 1.600 Compilerfehlern die Rede, im Zitat jedoch davon, dass beim Auflösen zyklischer Abhängigkeiten rund 16.000 Fehler sichtbar wurden
- Auch das Beheben der Fehler wurde parallelisiert
- In jeder Crate wurde
cargo checkausgeführt - Die Ausgabe wurde dateiweise gebündelt und Fehlerdateien wurden gespeichert
- Sämtliche Compilerfehler der jeweiligen Crate wurden behoben
- Zwei adversarielle Reviewer prüften die Änderungen
- Ein Agent für Korrekturen übernahm die Review-Ergebnisse
- In jeder Crate wurde
- Von Mitternacht bis 11:30 Uhr vormittags behoben die Agenten Compilerfehler ohne menschliches Eingreifen
- Anschließend wurde in etwa zwei Tagen die große Test-Suite so weit gebracht, dass sie lokal ohne Compilerfehler lief; danach flossen noch mehrere Tage in das Beheben fehlschlagender Tests, bis CI erfolgreich war
- Nachdem alle Tests bestanden und die Funktion bestätigt war, wurden die Änderungen gemergt; von der Planung bis zum Abschluss dauerte es insgesamt 11 Tage
- Portierung von rund 550.000 Zeilen Code
- 6.500 Commits
- Einsatz von 64 Agenten
Kosten und Ergebnis im Vergleich zu manueller Arbeit
- Nach Fable-API-Preisen beliefen sich die Gesamtkosten der Neuschreibung auf 165.000 US-Dollar
- 5,9 Milliarden nicht gecachte Input-Token
- 690 Millionen Output-Token
- 72 Milliarden gelesene Cache-Input-Token
- Anthropic verkauft API-Token mit Marge, daher dürften die tatsächlichen internen Kosten darunter liegen
- Die API-Kosten entsprechen etwa dem jährlichen Grundgehalt eines Software-Ingenieurs auf mittlerem Niveau in den USA, doch ein einzelner Ingenieur in derselben Gehaltsklasse könnte das gleiche Ergebnis in 11 Tagen unmöglich erreichen
- Das passt auch zu Mitchell Hashimotos Einschätzung, dass Fable besonders stark bei schwierigen, fokussierten Aufgaben mit klarer Reward Function ist
- Bei manueller Arbeit wären voraussichtlich drei Ingenieure nötig gewesen, die die Codebasis vollständig kennen, und zwar für etwa ein Jahr
- In dieser Zeit wären Verbesserungen der Node.js-Kompatibilität, Bug- und Security-Fixes sowie neue Features kaum vorangekommen
- Die realistische Alternative wäre gewesen, nicht neu zu schreiben und stattdessen die bestehenden Memory Bugs weiter zu flicken
Voraussetzungen für den Einsatz in anderen Projekten
- Wenn AI eine einjährige Neuschreibung oder Migration auf etwa eine Woche verkürzen kann, werden auch Projekte machbar, die zuvor kaum ernsthaft in Betracht kamen
- Um Buns Workflow wiederzuverwenden, sind drei Bedingungen nötig
- ein Ingenieur, der die Codebasis sehr gut kennt und den starken Willen zur Umsetzung hat
- eine ausreichend starke Test-Suite, deren Bestehen als Nachweis für reales Funktionieren vertrauenswürdig ist
- die Bereitschaft, erhebliche Token-Kosten zu investieren, obwohl der Erfolg im Voraus nicht sicher ist
- Wiederholbare Arbeiten wie Code-Migrationen können LLMs vergleichsweise gut bearbeiten; mit guten Tests und einem Ingenieur, der das Problem strukturieren kann, stehen die Erfolgschancen hoch
- Nicht jedes Projekt braucht 165.000 US-Dollar
- Bei einfacheren Projekten können die Kosten geringer ausfallen
- Für die High-Level-Planung kann das teuerste Modell verwendet werden, während für Coding und Reviews günstigere Modelle eingesetzt werden können
- AI-basierte Migrationen werden schneller, aber Geschwindigkeiten wie bei Bun lassen sich nur in gut entwickelten Projekten erreichen
Noch keine Kommentare.