Dev Practice

Bun and Claude Team Up: AOT and Lint Next? Is It Time to Switch to Bun?

Key Takeaway

Bun, a JavaScript development tool, attracted attention from the start as a “fast tool.”

It runs JavaScript and TypeScript, installs packages, and handles testing and bundling in one place. It was built on the systems programming language Zig and JavaScriptCore, Safari’s JavaScript engine.

In 2026, however, Bun’s internals changed significantly. The Bun team moved major portions of its code from Zig to Rust, using Claude Code extensively in the process. The initial migration reportedly took about 11 days. After a period of stabilization, the Rust-based code entered the stable Bun 1.4 release.

This story does not end with the simple conclusion that “Rust is faster than Zig” or that “AI replaced developers.” Memory safety problems were a reason for the migration, and regressions were found even after all tests passed. Some performance improvements also came from optimizations carried out separately from the language migration.

Let’s look in turn at what changed from Bun 1.3.14 through 1.4.4, how it differs from Node.js and Deno, and what the community had to say.

Key points first

  • Bun 1.3.14 was the last stable release of the Zig era, and 1.4.0 was the first stable release to include the Rust migration.
  • Anthropic acquired Bun in December 2025. Bun creator Jarred Sumner said the migration used Claude Code and the pre-release Claude Fable 5.
  • The initial port was merged into main in about 11 days, but there was additional verification and stabilization between the merge and the stable release.
  • Moving to Rust does not mean all of Bun is composed solely of safe Rust. It continues to use JavaScriptCore and several C and C++ libraries.
  • Bun 1.4’s startup time and memory improvements are worth examining, but those figures cannot be attributed to the Rust language alone.
  • As checked on November 6, 2026, the latest stable release was 1.4.4. Experimental AOT compilation, bun lint, and other work have been under development on main since then. Bun releases

What was Bun originally building?

Bun is often introduced as an alternative to Node.js, but it is more than a runtime alone.

It combines a JavaScript and TypeScript runtime, package manager, test runner, and bundler in one tool. Developers can use only bun install or bun test in an existing Node.js project, or they can run the application itself on Bun.

Its technical architecture also differs from Node.js. Node.js and Deno use Google’s V8 engine, while Bun uses WebKit’s JavaScriptCore. A layer connects the engine to operating system, networking, file system, and package management features, and much of that layer was previously written in Zig.

Bun creator Jarred Sumner says Zig’s simplicity and low-level control helped him build the initial Bun quickly. At the same time, he says that as Bun grew, correctly coordinating lifetimes between JavaScript’s garbage collection and manually managed native memory became difficult. Bun: Rewriting Bun in Rust

From 1.3.14 to 1.4.4: What changed?

TimeVersion or eventMain details
December 2025Anthropic acquires BunThe Bun team joined Anthropic.
May 2026Rust port mergedThe Rust code was merged into main after about 11 days of initial migration work.
June 2026Used in Claude CodeBun said the Rust port first went into Claude Code.
August 2026Bun 1.4.0The first stable release containing the Rust port was released.
September 20261.4.1 and 1.4.2HTTP/2 and memory improvements arrived alongside fixes for several regressions and crashes.
October 20261.4.3The built-in TypeScript type checker bun check appeared.
October 20261.4.4Included bun fmt, package installation improvements, SQL and WebSocket fixes, and security fixes.

The acquisition is documented in Anthropic’s December 2025 announcement. The timing of the Rust port’s merge and its use in Claude Code are described in Bun’s migration account, while version changes can be found on the Bun blog.

1.4.0: A larger toolbox alongside the language migration

In addition to the Rust port, Bun 1.4 announced Node.js compatibility improvements, parallel test and script execution, Bun.Image, Bun.WebView, Bun.markdown, and APIs related to terminals and cron.

For Node.js compatibility, the Bun team said an additional 1,517 tests passed in the Node.js test suite. Bun explicitly states in its official announcement, however, that it is still not 100% compatible with Node.js. The pass rates of individual modules should not be read as the compatibility rate for all npm packages. Bun 1.4 announcement

1.4.1 and 1.4.2: Stabilization continued after release

Version 1.4.1 added HTTP/2 support for Bun.serve, improved idle memory usage, and offline installation options. Version 1.4.2 fixed regressions affecting Elysia builds and AsyncLocalStorage, among other things, as well as rare JIT and garbage collection crashes.

The important point is that not every subsequent bug can be considered a direct result of the Rust port. Conversely, passing a large test suite does not mean one should assume a new version has no regressions. Bun 1.4.1, Bun 1.4.2

1.4.3 and 1.4.4: Type checking and formatting

The standout change in 1.4.3 was bun check. The Bun team said the type checker is based on a TypeScript 7-family implementation and was faster than tsc 7.0.2 on several projects selected at the time of the announcement.

For example, on a 16-core Apple Silicon Mac, type checking the VS Code source took 1.24 seconds with bun check and 5.98 seconds with tsc 7.0.2. These are results from projects and an environment selected by the Bun team. Also, bun check is a type checker; it does not itself emit JavaScript or .d.ts files. Bun 1.4.3 announcement and measurement conditions

Version 1.4.4 added bun fmt, Yarn Berry lockfile migration, improved installation retries, and SQL and WebSocket changes, among other things. It also includes security fixes for TLS, networking, the package manager, and more, so production users should review the scope of fixes in the release notes as well as the new features. Bun 1.4.4 release notes

How did Claude move Bun to Rust?

The idea that “someone entered one sentence into an AI and Bun was complete” is far from the actual process.

According to the Bun team, it first worked out how to map Zig types and patterns to Rust. It then used Claude Code workflows to repeatedly convert individual files, fix compilation errors, check command-by-command behavior, fix test failures, and clean up the results.

Sumner says he used about 50 workflows and that, at the busiest point, about 64 Claudes were running simultaneously across multiple workflows. He also says a person watched the results and adjusted the workflows and instructions when problems were found. Bun’s explanation of the migration process

What does the 11-day period cover?

Bun’s 11 days covers the period from the initial porting work through the merge into main. Stable version 1.4 was not released that same day.

Existing tests also passed before the merge, but the Bun team says it subsequently found and fixed 19 known migration regressions. Passing tests is important evidence, but it does not mean the tests cover every real-world environment and failure.

There is a concrete example. The Bun team says that when a validation expression in Zig code was moved to Rust’s debug_assert!, a necessary side effect did not execute in release builds, breaking the refresh functionality of a particular development server. It shows how problems can arise when language execution semantics differ, even if syntax looks similar. Bun’s migration error example

“$165,000” is not the total project cost

Bun and Anthropic said that, priced at API rates, the tokens used for the pre-merge migration amounted to about $165,000. That figure is a conversion based on token usage within that scope.

It should not be read as a total cost that also includes the years of work spent developing Bun, human management and review, the computing environment, post-merge stabilization, and subsequent improvements. The estimated duration for a manual migration is also Bun’s creator’s estimate, not a value measured by having the same team actually perform the migration by hand. Anthropic’s explanation of migration costs

Does moving to Rust automatically make Bun safe?

Rust’s ownership and lifetime system helps reduce certain kinds of memory errors at compile time. Given the memory leaks, use-after-free errors, and lifetime management problems the Bun team repeatedly experienced, the reason for the migration is understandable.

But the name Rust alone does not prove the safety of an entire program.

Bun continues to use JavaScriptCore and other C and C++ libraries. Rust’s unsafe marks boundaries where the compiler does not automatically guarantee certain safety conditions, and the authors and reviewers of the code inside must uphold those conditions. The presence of unsafe does not immediately mean there is an error, nor does removing it mean all errors disappear.

The Bun team said that, when it wrote its migration account, about 4% of its Rust code was inside unsafe blocks. This percentage describes the code and counting criteria at that time; it is not a risk score for the whole current version. Bun’s explanation of `unsafe`

How much did performance change between the Zig and Rust versions?

The results below were published by the Bun team. They are not independently reproduced measurements, and each figure should be interpreted only in the context of its test and environment.

Startup time and memory

These are the hello.js measurements from the Bun 1.4 announcement.

EnvironmentMetricBun 1.3 seriesBun 1.4Node.js 26
LinuxStartup time10.9ms5.1ms27.2ms
LinuxPeak memory33.0MB14.6MB44.5MB
WindowsStartup time39.0ms15.5ms40.1ms
WindowsPeak memory46.5MB16.8MB32.5MB

The earlier Bun version in the Windows comparison was labeled 1.3.14, while the Linux table was labeled 1.3. Because this is a small startup test, its results do not directly represent long-running API servers, large builds, or real user response times. Bun 1.4 performance announcement

Server memory also fell, but the causes must be distinguished

The Bun team reported that in load tests, peak memory for Express fell from 169MB to 92MB, and for Fastify from 233MB to 120MB. Most tests sent 1 million requests over 64 connections; Next.js and Vite used 100,000 requests.

But the improvements described by the Bun team include changes to memory allocation in JavaScriptCore and Bun, along with garbage-collection-related optimizations. Therefore, one cannot say “memory fell by exactly this amount because of the switch to Rust.” Several changes arrived together as the version changed. Bun 1.4 memory measurements

Node.js, Deno, and Bun: What is different?

CategoryNode.jsDenoBun
JavaScript engineV8V8JavaScriptCore
General directionMature server runtime and npm ecosystemWeb standards, permission controls, and integrated toolsFast integrated runtime and Node.js compatibility
TypeScriptCheck the support and configuration of the current Node.js versionSupports running TypeScriptSupports running TypeScript and provides a separate bun check
Packages and testsnpm and various external toolsProvides package management and testing toolsBuilt-in tools such as bun install and bun test
Points to checkTool combinations depend on the version and project configurationCheck npm and Node compatibility for each projectCheck Node API and native module compatibility for each project

All three products continue to evolve, so the table is a starting point for choosing. In particular, being able to run TypeScript files and type checking an entire project are separate features.

Node.js benefits from long operational experience and a vast ecosystem. It provides a stable reference point for a service that already depends on a specific Node.js version and native modules.

Deno began with a focus on its permission model and web-standard APIs, but it is now also actively improving npm and Node.js compatibility. Its permission settings are worth examining in environments where scripts should run with limited permissions.

Bun combines installation, execution, testing, and bundling in one tool and has consistently placed strong emphasis on startup time and development tool speed. But installing a particular npm package is different from having every behavior match Node.js in production.

Competing benchmarks: Who is always faster?

The published measurements show that rankings change depending on the task.

One set of measurements published by Deno on its own site produced these results:

MeasurementDenoBunNode.js
RealWorld example throughput72,400 req/s68,200 req/s44,000 req/s
RealWorld p99 latency1.87ms2.80ms3.76ms
RealWorld peak memory64MB45MB116MB
TypeScript startup time19.6ms14.7ms50.0ms

The HTTP measurements are described as using an AMD EPYC x86_64, 100 concurrent connections, and the median of three runs. Startup time was measured on an Apple M5, using canary builds of Deno 2.9 and Bun 1.4 and the Node.js 26 series. The server and startup-time rows were not measured on the same machine. It should also be considered that these figures were published by Deno. Deno’s benchmarks and conditions

In the same Deno material, package installation results also varied with cache state. For the tested 18-package dependency tree, Deno took 598ms and Bun 766ms with a prepared cache, but 5.3 seconds and 4.9 seconds respectively with an empty cache. Installation scripts were disabled.

Rather than supporting a conclusion about “who always installs packages faster,” these numbers show which conditions must be recorded for a comparison to be meaningful. Results can change with the registry, network, lockfile, cache, disk, and installation scripts.

Comparing them in practice

For your own project, it is useful to measure these items separately:

  1. Development commands: Dependency installation, tests, type checking, and build time.
  2. Startup: Time from process start until it responds to the first request.
  3. Sustained throughput: Request count and CPU usage after sufficient warm-up.
  4. Latency distribution: Not just the average, but p95 and p99 latency.
  5. Memory: Peak usage and usage remaining after load ends.
  6. Compatibility: Authentication, databases, native modules, observability tools, and failure handling.

Record the runtime version, CPU, operating system, test code, number of connections, cache state, and number of repetitions as well, so the results can be compared with later measurements.

What is being built on Git after 1.4.4?

When checked on November 6, 2026, GitHub main was 90 commits ahead of the Bun 1.4.4 tag. The comparison used 1.4.4’s 38afee6 and the then-current main commit b1305dd.

The items below are development changes merged into main. The form in which they enter the next stable release may change before release. Compare 1.4.4 and main

1. Experimental AOT: Compiling TypeScript to machine code ahead of time

The most notable change is bun build --compile --aot. This experimental feature compiles JavaScript and TypeScript to machine code at build time to create a standalone executable. It also provides the shorter bun compile command.

In conventional JIT execution, frequently used code is optimized while the program runs. AOT compiles before execution, so it may reduce initial warm-up costs. The Bun team also describes a way to optimize some object accesses using TypeScript type information.

What makes Bun interesting is that it uses TypeScript type information for AOT machine-code optimization rather than simply erasing it. Well-defined TypeScript types can therefore increase a project's potential to benefit from AOT.

The key is the scope in which the compiler can establish types and actual object structure, rather than the number of type annotations. The Bun team describes using fixed field layouts and simple memory accesses where it can prove that only specific objects reach an access. Where it cannot, it retains checks and a slow path; annotations alone do not guarantee a speedup for every part of the code.

But it is not faster in every case. In a server test included in Bun’s PR, Express throughput during the first second was about 46,562 req/s with AOT and 24,181 req/s with JIT, but after sufficient warm-up it was 47,935 req/s with AOT and 51,587 req/s with JIT. Results for other frameworks in the same PR also differed.

The measurement was performed on an AMD EPYC 9R14 running Linux x64, with the server and load generator pinned to separate cores and 64 connections. These are the Bun team’s experimental results, not independently reproduced figures.

The current documentation marks AOT as experimental. It does not support cross-compilation, and breakpoints and step-by-step debugging in executables are also limited. AOT implementation PR and measurements

Why AOT matters for serverless, Lambda, and short-lived workers

AOT is a promising alternative for reducing cold-start overhead in serverless functions, AWS Lambda, and short-lived event or job workers. Preparing machine code before execution can reduce parsing and JIT warm-up work when a process starts. Compare time to first response, initial memory, and real task duration rather than only the peak throughput of a long-running server. This is an application-oriented interpretation of the Bun experiments above, not a Lambda benchmark measured for this article.

Deployment requirements matter. AWS Lambda can connect native executables through OS-only and custom runtimes, but the entry point and event/response processing through the Runtime API must be implemented. Initialization happens once per instance and can be reused for later invocations; not every request is a cold start. AWS Lambda custom runtime requirements

Here, worker means an execution unit handling events or queue jobs. Cloudflare Workers has a separate V8 isolate execution model, so this does not mean a Bun AOT executable can be deployed unchanged to every worker platform. Evaluate the alternative where native execution is allowed and the platform integration requirements can be met. How Cloudflare Workers works

2. bun lint: A move to include linting too

A change enabling bun lint, which was not included in 1.4.4, in release builds was merged into main. It also addresses behavior when an existing project has its own lint script and plugin compatibility.

Given that Bun already provides bun check and bun fmt, this suggests a direction toward combining development tools more broadly in one place, beyond the runtime. However, which settings and plugins behave the same way as an existing ESLint environment must be verified for each project. bun lint change PR

3. Reducing unsafe and replacing native dependencies

After 1.4.4, changes continued on main to reduce unsafe blocks in various areas by making Rust lifetimes and borrowing more explicit. These include the event loop, file system, networking, bundler, and package manager.

A change was also merged to remove the existing libarchive dependency and move tar reading and writing and gzip container handling to safe Rust code. The PR explains, however, that zlib is still used for DEFLATE processing. This means some components have moved to safe Rust; it does not mean C and C++ have disappeared from Bun altogether. Archive change PR

Community reaction: Both admiration and anxiety

Reactions broadly split in two directions.

Some praised the attempt to use an established codebase and extensive tests to carry out quickly a migration that would have been difficult for people to rewrite file by file. In particular, some said changing languages had become a far more realistic option than before.

Others worried about the reviewability of large amounts of AI-generated code, unsafe boundaries, and long-term maintenance costs. The inputs covered by tests can differ from those encountered in real production use. Discussion in the Rust community

These posts are examples of individual opinions in the community. They cannot be taken as representing the proportion of supporters and opponents or developer opinion as a whole.

Believe it or not: Behind-the-scenes stories circulating in the community

“Did Anthropic tell Bun to switch to Rust because of Zig’s AI policy?”

Confirmed facts: Anthropic acquired Bun, and Bun used Claude to carry out the Rust port. Differences of opinion concerning the relationship between the Zig community and Bun, and the use of AI, also became public.

Unconfirmed: Public evidence alone cannot establish a causal link that Anthropic ordered the language migration after the acquisition because of Zig’s AI policy. The technical reasons Bun’s creator officially gave were recurring memory safety problems and maintenance burden. The fact that two events followed each other must be distinguished from the decisive motivation for the migration. Bun’s explanation, Anthropic’s acquisition announcement

“Was Zig’s creator angry that Bun left?”

This too is difficult to summarize in a single sentence. In a public post, Zig creator Andrew Kelley strongly criticized Bun’s code quality and the relationship between the projects, and wrote to the effect that he was instead glad about the Rust migration.

Kelley argued that some of Bun’s performance and binary size improvements could have come from engineering work separate from the language change. Sumner, meanwhile, expressed gratitude that Zig made the initial Bun possible, while citing Bun’s memory management problems as a reason for the migration.

The two posts are the perspectives of the respective parties. Neither account alone can establish the full history of the relationship or the technical causal links. Kelley’s response, Sumner’s migration explanation

“Did Claude complete one million lines alone in 11 days?”

Bun said the merged change added about one million lines and that the initial work took 11 days. But the existing Zig code and tests were the product of years of human work, and people created instructions and observed the work during the migration. Regression fixes and stabilization continued after the merge.

Thus, 11 days is the initial porting period for an impressive amount of work, but it is not a number that erases the existing project’s accumulated work or all the work required to reach a stable release. Bun’s work statistics

“Has Zig Bun disappeared entirely?”

Official Bun stable releases have moved to a Rust base, but community forks have appeared that aim to carry on the Zig-based code. For example, Cruller describes itself as a derivative of Bun. The existence of a fork and its ability to continue delivering features and security fixes at the same pace as official Bun are separate matters. Cruller repository

So should you switch to Bun now?

If fast installation and integrated tools matter for a new project, Bun is well worth trying. For an existing Node.js project, it is better to compare package installation, testing, the development server, and the production server separately rather than replacing the entire runtime at once.

In particular, areas where failures affect production—such as database drivers, TLS settings, native add-ons, worker threads, and monitoring tools—need to be checked using the project’s tests and load conditions. Bun’s official compatibility improvements are welcome, but they do not automatically guarantee compatibility with your service’s dependencies.

Bun’s Zig-to-Rust migration leaves a more interesting question than who won a language war. When AI makes it possible to perform a large migration quickly using existing code and tests, what should a development team verify first, and what evidence should it use to decide on a release?

Part of the answer is already visible in Bun’s case. Code that describes existing behavior, sufficient tests, human judgment, and fixes after real-world production use were all necessary. And, as the AOT experiment on the latest main shows, Bun’s next competitive challenge continues even after the migration.

Sources & Verification Date

  1. Bun releases · Verified
  2. Bun: Rewriting Bun in Rust · Verified
  3. Anthropic’s December 2025 announcement · Verified
  4. Bun blog · Verified
  5. Bun 1.4 announcement · Verified
  6. Bun 1.4.1 · Verified
  7. Bun 1.4.2 · Verified
  8. Bun 1.4.3 announcement and measurement conditions · Verified
  9. Bun 1.4.4 release notes · Verified
  10. Anthropic’s explanation of migration costs · Verified
  11. Deno’s benchmarks and conditions · Verified
  12. Compare 1.4.4 and main · Verified
  13. AOT implementation PR and measurements · Verified
  14. bun lint change PR · Verified
  15. Archive change PR · Verified
  16. Discussion in the Rust community · Verified
  17. Kelley’s response · Verified
  18. Cruller repository · Verified
  19. AWS Lambda custom runtime requirements · Verified
  20. How Cloudflare Workers works · Verified