The Bun Rust rewrite is an impressive feat

MMaximilian Schwarzmüller
Computing/SoftwareSmall Business/StartupsInternet Technology

Transcript

00:00:00BUN was ported from SIG to Rust.
00:00:02You probably already heard about that,
00:00:04but there's a lot to unpack here.
00:00:06There has been a lot of drama last week,
00:00:08but there's a lot of interesting stuff going on.
00:00:10And no matter if you're interested in BUN, SIG or Rust,
00:00:14this is really interesting.
00:00:15Also regarding how AI was leveraged
00:00:18and what that could mean for similar projects
00:00:20in our industry in general.
00:00:22Now, just as a little side note,
00:00:24I personally like BUN quite a bit.
00:00:26It is my default JavaScript runtime I use
00:00:29in most of my projects.
00:00:30And indeed, as a nice coincidence,
00:00:32I published a brand new course on BUN last week.
00:00:35And it works of course for the Rust version
00:00:37as it does for the SIG version.
00:00:39So if you wanna dive a bit deeper into BUN
00:00:41and learn about all the core APIs it has to offer,
00:00:44because that's one of the biggest advantages of BUN
00:00:46that it has so much stuff built in.
00:00:48Some people don't like it, I love it.
00:00:50If you wanna learn more about that,
00:00:51that course may be interesting.
00:00:53But let's now take a closer look
00:00:54at the overall porting timeline, shall we?
00:00:58It actually happened two months ago.
00:01:01So the blog post was released last week in July,
00:01:04but the port itself happened in May.
00:01:08And it started in early May
00:01:10when the CloudFaserPort branch was discovered
00:01:13on the official BUN GitHub repository.
00:01:15That branch contained a porting MD file,
00:01:18a markdown file with instructions
00:01:21on how to convert SIG code to Rust code,
00:01:23how to port that code, translation tables,
00:01:27and in general instructions.
00:01:28And we'll get back to how that file was created,
00:01:30because of course AI was involved,
00:01:32as you may guess, a little bit later.
00:01:34That was discovered.
00:01:36So naturally, discussions ensued on Hacker News on X.
00:01:40And there were people excited about that.
00:01:43There were people very critical of that.
00:01:46But at that point, we didn't know a lot.
00:01:47Obviously, there is a lot of polarization around Rust.
00:01:52There are people that love Rust, like myself.
00:01:55There are people that hate Rust.
00:01:57There are people that hate
00:01:58that everything should be rewritten in Rust,
00:02:00because very often you read
00:02:03that people want program XYZ to be rewritten in Rust.
00:02:06And I get that this is annoying.
00:02:08But naturally, therefore,
00:02:09there was a lot of polarization there going on.
00:02:11But the port had not yet happened.
00:02:15That changed later in May.
00:02:16And on May 14th, an official pull request was opened,
00:02:22and then also merged,
00:02:24that actually migrated the BUN code base,
00:02:28all of it, from SIG to Rust.
00:02:30Now, as you can see, it's a huge pull request.
00:02:32More than one million lines of code were added.
00:02:35And the removal of the SIG code happened
00:02:39in a different stage.
00:02:40So yeah, that's why it's not a swap.
00:02:42But it's a huge change, as you can see,
00:02:44with almost 7,000 commits.
00:02:46Now, naturally, that code was not human reviewed,
00:02:51at least not entirely.
00:02:52It was reviewed by AI.
00:02:54It had passing tests, but it was not human reviewed.
00:02:59And we'll get back to how AI was used in just a second.
00:03:02But that was published or merged.
00:03:06And of course, more discussion ensued now.
00:03:08As I just mentioned, it was not reviewed by humans.
00:03:10That's impossible to do in that timeframe, of course.
00:03:14But the community dove in and had a look
00:03:17and analyzed parts.
00:03:19And then there was another, or a first blog post,
00:03:23not the official one about all the details,
00:03:25but one first blog post or statement released by the Buntine
00:03:29about the use of unsafe.
00:03:32Because one big criticism that came up after this pull request
00:03:37is that the Rust code in there was not idiomatic Rust.
00:03:41It was not the kind of Rust code you would or should write
00:03:44if you were building this from scratch.
00:03:46Instead, it really was like a translation from SIG to Rust.
00:03:50And that meant that not all those Rust best practices
00:03:54and patterns were used.
00:03:55And especially, there was a decent amount
00:03:58of unsafe usage in there.
00:04:00Now, to understand unsafe, you have to understand
00:04:03how Rust manages memory.
00:04:05because that is one of its biggest advantages,
00:04:08and it's quite different from other languages.
00:04:10Because in most languages, you have either a garbage collector,
00:04:14which is a process that basically detects
00:04:16when a value is no longer used anywhere in the program
00:04:19and then frees up the memory, which is convenient,
00:04:21but consumes extra resources.
00:04:24Or you have to do it yourself.
00:04:26In languages like C, for example,
00:04:28you have to manually allocate and free up memory.
00:04:31And it's the same in SIG.
00:04:33You can allocate memory there, but you also have to call free
00:04:37or you have to free it up when you no longer need it.
00:04:40You can use defer, which is nice.
00:04:43That basically means you can call that
00:04:47before it's actually executed.
00:04:49It is deferred and will be called automatically
00:04:52when this scope ends, essentially.
00:04:55And that's nice because there are different situations
00:04:58where a value may no longer be needed.
00:05:00But still, when you have to clean up memory manually,
00:05:04there are many situations
00:05:05where you can shoot yourself in the foot.
00:05:07You have more fine-grained control
00:05:09and that can be very useful, very efficient,
00:05:11but it's also easy to forget situations
00:05:15in more complex programs
00:05:16where you then may not be cleaning up memory,
00:05:19hence introducing a memory leak,
00:05:20or where you may be cleaning up twice,
00:05:23which will also cause an error.
00:05:25And therefore there is a trade-off.
00:05:27And Rust has a different approach.
00:05:30In Rust, you have a concept called ownership,
00:05:32which means that every value has exactly one owner,
00:05:36and it's tied to scope.
00:05:38So if you have a scope,
00:05:39and you can create scope by using curly braces,
00:05:41or a function would also have its own scope.
00:05:43You may know that concept from JavaScript.
00:05:46If you have scope,
00:05:47then when a value is created in there,
00:05:49it's owned by that scope.
00:05:51And if the scope ends, it's freed up.
00:05:53And that of course is very convenient
00:05:55because you don't have to take care about freeing it up.
00:05:58You also don't have a garbage collector.
00:06:00Instead, you have that clear rule.
00:06:02That can lead to complexity in more complex programs
00:06:05where you need to pass values around.
00:06:07You can do that in Rust,
00:06:08but it requires a different way of thinking.
00:06:11But of course it gives you memory safety,
00:06:14unless you use the unsafe keyword.
00:06:19If you use that, you can create an unsafe scope.
00:06:22And in there, those rules no longer apply.
00:06:24And it's then your job to make sure
00:06:26that memory is managed appropriately.
00:06:28Now, why would you do that?
00:06:29Well, for example,
00:06:31if you're pulling in some C library,
00:06:33which you can do in Rust,
00:06:34you can blend in some C code, so to say,
00:06:37or call some C library methods and functions,
00:06:40then since C is naturally unsafe,
00:06:44the code where you reach out to that C code is also unsafe.
00:06:48So you need that feature to interact with our unsafe code.
00:06:52And that is also one thing they noted
00:06:54in that official statement,
00:06:56that all those unsafe usages in the code base
00:07:00to a decent part were actually related to calls,
00:07:04to other libraries, C libraries, and so on,
00:07:07which won't change.
00:07:08But they also identified areas
00:07:10where they could actually improve the code
00:07:13and get rid of unsafe.
00:07:14And they mentioned that they would do this
00:07:15in subsequent pull requests.
00:07:18And they did and still are doing that.
00:07:20So you can think of this initial port
00:07:22as like a starting point,
00:07:24which then got refined over time.
00:07:26Still worth mentioning that this initial pull request,
00:07:28or that huge pull request,
00:07:30already had passing tests.
00:07:32So it was stable, the tests were passing,
00:07:35but the code was not of the code quality
00:07:37you would maybe expect if it were written in Rust
00:07:40from the grown up, because that wasn't the goal.
00:07:43So that was May 21st.
00:07:45Then there was silence.
00:07:46And it's also worth noting that this version of BUN
00:07:49was not released yet.
00:07:50And when I'm recording this, it's still not live.
00:07:52When you're installing BUN right now,
00:07:54you're still getting the SIG version,
00:07:56but that should change any day now.
00:07:58But then on July 8th,
00:07:59the official blog post was released
00:08:02where we find lots of interesting details
00:08:04about this port.
00:08:06And it's really worth reading.
00:08:07I'll link it below
00:08:08because there is a lot to learn here.
00:08:11This entire port, and that's no secret,
00:08:13was done with help of AI.
00:08:15It's worth keeping in mind that BUN is owned by Anthropic.
00:08:18So they had free access to all those tokens
00:08:22and especially also to Fable 5
00:08:24before it was released to the public.
00:08:26This port was done with Fable 5.
00:08:29And if you're installing Cloud Code now, by the way,
00:08:32even though BUN 1.4, the Rust version is not released yet,
00:08:36Cloud Code is already running on top
00:08:39of an unreleased BUN version, so to say,
00:08:42that is the Rust version.
00:08:44So there's that.
00:08:45But yeah, this port was done with Cloud Code
00:08:48based on Fable 5 with free tokens, of course,
00:08:52essentially, since BUN is part of Anthropic.
00:08:54And that's important to keep in mind
00:08:56because in that blog post,
00:08:58we learn that if you were to combine all the tokens,
00:09:03or if you were to sum up all the tokens
00:09:04that were spent and charge API prices,
00:09:08this entire port would have cost around $160,000.
00:09:13That's a mind-blowing number, but actually,
00:09:18if you think about the scope of this project,
00:09:20and the scope is that BUN was 535,000 lines of SIG code,
00:09:26if you think about that scope
00:09:28and how long it would take humans to port that to Rust,
00:09:32then the $160,000 actually might not sound too bad,
00:09:36depending on where you're located.
00:09:38Now, nonetheless, it's clear that no open source project
00:09:43would be able to do that.
00:09:44And most companies would probably not be able
00:09:47or willing to spend that amount of money on a port.
00:09:50This is possible because BUN is part of Anthropic.
00:09:54And of course, this is also a nice marketing stunt
00:09:58for Anthropic.
00:09:59That may not have been the main intent.
00:10:03I don't know that.
00:10:04But of course, it's nice marketing.
00:10:06That is all important to keep in mind.
00:10:08Nonetheless, in this blog post,
00:10:10we can learn how Jared did that port
00:10:14or how he made that port work.
00:10:18And that all started with that porting MD file,
00:10:21which he created in a discussion with Claude,
00:10:25in a three-hour discussion,
00:10:26as he mentioned in the blog post,
00:10:28where he essentially decided together with Claude code
00:10:32and the Anthropic models,
00:10:35how such a porting MD file would have to look like
00:10:37to be able to translate SIG to Rust code.
00:10:40Then once he iterated on that and was happy with it,
00:10:44he tested it on three files initially.
00:10:46And once he was happy with that,
00:10:48he unleashed Claude on the entire BUN code base.
00:10:53Now in this blog post,
00:10:54he makes it clear that he did not just prompt Claude
00:10:57to rewrite BUN and Rust, make no mistakes,
00:11:00but that instead he set up an elaborate system
00:11:03where he had one main agent,
00:11:07spinning up sub-agents too, of course,
00:11:09doing the port according to the porting MD file.
00:11:13And then he had two adversarial review agents
00:11:16that reviewed the work of that main agent once it was done
00:11:19and provided feedback,
00:11:21and then a fixer agent for applying that feedback.
00:11:24And he had that all running in a loop
00:11:25and of course distributed across multiple work trees
00:11:30to process the entire code base
00:11:33and work its way through it.
00:11:35In the blog post,
00:11:35he mentioned that he rewrote BUN and Rust
00:11:38using 50 dynamic workflows in Claude code,
00:11:40which are these workflows that spin up a lot of sub-agents
00:11:43over the course of 11 days.
00:11:46And he also has a nice chart in there.
00:11:48In general, in the blog post,
00:11:49there are nice graphics in there
00:11:51that make it a bit easier to digest,
00:11:53that show the amount of commits that were created
00:11:56and then pushed on the different days
00:11:58and then times of the day.
00:12:00So that all happened with help of loops in Claude code,
00:12:04with help of a lot of sub-agents
00:12:05and the clear process of one main agent,
00:12:08the review agents and the fixer agent.
00:12:10And then he also did another separate path
00:12:15so to say making all those tests work.
00:12:20And that brought its own challenges
00:12:22because the test suite is so large and complex
00:12:25that he ran into various infrastructure restrictions
00:12:29because some tests consume a lot of memory
00:12:31and running many tests in parallel,
00:12:33therefore it doesn't work.
00:12:34But ultimately he made that all work also with help of AI,
00:12:39running the tests, fixing the code,
00:12:42rerunning the tests and so on.
00:12:43So lots of looping, lots of agents and sub-agents involved,
00:12:47naturally, and lots of tokens burned.
00:12:49$165,000 in tokens burned.
00:12:53Now again, you can dive in deeper,
00:12:55and that is what I would recommend doing
00:12:57if you're interested in all the nitty-gritty details.
00:12:59It's a really great blog post documenting the journey to getting there.
00:13:03But that is in a nutshell how the port happened over 11 days
00:13:08with all those agents and sub-agents distributed across multiple workflows,
00:13:1250 such workflows, as we learned across or over 11 days,
00:13:17$165,000 spent in tokens at API prices.
00:13:24Now, finally, once he was done in the blog post,
00:13:29he mentioned that Bun 1.4 fixes various bugs that the last SICK version has,
00:13:35that it's more memory efficient, that it's smaller.
00:13:38And as we learn by the response of Andrew Kelly, the creator of SICK,
00:13:43some of these improvements could have probably also achieved with SICK.
00:13:47But that blog post is pretty interesting because it got edited.
00:13:53It's less full of anger now than it was initially.
00:13:57The first version was full of personal attacks,
00:14:00just to then say that it was not meant as a personal attack,
00:14:03but it was full of personal attacks.
00:14:05The latest version, which I'll also link below, is still pretty spicy.
00:14:11In the end, you can clearly tell from reading the first version,
00:14:14but also this version,
00:14:16that Andrew, the creator of SICK and Jared, the creator of Bun,
00:14:21they won't become best friends anymore or again.
00:14:26Now, he thanks Bun for supporting SICK, also financially,
00:14:31just to basically rage about this entire port and how it wouldn't have been necessary
00:14:41if the Bun code would have been written in proper SICK.
00:14:44He makes it very clear that he doesn't feel like the Bun repository,
00:14:48the SICK version, had a high code quality and that led to many problems.
00:14:53And that may or may not be true.
00:14:56I think it's absolutely possible that in a project of the scale of Bun,
00:15:01moving at the speed in which Bun moves,
00:15:06code quality may not have been up to the standards of the creator of SICK.
00:15:12You could definitely argue that most code projects
00:15:15don't necessarily have the highest code quality, though.
00:15:18So you can make up that whatever you want.
00:15:21Now, I'll leave it at that.
00:15:24I feel like the overall response blog post is pretty weak
00:15:29because it is so steaming with anger.
00:15:33It has some valid points.
00:15:35Like, for example, in the blog post Jared makes,
00:15:40he mentions that the port from SICK to Rust was validated,
00:15:46of course, with all these reviewer agents,
00:15:48but also by running the test suite and making that work.
00:15:51And Andrew correctly states that, of course, that same test suite
00:15:56should or should not have been sufficient to prove that the SICK version is great.
00:16:00So maybe the test suite should have been improved, too.
00:16:04Either way, definitely these two won't become best friends.
00:16:09And I have no opinion on whether SICK or Rust is the battery language in general or for Bun.
00:16:17I do believe, however, that with AI, Rust and its memory model and the fact
00:16:23that you get compile time errors for many memory related issues is a huge advantage,
00:16:30especially in the age of AI, because, of course, this entire port is really impressive
00:16:38when it comes to the use of AI.
00:16:41And sure, it's it's a way of using AI that most of us won't be able to afford
00:16:45or won't be willing to afford in companies.
00:16:48But it's impressive that I was able to do that.
00:16:52And it's not Vibe coding or just YOLO prompting.
00:16:56There is a clear process behind all of that.
00:16:59A lot of thought went into this, which I hopefully made clear, which definitely also gets clear
00:17:05if you dive into the nitty gritty technical details.
00:17:08But with all the planning, all the iteration with the setup, with the way this was approached,
00:17:13clearly this was not just one prompt thrown at it.
00:17:17And then we'll see where we get this shows what you can do with AI.
00:17:21And of course, porting a code base from one language to another is a pretty good use case for AI.
00:17:27If you think about it, AI can, of course, struggle with writing new code.
00:17:32It may not write the code you wanted to write, not follow the code conventions
00:17:36or styles you wanted to follow, and it may also mess up things.
00:17:40Now, it definitely AI is amazing for building new software, too.
00:17:43But you face a different set of problems there with a port.
00:17:47The huge advantage is that you have a code base for the AI to just look at and translate,
00:17:53which is something AI can do, and you have a test suite there.
00:17:57So there's a lot to build up on.
00:17:59It's a good use case for AI, as it seems, and as this port clearly proves.
00:18:04And I think that is the most interesting takeaway here.
00:18:08Also that you can tackle projects that just would have been impossible
00:18:12to tackle before.
00:18:13Again, not for everybody, but for certain companies of certain sizes.
00:18:18This may be interesting.
00:18:19Modernizing legacy software with help of AI can or may be a great use case.
00:18:26And this shows and proves that this can be done.
00:18:30Now, of course, BUN 1.4 is not out yet.
00:18:32We'll see if everything crashes and they have to revert in a month from now.
00:18:36You can't totally rule it out, but I personally don't think that will happen.
00:18:40It is being used in production by some early adopters already, like the Cloud Code CLI.
00:18:47It has been tested and reviewed extensively, even though, of course, by AI, not human reviewers.
00:18:54But I'm pretty confident that this will work out and I find it a pretty impressive feat and also a pretty impressive usage of AI.
00:19:03But as always, I'm also interested in hearing what your thoughts are about all of that.

Key Takeaway

The successful migration of Bun from Zig to Rust demonstrates that complex, large-scale codebases can be effectively ported using multi-agent AI systems, despite high API costs and initial code quality trade-offs.

Highlights

  • Bun migrated its entire 535,000-line codebase from Zig to Rust over an 11-day period in May 2026.

  • The porting project utilized 50 dynamic Claude Code workflows, deploying a system of adversarial review and fixer agents to automate the conversion.

  • Replacing the legacy codebase required an estimated $160,000 in API tokens at current market prices.

  • The resulting Rust code initially contained a high volume of unsafe blocks, partially due to necessary interoperability with existing C libraries.

  • The migration was managed using a custom markdown-based instruction set developed through three hours of iterative prompting with Anthropic's models.

Timeline

Project Timeline and Initial Reception

  • The migration project began in early May 2026 and concluded on May 14th with an official pull request.
  • The pull request involved adding over 1 million lines of code and required nearly 7,000 commits to transition the project structure.
  • Public discourse surrounding the move was highly polarized, reflecting broader industry debates over the merits of rewriting existing software in Rust.

Development started after the discovery of a 'CloudFaserPort' branch on GitHub containing markdown instructions for translating Zig to Rust. The transition was not a direct file swap but a large-scale migration involving the addition of Rust code before the eventual removal of Zig components. The speed of the pull request meant the changes were reviewed primarily by AI and test suites rather than human engineers.

Technical Challenges and Unsafe Code Usage

  • Critics noted the initial Rust implementation was not idiomatic and contained excessive 'unsafe' blocks.
  • Rust's ownership model requires strict memory management, which can be bypassed using the 'unsafe' keyword.
  • Many instances of 'unsafe' were necessary to maintain compatibility with existing C libraries, though plans exist to refactor these in future updates.

The community identified that the ported code did not follow standard Rust best practices, functioning more like a direct translation. While Rust typically guarantees memory safety through ownership, interacting with C libraries requires the 'unsafe' keyword. The development team has committed to subsequent refactoring to minimize these safety-bypass areas over time.

Agentic Architecture and Economic Scope

  • The port was executed using 50 dynamic workflows, leveraging a main agent supported by adversarial review agents and a dedicated fixer agent.
  • The project consumed approximately $160,000 in compute tokens at commercial API prices.
  • The process was built on an iterative foundation, where initial instructions were tested on small samples before being applied to the full codebase.

The developer avoided simple prompting by creating a structured agentic loop. A main agent performed the translation, while two adversarial agents reviewed the work, and a fixer agent applied corrections based on feedback. This highly automated approach enabled the migration of over 500,000 lines of code in just 11 days.

Industry Implications and Future Outlook

  • The Bun 1.4 update promises improved memory efficiency and smaller binary sizes compared to the Zig version.
  • The migration highlights AI's capability to modernize legacy software, provided there is an existing test suite for validation.
  • The project serves as a practical proof of concept for using multi-agent systems to tackle engineering tasks previously considered cost-prohibitive.

The move to Rust has sparked friction between project leads, but the technical result appears stable, with early adopters already running the code via CLI tools. The most significant takeaway for the software industry is the viability of using agentic loops for large-scale language migrations, provided the project is supported by a comprehensive existing test suite.

Community Posts

View all posts