Bun이 11일 만에 Rust로 갈아탔다 — 53만 줄 재작성의 전말
자바스크립트 런타임 하나가 언어를 통째로 갈아탔다
Bun이 Zig로 작성돼 있던 535,496줄을 Rust로 재작성했다고 2026년 7월 8일 공식 블로그에서 발표했습니다. 부분 교체가 아니라 런타임 본체를 언어 단위로 옮긴 것입니다.
숫자부터 보면 규모가 짐작됩니다.
| 항목 | 값 |
|---|---|
| 포팅된 코드 | 535,496줄 (Zig → Rust) |
| 소요 기간 | 11일 (2026-05-03 ~ 05-14) |
| 커밋 수 | 6,502개 (최대 1시간에 695개 — 5/6 10~11시 PDT) |
| 테스트 통과 | 6개 플랫폼, 약 6만 개 전부 통과 (스킵 0) |
| Zig 마지막 버전 | v1.3.14 |
| Rust 첫 버전 | v1.4.0 (현재 카나리) |
여기서 대부분의 개발자가 먼저 멈추는 지점은 “11일”입니다.
사람이 쓴 게 아니다
이 재작성은 손으로 한 작업이 아닙니다. Bun 개발자 Jarred Sumner는 이렇게 적었습니다.
> “I rewrote Bun in Rust using about 50 dynamic workflows in Claude Code run continuously over the course of 11 days.”
Claude Code 워크플로 약 50개를 11일간 쉬지 않고 돌렸고, API 비용만 약 16만 5천 달러가 들었습니다. 배경도 함께 공개됐는데, Bun은 2025년 12월 Anthropic에 인수됐고 Bun 팀은 현재 Anthropic 소속입니다. 재작성에는 정식 출시 전 버전의 Claude Fable 5가 쓰였습니다.
즉 이 사건은 “언어를 바꾼 이야기”인 동시에 에이전트가 실제 프로덕션 코드베이스를 어디까지 옮길 수 있는지에 대한 실측 사례입니다. 53만 줄짜리 시스템 소프트웨어를 옮기고, 테스트를 초록불로 유지한 채 병합까지 끝냈다는 점이 핵심입니다. 자기 테스트도 통과 못 하는 재작성은 실험이지만, 테스트를 유지한 재작성은 기반이 됩니다.
왜 Zig를 떠났나 — 성능이 아니라 메모리 안전성
목적은 속도가 아니었습니다. 발표문이 지목한 것은 Zig에서 반복해서 나온 버그 유형입니다.
> “use-after-free, double-free, and ‘forgot to free’ in an error path. In safe Rust, these are compiler errors”
해제된 메모리를 다시 참조하거나, 두 번 해제하거나, 에러 처리 분기에서 해제를 빠뜨리는 문제입니다. 세 가지 모두 런타임에야 드러나고 재현이 어려운 부류입니다. 안전한 Rust에서는 이것들이 컴파일 단계에서 걸립니다. 버그를 잘 잡는 쪽으로 바꾼 게 아니라, 그 버그가 존재할 수 없는 영역을 넓힌 것입니다.
이 선택은 백엔드 언어를 고를 때 흔히 하는 TypeScript·Rust·Go 비교의 판단 기준과도 맞물립니다. 런타임처럼 수명이 길고 실패 비용이 큰 소프트웨어일수록, 컴파일러가 강제하는 안전성의 가치가 실행 속도 몇 퍼센트보다 큽니다.
전략은 “트랜스파일한 것처럼 옮겨라”
대규모 재작성이 실패하는 전형적인 이유는 옮기면서 설계까지 손대는 것입니다. Bun은 그 유혹을 명시적으로 차단했습니다.
> “Do the rewrite that looks like we transpiled our Zig code to Rust”
구조를 유지한 기계적 포팅을 먼저 끝내고, 리팩터링은 v1.4 이후로 미뤘습니다. 덕분에 “동작이 같은가”만 검증하면 되는 상태가 유지됐고, 6만 개 테스트가 판정 기준으로 그대로 쓰일 수 있었습니다. 옮기기와 고치기를 한 번에 하지 않는다는 원칙은 규모와 무관하게 유효합니다.
성능은 덤, 진짜 소득은 메모리
가장 극적인 수치는 여기입니다. 2,000회 빌드 기준 메모리 사용량이 6.7GB에서 609MB로 떨어졌습니다. 누수를 제거한 결과입니다. 장시간 돌아가는 빌드 서버나 CI에서 체감이 큰 종류의 개선입니다.
– HTTP 처리량: +2.8~4.8%
– 애플리케이션 성능: +2.2~4.7%
– 바이너리 크기: 약 20% 감소 (Linux/Windows)
성능 향상 폭은 오차 범위를 조금 넘는 수준입니다. 언어를 바꾼다고 실행 속도가 극적으로 뛰지는 않는다는 점을 그대로 보여줍니다.
사용자는 눈치채지 못했다
이미 실사용 중이라는 점도 공개됐습니다. Claude Code v2.1.181부터 Rust 기반 Bun이 들어가 있습니다. 그 결과에 대한 평가는 이렇습니다.
> “Startup got 10% faster on Linux but otherwise, barely anyone noticed. Boring is good.”
리눅스에서 시작 속도가 10% 빨라진 것 외에는 아무도 눈치채지 못했다는 것이고, 인프라 교체에서는 그게 성공의 정의입니다.
남은 과제 — unsafe 영역과 카나리 단계
낙관만 할 상황은 아닙니다.
– 남아 있는 unsafe: Rust 코드의 약 4%가 unsafe 블록 안에 있습니다(약 78만 줄 중 unsafe 키워드 약 1만 3천 개가 약 2만 7천 줄에 걸쳐 있음). 안전 영역이 넓어졌을 뿐 경계는 남아 있습니다.
– 회귀 버그 19건: 발견돼 모두 수정됐지만, 그만큼 기계적 포팅에도 틈이 생긴다는 뜻입니다.
– 검증 물량: 보안 검토 11회, 퍼징 1,000억 회 실행으로 약 15개 PR이 나왔습니다.
– 아직 카나리: v1.4.0은 정식 릴리스 전입니다.
지금 무엇을 하면 되나
프로덕션에서 Bun을 쓰고 있다면 서두를 이유는 없습니다. 안정판(v1.3.x)을 유지하고, 정식 릴리스 시점에 맞춰 검증하는 쪽이 안전합니다. 미리 확인하고 싶다면 카나리로 받아 CI에서만 돌려보는 정도가 적당합니다.
bun upgrade --canary
주목할 지점은 오히려 방법론 쪽입니다. “레거시를 다른 언어로 옮기는 일”의 비용 구조가 바뀌고 있다는 실측치가 처음 공개된 사례이기 때문입니다. 11일과 16만 5천 달러라는 숫자는, 지금까지 “현실적으로 불가능”으로 분류돼 있던 마이그레이션들을 다시 계산해볼 근거가 됩니다. 다만 그 전제는 Bun이 갖고 있던 조건 — 6만 개짜리 테스트 스위트입니다. 판정할 수단이 없으면 속도는 의미가 없습니다.
—
참고 자료
– Rewriting Bun in Rust — Bun 공식 블로그 (2026-07-08)
자주 묻는 질문
Bun을 Rust로 다시 짠 이유가 뭔가요?
메모리 안전성 때문입니다. Zig에서는 use-after-free, double-free, 에러 경로에서의 해제 누락 같은 버그가 런타임에야 드러났는데, 안전한 Rust에서는 이런 것들이 컴파일 에러로 잡힙니다. 성능을 올리려고 바꾼 게 아니라 버그 계층 하나를 통째로 없애려고 바꾼 것입니다.
지금 쓰는 Bun에 바로 영향이 있나요?
아직은 없습니다. Zig 기반 마지막 버전이 v1.3.14이고, Rust 기반 첫 버전인 v1.4.0은 카나리 채널에 있습니다. 정식 릴리스 전까지는 기존 안정판을 그대로 쓰면 됩니다. 미리 확인하려면 bun upgrade –canary로 받아볼 수 있습니다.
재작성 후 성능이 크게 좋아졌나요?
체감할 만큼은 아닙니다. HTTP 처리량 2.8~4.8%, 애플리케이션 성능 2.2~4.7% 개선 수준입니다. 오히려 의미 있는 변화는 바이너리 크기 약 20% 감소와 메모리 누수 제거입니다. 2,000회 빌드 기준 메모리 사용량이 6.7GB에서 609MB로 줄었습니다.
Rust로 옮겼으면 이제 메모리 버그는 없는 건가요?
아닙니다. Rust 코드의 약 4%는 여전히 unsafe 블록 안에 있습니다. 약 78만 줄 중 unsafe 키워드가 약 1만 3천 개, 약 2만 7천 줄에 걸쳐 있습니다. 안전한 영역이 크게 늘어난 것이지 전부 사라진 것은 아니라서, unsafe 경계에 대한 검증은 계속 필요합니다.
11일 만에 53만 줄을 옮기는 게 가능한가요?
사람이 손으로 한 게 아닙니다. Claude Code 워크플로를 약 50개 동시에 돌려서 11일 연속으로 진행했고, 커밋이 6,502개 쌓였습니다(가장 많이 몰린 1시간에 695개). API 비용만 약 16만 5천 달러가 들었습니다.
