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.