Bun 1.4가 출시됐다.
릴리스 자체만 보면 축하할 만하다. 성능은 개선됐고, 메모리 사용량은 줄었으며, Node.js 호환성도 더 좋아졌다. 패키지 매니저와 테스트 러너도 계속 성숙하고 있다.
그리고 무엇보다 Bun의 핵심 코드베이스가 Zig에서 Rust로 옮겨졌다.
Bun 팀에 따르면 기존 약 53만 줄의 Zig 구현을 기반으로 한 Rust 포트는 단 11일 만에 모든 지원 플랫폼에서 기존 테스트 스위트를 통과했다. 최종적으로 main에 들어간 diff는 약 100만 줄에 달했다.
그 자체만 보면 놀라운 기술적 성과다.
나 역시 Bun을 좋아하고, Bun 1.4가 잘 나온 것은 기쁘다.
그런데 이번 릴리스를 보면서 이전 버전들처럼 마음 편하게 bun upgrade를 누르고 싶다는 생각은 들지 않았다.
Rust가 싫어서가 아니다.
Zig를 계속 써야 한다고 생각해서도 아니다.
AI가 코드를 작성했다는 사실 자체가 문제라고 생각하는 것도 아니다.
내가 의문을 갖게 된 것은 이 정도로 거대한 변경을 어떤 과정으로 검증했고, 무엇을 근거로 불과 11일 만에 기존 구현을 대체할 미래의 코드베이스로 결정했는가다.
그리고 이 질문은 Rust rewrite가 시작된 시점보다 조금 전으로 거슬러 올라가야 제대로 이해할 수 있다.
Rust 이전에 이미 시작된 Bun과 Zig의 균열
Bun은 오랫동안 Zig를 대표적으로 사용하는 대형 프로젝트 중 하나였다.
하지만 Rust 포트가 시작되기 전부터 Bun은 upstream Zig 대신 자체 Zig compiler fork를 사용하고 있었다.
Bun 팀은 AI를 활용해 semantic analysis를 병렬화하고 LLVM code generation을 여러 단위로 나누는 등의 변경을 적용했으며, 이를 통해 Bun의 debug build가 약 4배 빨라졌다고 주장했다. 문제는 이 변경을 Zig upstream에 그대로 보내기 어려웠다는 점이다. Zig 프로젝트는 issue, pull request, bug tracker comment 등에 LLM으로 작성된 기여를 받지 않는 강한 정책을 유지하고 있었기 때문이다.
그렇다고 이 사건을 단순히
“Zig가 AI가 작성했다는 이유만으로 좋은 패치를 거부했다”
고 설명하는 것도 정확하지 않다.
Zig 측에서는 Bun fork의 변경 자체에도 기술적인 이견을 제기했다. parallel semantic analysis가 비결정적인 동작을 일으킬 수 있다는 점, LLVM backend를 여러 module로 나누는 방향보다 Zig가 추진하고 있는 incremental compilation이 장기적으로 더 적합하다는 점 등이 언급됐다. 즉 AI 기여 정책과 별개로 해당 구현을 upstream하고 싶지 않다는 입장이었다.
이 시점에서 두 프로젝트 사이에는 적어도 두 가지 충돌이 있었다.
하나는 AI를 소프트웨어 개발에 어디까지 사용할 것인가에 대한 철학의 차이였고, 다른 하나는 compiler를 어떤 방향으로 발전시킬 것인가에 대한 기술적 차이였다.
Bun 입장에서는 자체 Zig fork를 계속 관리해야 하는 상황이 된 셈이다.
그리고 얼마 지나지 않아 선택지가 완전히 달라졌다.
Zig compiler를 계속 고치는 대신 Bun 자체를 Rust로 옮기는 실험이 시작됐다.
처음에는 정말 ‘실험’이라고 했다
2026년 5월 5일, Rust 포트가 알려지기 시작했을 당시 Jarred Sumner의 설명은 상당히 조심스러웠다.
아직 rewrite를 결정하지 않았고, 지금 작성하고 있는 코드가 전부 버려질 가능성도 높으며, 일단 동작하는 Rust 버전이 어떤 모습이고 어떤 느낌인지 확인해보고 싶다는 취지였다.
그 설명만 보면 충분히 이해할 만하다.
AI가 대규모 포팅을 어느 정도까지 수행할 수 있는지 알아보기 위한 실험적인 branch를 만드는 것은 흥미로운 시도다. 성공하지 않으면 버리고, 유용한 부분만 연구 자료로 남길 수도 있다.
문제는 그 이후의 속도다.
Bun 팀의 공식 회고에 따르면 Rust rewrite는 5월 3일 시작됐고, 5월 14일 main에 병합됐다.
11일이었다.
Jarred 역시 처음에는 Anthropic의 새 모델을 가지고 일주일 정도 rewrite 가능성을 시험해볼 생각이었다고 회고한다. 그러나 며칠 만에 높은 비율의 테스트가 통과하고 Rust 코드가 기존 Zig 구현을 상당히 충실하게 따라가는 것을 보면서 생각이
“해볼 만하다”
에서
“이걸 merge하겠다”
로 바뀌었다고 직접 설명한다.
결과적으로 “전부 버릴 가능성도 높다”고 공개적으로 설명했던 시점에서 불과 약 9일 뒤, Rust 구현은 Bun의 main branch로 들어갔다. 당시 병합된 diff는 약 100만 줄이었다.
사람의 판단이 바뀌는 것 자체는 문제가 아니다.
실험 결과가 기대 이상이었다면 계획이 빠르게 바뀔 수도 있다.
따라서 당시 발언을 의도적인 거짓말이었다고 단정할 생각은 없다.
하지만 사용자 입장에서 보면 “아직 단순한 실험이며 버릴 가능성이 높다”는 커뮤니케이션과 며칠 후 프로젝트의 미래 구현으로 확정한 결정 사이에는 상당히 큰 간극이 있다.
그리고 인프라 프로젝트를 신뢰할 때는 코드만큼 이런 의사결정 과정도 중요하다.
11일 만에 만들었다는 것보다, 11일 만에 결정했다는 것이 더 놀랍다
나는 AI가 100만 줄의 코드를 11일 만에 작성했다는 사실 자체보다 다른 부분이 더 놀랍다.
그 구현을 앞으로 Bun이 유지할 본선 코드베이스로 삼겠다는 결정을 11일 안에 내렸다는 것이다.
Bun 팀은 이 rewrite를 아무 생각 없이 프롬프트 하나 던져놓고 만든 것은 아니다.
약 50개의 Claude Code dynamic workflow를 운영했고, 한 workflow 안에서도 구현 담당 Claude와 별도의 adversarial reviewer들을 분리했다. 리뷰 모델에는 구현 모델의 reasoning을 넘기지 않고 diff만 보여주며 문제가 있다고 전제하고 버그를 찾도록 했다. 최대 약 64개의 Claude가 동시에 작업했다고 한다.
이건 꽤 흥미로운 접근이다.
앞으로 AI를 이용해 대규모 코드를 작성할 때 참고할 가치가 있는 실험이라고 생각한다.
하지만 아무리 좋은 자동화 체계를 만들었더라도 11일 동안 확인하기 어려운 것들이 있다.
예를 들어:
- 실제 workload에서만 발생하는 race condition
- 드문 FFI lifetime 문제
- 장시간 실행 후의 메모리 상태
- 특정 OS와 파일 시스템에서만 발생하는 edge case
- 테스트가 존재하지 않는 기존 동작
unsafeabstraction의 soundness- 유지보수 과정에서 새로운 개발자가 코드를 이해하기 쉬운지
- 수개월 뒤 기능을 수정할 때 새 구조가 실제로 더 안전한지
같은 것들이다.
이것들은 단순히 테스트가 초록색이 되었다고 답할 수 있는 질문이 아니다.
Bun 팀 역시 main에 병합한 것이 곧바로 stable release를 의미한 것은 아니라고 분명히 말한다.
모든 플랫폼에서 테스트가 100% 통과하고 실제로 테스트가 skip되지 않았는지 확인한 후 병합했지만, 당시에는 **“rewrite에 commit할 정도의 자신감은 있었지만 release할 정도는 아니었다”**고 설명한다.
그 구분은 중요하다.
하지만 동시에 내 의문도 바로 거기에 있다.
stable release는 아직 아니었더라도, 기존 Zig 구현 대신 Rust 구현을 앞으로 가져가겠다는 전략적인 결정은 이미 내려진 것이기 때문이다.
테스트 100% 통과는 무엇을 증명하는가
Rust rewrite를 신뢰할 가장 강력한 근거로 제시된 것은 기존 Bun의 대규모 테스트 스위트였다.
병합 당시 Bun 팀이 공개한 수치를 보면 Linux에서는 약 6만 개의 테스트와 138만 개 이상의 expect() 호출이 실행됐다. macOS와 Windows에서도 각각 수만 개의 테스트가 통과했다. 테스트를 삭제하거나 skip하지 않았다고도 강조했다.
이건 굉장히 중요한 자산이다.
언어에 독립적인 대규모 TypeScript 테스트 스위트가 있었기 때문에 53만 줄이 넘는 구현을 다른 언어로 기계적으로 옮겨도 동작의 상당 부분을 비교할 수 있었다.
그러나 여기에는 한 가지 중요한 한계가 있다.
테스트가 100% 통과한다는 것은
우리가 이미 알고 있고 테스트로 표현한 동작에 대해 새 구현이 기대 결과를 낸다
는 강한 증거다.
그것이
우리가 아직 모르는 문제가 새 구현에 존재하지 않는다
는 증거는 아니다.
특히 이 부분은 Bun이 Rust로 옮긴 이유와 연결하면 더 흥미롭다.
Bun은 기존 Zig 구현에서 use-after-free, double-free, error path에서의 memory leak, GC와 수동 메모리 관리 사이의 lifetime 문제 등을 지속적으로 겪었다고 설명한다. Bun 1.3.14에서 수정한 사례만 공식 글에 긴 목록으로 정리돼 있다.
그렇다면 자연스럽게 질문이 하나 생긴다.
그 버그들이 기존 테스트에서 사전에 발견되지 않았다면, 같은 테스트가 새로운 100만 줄의 구현에 존재할 수 있는 새로운 종류의 버그를 얼마나 보증할 수 있을까?
Zig 창시자 Andrew Kelley의 비판에는 개인적인 갈등과 공격적인 표현이 상당히 섞여 있다. 나는 그의 글 전체를 그대로 받아들일 필요는 없다고 생각한다.
하지만 그가 제기한 이 질문 자체는 피하기 어렵다.
기존 구현의 안정성 문제를 설명하면서 동시에 같은 테스트 스위트를 거대한 새 구현을 신뢰하는 핵심 근거로 삼는 것이 충분한가.
내 생각에 답은 **“필요하지만 충분하지 않다”**에 가깝다.
AI가 작성하고 AI가 리뷰했다
검증 과정에서 또 하나 생각해볼 부분은 작성과 리뷰의 독립성이다.
Bun은 Claude가 작성한 변경을 다른 context의 Claude들에게 adversarial review하도록 했다.
구현을 맡은 Claude에는 기존 Zig 코드, 포팅 가이드, 자신의 reasoning 등이 있었지만, 리뷰하는 Claude에게는 diff를 중심으로 제공하고 “이 코드가 잘못됐다고 가정하고 문제를 찾아라”라는 식으로 역할을 분리했다. Bun 팀은 이 과정이 실제로 merge 전에 여러 문제를 찾아냈다고 설명한다.
이건 단순 self-review보다 분명 낫다.
그러나 이것을 인간 개발자 여러 명이 완전히 독립적으로 검증하는 것과 동일하게 볼 수 있을지는 모르겠다.
context를 분리하면 구현자가 자신의 해결책을 정당화하려는 편향은 줄어들 수 있다.
하지만 같은 모델 계열이 공통적으로 가지고 있는 blind spot까지 사라지는 것은 아니다.
특히 시스템 프로그래밍에서는 한 번의 잘못된 lifetime 가정이나 FFI boundary의 실수가 테스트에서는 잘 드러나지 않다가 특수한 조건에서만 심각한 문제로 나타날 수 있다.
AI가 코드를 작성하면 안 된다는 이야기가 아니다.
오히려 반대다.
AI가 인간보다 압도적으로 빠른 속도로 거대한 변경을 만들어낼 수 있다면, 검증 과정도 그 속도에 맞춰 더 강해져야 한다.
작성 속도만 100배 빨라지고 검증 기준은 그대로라면, 우리는 안전한 코드를 100배 빨리 만드는 것이 아니라 단순히 검토해야 할 위험을 100배 빨리 만들어낼 수도 있다.
그리고 merge 당일 Miri가 문제를 찾았다
이 우려를 상징적으로 보여준 사건도 있었다.
Rust rewrite가 main에 병합된 바로 그날, 새 Rust 코드가 기본적인 Miri 검사에서 undefined behavior를 발생시키며 safe API를 통해 dangling reference가 만들어질 수 있다는 GitHub issue가 올라왔다.
Bun 측도 이를 재현했고, 문제가 된 API를 unsafe로 변경하고 call site를 audit하는 등의 수정 작업을 진행했다.
이 사건 하나만 가지고 전체 rewrite가 잘못됐다고 말할 수는 없다.
오히려 Rust와 Miri가 이런 문제를 발견할 수 있었기 때문에 Rust 전환의 장점이 드러난 사례라고도 볼 수 있다.
하지만 타이밍은 의미가 있다.
모든 기존 테스트가 통과한 상태에서 main에 병합했지만, 그 테스트와 AI adversarial review가 잡지 못한 soundness 문제가 병합 당일 별도의 검증 도구를 통해 발견됐다.
즉 기존 테스트가 초록색이라는 것과 새 구현의 안전성 검증이 완료됐다는 것은 실제로 다른 문제였다.
Bun 팀도 이후 Miri를 CI의 더 많은 코드에 적용하기 시작했다.
오히려 나를 안심시키는 것은 ‘11일’ 이후의 작업이다
여기까지 쓰면 마치 Bun이 11일 동안 AI가 만든 코드를 그대로 1.4로 출시한 것처럼 들릴 수도 있다.
그건 사실과 다르다.
그리고 이 부분은 반드시 공정하게 평가해야 한다.
5월 14일 main에 병합한 뒤 Bun 팀은 추가적인 검증을 상당히 많이 진행했다.
공식 회고에 따르면:
- Claude Code Security를 이용한 11차례의 security review
- JavaScript, TypeScript, CSS, JSON, TOML, YAML, Markdown 등 parser에 대한 24/7 coverage-guided fuzzing
- 당시까지 약 1,000억 회의 parser fuzz 실행
- LeakSanitizer 개선
- CI에서 점차 확대되고 있는 Miri
- Rust port로 생긴 것으로 파악된 19개의 알려진 regression 수정
등을 수행했다.
또 당시 전체 Rust 코드 약 78만 줄 중 약 2만 7천 줄이 unsafe block 안에 있었고, Bun 팀은 기계적인 Zig 포트에서 점차 idiomatic Rust로 refactor하면서 이를 줄이겠다고 밝혔다. JavaScriptCore 등 C/C++ 라이브러리와의 연결 때문에 unsafe가 완전히 사라질 수는 없다고도 설명했다.
실서비스 검증도 있었다.
Prisma Compute의 public beta가 Rust rewrite 기반 Bun을 사용했고, Claude Code 역시 6월 17일 출시된 v2.1.181부터 Rust 포트를 사용했다. Bun 팀은 Claude Code에서는 Linux startup이 약 10% 빨라진 것 외에는 대부분의 사용자가 변화를 눈치채지 못했다고 설명한다.
내가 Bun 1.4에 대해 어느 정도 안심할 수 있는 이유는 사실 이쪽이다.
11일 만에 rewrite를 만들었다는 사실보다 그 이후 수개월 동안 실제로 검증하고, 문제를 찾고, 고친 시간이 있었기 때문이다.
아이러니하게도 이것은 동시에 처음의 의문을 더 크게 만든다.
그만큼 많은 추가 검증이 실제로 필요했다면,
왜 Rust rewrite 자체에 commit하겠다는 결정은 11일 만에 내려도 충분하다고 판단했을까?
결과가 좋으면 과정도 옳았던 것일까
현재까지 결과만 보면 Bun 팀의 선택은 꽤 성공적인 것으로 보인다.
Bun 1.4의 공식 벤치마크에서는 HTTP workload와 build workload가 대체로 2~5% 정도 빨라졌고, 메모리 사용량과 binary size도 개선됐다. 이전 Zig 버전에서 재현되는 여러 메모리 누수와 안정성 문제도 해결했다고 한다.
Rust로의 전환 자체도 기술적으로 충분히 이해할 수 있다.
Bun은 JavaScriptCore라는 GC 기반 런타임과 수동 관리 native memory를 동시에 다뤄야 한다. 이런 환경에서는 Drop, ownership, borrow checker처럼 resource lifetime을 언어 수준에서 표현하고 검사할 수 있는 기능이 분명 매력적이다. Bun 팀이 왜 Rust를 선택했는지도 이해된다.
그러나 결과가 좋았다는 사실과 당시의 의사결정 과정이 충분히 보수적이었다는 것은 같은 명제가 아니다.
위험한 결정을 했는데 결과적으로 성공할 수도 있다.
아주 보수적인 결정을 했는데도 실패할 수도 있다.
그래서 인프라 소프트웨어를 평가할 때는 최종 binary만 볼 것이 아니라 프로젝트가 큰 변경을 어떤 방식으로 결정하고 검증하는지도 봐야 한다고 생각한다.
이것은 Zig 대 Rust의 이야기가 아니다
이번 사건은 쉽게 언어 전쟁으로 흐른다.
Zig를 좋아하는 쪽에서는 Rust rewrite를 공격하고, Rust를 좋아하는 쪽에서는 기존 Zig 코드의 버그를 근거로 rewrite가 당연했다고 주장한다.
하지만 내가 궁금한 것은 어느 언어가 더 좋은가가 아니다.
Rust로 옮기는 것 자체는 충분히 합리적인 선택일 수 있다.
그렇다고 Rust라는 언어가 자동으로 sound한 프로그램을 만들어주는 것도 아니다. Bun처럼 C와 C++ 라이브러리를 대량으로 연결하는 프로젝트에서는 unsafe와 FFI가 계속 필요하다.
반대로 Zig를 사용한다고 반드시 메모리 버그가 발생하는 것도 아니다. Bun 역시 공식 회고에서 자신들이 겪은 문제를 Zig 자체의 잘못으로 돌리지 않았다.
결국 안정성은 언어 하나로 결정되지 않는다.
언어, 구현, 테스트, static analysis, fuzzing, code review, 실제 workload, 배포 경험 그리고 프로젝트의 개발 문화가 모두 합쳐진 결과다.
이것은 AI 대 인간의 이야기도 아니다
나는 AI가 작성한 코드이기 때문에 Bun 1.4를 신뢰하지 못하겠다고 말하고 싶은 것도 아니다.
오히려 이번 rewrite는 소프트웨어 개발 방식이 정말로 달라졌다는 강력한 사례다.
기존 방식이었다면 숙련된 개발자 몇 명이 1년 가까이 걸릴 것으로 예상한 작업을 한 명의 엔지니어와 여러 AI agent가 11일 만에 기존 테스트가 전부 통과하는 수준까지 가져갔다.
이 가능성을 무시하는 것도 현실적이지 않다.
앞으로 이런 사례는 더 많아질 것이다.
그렇기 때문에 지금 필요한 논의는
“AI가 코드를 써도 되는가?”
보다는
“AI가 인간의 검토 능력을 훨씬 넘어서는 속도로 코드를 생산할 때, 무엇을 근거로 그 결과를 신뢰할 것인가?”
에 가깝다고 생각한다.
100만 줄짜리 diff는 인간 몇 명이 며칠 동안 line-by-line review할 수 있는 크기가 아니다.
앞으로 소프트웨어 엔지니어링에서는 테스트, fuzzing, formal verification, sanitizer, differential testing, production canary처럼 코드를 읽지 않고도 시스템의 특성을 검증할 수 있는 방법이 지금보다 훨씬 중요해질 것이다.
Bun은 어쩌면 그 문제를 남들보다 먼저 겪고 있는 프로젝트일지도 모른다.
신뢰는 테스트 결과 하나로 만들어지지 않는다
내가 Bun 1.4를 보며 가장 크게 느낀 것은 이것이다.
소프트웨어의 신뢰는
“테스트 100% 통과”
라는 숫자 하나에서 나오지 않는다.
특히 런타임이나 compiler처럼 수많은 프로젝트의 기반이 되는 인프라는 더 그렇다.
사용자가 신뢰하는 것은 코드뿐 아니라
- 큰 변경을 결정하는 기준
- 위험을 설명하는 방식
- 검증 방법의 한계를 인정하는 태도
- 문제가 발생했을 때 처리하는 과정
- 충분한 canary 기간
- 실제 production workload에서 쌓인 시간
까지 포함한다.
그런 의미에서 나는 Rust rewrite 직전의 커뮤니케이션이 아쉽다.
며칠 전까지 “전부 버릴 가능성도 높다”고 설명했던 프로젝트가 불과 며칠 뒤 사실상 방향을 확정했다면, 적어도 무엇이 그 짧은 시간 동안 판단을 그렇게 크게 바꾸었고, 왜 그 증거가 충분하다고 생각했는지 더 조심스럽게 설명할 필요가 있었다고 생각한다.
그래도 Bun 1.4는 축하할 만한 릴리스다
이 모든 의문에도 불구하고 Bun 1.4 자체가 인상적인 릴리스라는 생각은 변하지 않는다.
결과적으로 Rust rewrite는 살아남았고, 수개월 동안 추가 검증을 거쳤으며, 실제 제품에 먼저 배포됐다.
그리고 1.4는 더 빠르고, 더 작고, 여러 기존 버그를 수정했다.
Bun 팀의 실험이 성공한다면 앞으로 대규모 소프트웨어 migration을 바라보는 방식 자체가 달라질 수도 있다.
그래서 더 흥미롭고, 동시에 더 조심해서 보고 싶다.
내가 이번 일을 보며 갖게 된 의문은
“AI가 만든 Bun을 믿을 수 있는가?”
가 아니다.
더 정확히는 이렇다.
코드를 만드는 속도가 검증할 수 있는 속도를 압도하기 시작한 시대에, 프로젝트는 언제 ‘이제 충분히 검증됐다’고 판단해야 하는가?
그리고 또 하나.
“잘 동작하는 실험”이 “프로젝트의 미래를 맡겨도 되는 구현”이 되는 경계는 어디인가?
Bun은 11일 만에 그 경계를 넘었다고 판단했다.
결과적으로 그 결정이 옳았을 수도 있다.
하지만 1.4가 성공적으로 출시됐다는 사실만으로 당시 그 판단 과정까지 자동으로 옳았다고 생각하고 싶지는 않다.
나는 앞으로도 Bun을 사용할 것 같다.
다만 이번에는 새 버전이 나왔다는 이유만으로 바로 올리기보다 몇 번의 patch release와 실제 사용자들의 경험을 조금 더 지켜볼 생각이다.
Bun의 성능을 의심하게 된 것은 아니다.
Rust라는 선택을 의심하는 것도 아니다.
내가 다시 확인하게 된 것은 Bun이라는 프로젝트가 큰 결정을 내리는 방식에 대한 신뢰다.
그리고 지금처럼 AI가 소프트웨어 개발 속도를 급격하게 바꾸고 있는 시기에는, 어쩌면 그 문제가 언어 선택보다 훨씬 중요한 문제인지도 모르겠다.