Zig 개발자가 이 상황을 매우 불편해하는 이유... (Bun에서 Rust로)

BBetter Stack
컴퓨터/소프트웨어창업/스타트업경영/리더십

스크립트

00:00:00Bun은 불과 11일 만에 전체 코드베이스를 Zig에서 Rust로 재작성했으며, 곧 이 버전이 정식 출시될 예정입니다.
00:00:06그 자체로도 놀라운 이야기지만, Zig의 창시자인 앤드류 켈리(Andrew Kelly)가 블로그 게시물을 올렸고,
00:00:11그의 의견은 이것이 기술적인 결정과는 거리가 멀다는 것입니다.
00:00:14땜질식 처방에 대한 비난과 제러드(Jared)의 경영 방식, 그리고 AI 애호가들을 향한 냉소적인 언급이 포함되어 있죠.
00:00:20팝콘 준비하세요.
00:00:26Bun 1.3.14 버전이 Zig로 작성된 마지막 릴리스가 될 예정이며, 1.4 버전부터는 새로운 Rust 코드베이스로 제공됩니다.
00:00:33이 포팅 작업은 5월 3일부터 14일까지 불과 11일 만에 이루어졌고,
00:00:376,502개의 커밋과 약 100만 줄의 코드가 추가되었습니다.
00:00:42정말 엄청난 PR 리뷰였겠네요.
00:00:44물론 AI를 사용했는데, 작업이 몰릴 때는 4개의 Git 작업 트리 전반에 걸쳐 64개의 Claude 인스턴스를 동시에 실행했습니다.
00:00:511분 만에 58개의 커밋이 이루어지기도 했는데, 이는 모두 Claude 5 프리릴리스 버전에서 진행되었습니다.
00:00:55전체적으로 이 재작성에 사용된 API 비용은 총 165,000달러로 추산되는데,
00:01:01저희 채널 구독자도 최근 165,000명을 넘겼으니, 아직 구독 안 하셨다면 구독 부탁드립니다.
00:01:06도대체 왜 Bun을 재작성했을까요?
00:01:08Zig는 분명 훌륭한 언어인데 말이죠.
00:01:10제러드가 밝힌 가장 큰 이유는 “안정성”입니다.
00:01:13Bun은 속도를 최우선으로 하며, 지금까지는 수동 메모리 관리를 사용하는 Zig를 사용해 왔습니다.
00:01:17자동 정리, 생성자나 소멸자, 그리고 borrow checker도 없었죠.
00:01:21Zig에서는 메모리 정리를 모든 코드 호출 시점에 명시적으로 작성해야 합니다.
00:01:25문제는 Bun이 가비지 컬렉션이 적용된 JavaScript Core 위에서 작동한다는 점입니다.
00:01:29그래서 가비지 컬렉션된 JavaScript 값들이 계속해서 수동으로 관리되는 Zig 메모리를 넘나드는 상황이 발생합니다.
00:01:34이것은 Bun의 지난 버전에서 해결된 안정성 관련 버그들의 일부일 뿐인데,
00:01:38사실상 더 이상 참을 수 없는 수준이었던 거죠.
00:01:40Zig에서는 스타일 가이드와 코드 리뷰를 통해 메모리 안전성을 강제했습니다.
00:01:43하지만 Rust에서는 컴파일 시간에 borrow checker가 이를 강제하죠.
00:01:46제러드의 말처럼, 기존 버그의 상당수는 use-after-free, double-free, 혹은 에러 경로에서의 정리 누락이었으며,
00:01:52Rust의 안전한 환경에서는 이런 것들이 모두 컴파일 에러가 되기에, 스타일 가이드보다 훨씬 더 나은 피드백 루프를 제공합니다.
00:01:57이것이 바로 재작성의 핵심 이유입니다.
00:01:59그럼 그냥 Claude Code를 Bun 레포에 열고 “Rust로 포팅하고 실수하지 마”라고 한 걸까요?
00:02:04당연히 아니죠.
00:02:05먼저 해결해야 할 두 가지 질문이 있었습니다.
00:02:07첫째, 한 번에 모두 포팅할 것인가?
00:02:09둘째, Rust 버전 Bun을 Zig 버전과 동일하게 유지하려면 어떻게 할 것인가?
00:02:13첫 번째 질문에 대해, 답은 “예”였습니다. 한 번에 모든 것을 처리하기로 했죠.
00:02:16점진적인 재작성은 결국 제거해야 할 임시 코드를 추가하게 만들고,
00:02:20가끔은 그 코드가 계속 남아있게 되어 단기적으로는 고통스러울 수 있기 때문입니다.
00:02:24두 번째 질문에 대해, 그들은 Rust식의 관용적인 재작성이 아닌, 충실한 포팅을 선택했습니다.
00:02:28그래서 Rust 코드는 의도적으로 Zig의 아키텍처를 그대로 따릅니다.
00:02:31제공된 코드 스니펫에서 이 점을 확인할 수 있습니다.
00:02:34함수 흐름과 구성이 거의 동일하게 읽힙니다.
00:02:36이는 TypeScript 팀이 Go 재작성을 처리했던 방식과도 같습니다.
00:02:39물론 당시엔 Claude와 같은 도구가 없었겠지만요.
00:02:42그 질문들에 답을 얻은 뒤, 다음 단계는 포팅을 시작하는 것이었습니다.
00:02:45가장 먼저 'porting.md'라는 문서를 작성했는데,
00:02:48Zig 패턴을 Rust로 어떻게 매핑할지 정의한 문서였습니다.
00:02:50이것이 Bun이 포팅을 고려하고 있다는 첫 번째 신호였고,
00:02:54사람들이 GitHub에서 이를 발견했을 때 트위터와 해커뉴스에서 큰 화제가 되었습니다.
00:02:58재밌게도 제러드는 해커뉴스에 답글을 달았는데,
00:03:00“이 모든 스레드는 과민반응입니다.”
00:03:02“작동하지도 않는 코드에 달린 댓글이 302개네요.”
00:03:04“재작성을 확정한 적은 없습니다.”
00:03:06“이 코드는 전부 버려질 가능성이 매우 높습니다.”
00:03:09하지만 결국 그렇게 되지는 않았죠.
00:03:10포팅 가이드 외에도 'lifetimes.tsv'라는 파일이 있었는데, 이는 구조체 필드의 의도된 생명 주기를 지정한 파일이었고,
00:03:15실제로 Claude에 이런 프롬프트를 사용하여 완료되었습니다.
00:03:19이 파일들을 설정한 후, AI 에이전트를 가동해 세 개의 파일을 대상으로 테스트를 시작했습니다.
00:03:23그들이 정착한 워크플로우는 구현 에이전트 하나가 새로운 Rust 파일을 작성하고,
00:03:27두 개의 대립적인 리뷰 에이전트가 이를 검토하는 방식이었습니다. 실제로는 별도의 Claude 인스턴스들이
00:03:32diff만 받아서 검토하고, 마지막에 수정 에이전트가 제안들을 적용했습니다.
00:03:37세 개의 파일 테스트가 잘 진행되었는지, 제러드는 Claude에게 1,448개의 Zig 파일 전체를
00:03:41대상으로 같은 워크플로우를 돌리라고 지시했습니다.
00:03:44완전히 순조롭지는 않았는데, 약 2분 뒤 한 Claude가 커밋하기 전에 git stash를 실행하고,
00:03:49다른 Claude가 git stash pop을, 그리고 git reset을 실행하면서 에이전트들끼리 서로 싸우는 상황이 발생했습니다.
00:03:54만약 제러드가 각각 별도의 작업 트리를 쓰지 않았다면 디스크 공간이 부족했을 겁니다.
00:03:57Bun Git 저장소가 워낙 크고, 변경 사항은 결국 컴파일되어 함께 보여야 하기 때문이죠.
00:04:03이를 해결하기 위해 제러드는 Claude에게 git stash나 커밋과 관련 없는 git 명령어,
00:04:07혹은 cargo 명령어처럼 느린 명령어는 절대 실행하지 말라고 명령했습니다.
00:04:11이 작은 수정 이후 Claude는 워크플로우를 재개했고, 속도는 느렸지만 모든 게 잘 작동했습니다.
00:04:17제러드는 워크플로우를 4개의 샤드로 나누고, 각기 고유한 작업 트리를 할당했습니다.
00:04:21총 4개의 작업 트리가 각각 16개의 Claude를 실행하며 파일을 커밋하고 푸시하게 만들었죠.
00:04:25앞서 말했듯이, 이러한 병렬화와 준비 작업 덕분에 최고조에 달했을 때 Claude는
00:04:29분당 1,300줄의 코드를 작성했습니다. 코드 한 줄 한 줄이 두 명의 대립적인 리뷰어에 의해 검토되었고,
00:04:34커밋 전에 수정 과정을 거쳤습니다.
00:04:37하지만 여전히 이 시점에서는 작동하지 않았습니다.
00:04:40그래서 다음 단계는 Crate 별로 컴파일 에러를 수정하는 것이었습니다.
00:04:43참고로, 이전 Zig 코드베이스는 사실상 하나의 거대한 컴파일 단위였는데,
00:04:48제러드는 Rust 버전을 100개의 Crate로 분리하여 컴파일 속도를 높이길 원했습니다.
00:04:53문제는 Crate는 순환 의존성을 가질 수 없다는 점인데, Zig는 이를 신경 쓰지 않았기에
00:04:57기존 코드는 순환 의존성으로 가득했습니다.
00:04:59제러드는 재작성 시작 직전 PR에서 이를 직접 해결하려 했지만,
00:05:02역부족이었습니다. 그래서 순환 코드가 어디에 위치해야 할지 분류하는 워크플로우를 먼저 실행하고,
00:05:06다음 워크플로우에서 실제 리팩토링을 진행했습니다.
00:05:10이러한 순환 문제를 해결하자 약 16,000개의 컴파일 에러가 드러났습니다.
00:05:14제러드의 말대로 한 사람이 처리하기엔 엄청난 숫자지만, 64개의 Claude에게는
00:05:18그다지 미친 숫자는 아니었습니다.
00:05:19또 다른 워크플로우가 시작되었습니다. 이번에는 Crate를 순회하며 시작할 때 cargo check를 실행하고,
00:05:23에러를 파일별로 그룹화하여 저장한 뒤, Claude가 해당 Crate의 모든 에러를 수정하게 했습니다.
00:05:27물론 대립적인 리뷰어 두 명과 수정 에이전트 한 명이 다시 투입되었죠.
00:05:31제안들을 반영하기 위해서였습니다.
00:05:34Claude들이 다시 충돌하는 것을 막기 위해, cargo check는 처음에만 실행하고
00:05:38끝날 때까지 git 명령은 실행하지 않았습니다.
00:05:40이 과정에서도 작은 실수가 있었는데, Claude가 “모든 Crate를 컴파일하라”는 지시를
00:05:43에러가 있는 함수들을 stub(껍데기)으로 바꾸라는 의미로 해석해 버린 것입니다.
00:05:46기술적으로는 컴파일이 되긴 하죠.
00:05:48또한 자신의 우회 방법이 왜 괜찮은지 설명하는 의심스러울 정도로 긴 주석을 달기 시작했습니다.
00:05:52그래서 제러드는 리뷰어 에이전트에게 규칙을 추가했습니다. “왜 이 우회 방법이 괜찮은지
00:05:56설명하는 긴 주석이 필요하다면, 그 코드는 잘못된 것이다. 코드를 고쳐라.”
00:06:01솔직히 꽤 훌륭한 판단 기준입니다.
00:06:03얼마 후 그 워크플로우는 모든 컴파일 에러를 수정했고, 다음 단계는
00:06:06단순히 'bun version' 명령어를 실행하는 것이었는데, 몇 가지 문제가 있었지만 잘 해결되었고,
00:06:10다음 목표는 단일 파일을 대상으로 테스트를 실행하는 것이었습니다.
00:06:14이번에도 Claude 워크플로우를 사용했습니다. Bun CLI의 모든 서브커맨드를 순회하며,
00:06:18실패하는 스택 트레이스를 파일로 저장하고, Claude 한 명이 고치고, 리뷰어 두 명과,
00:06:23수정 에이전트 한 명이 작업하는 방식이었죠.
00:06:24그들은 이 방식의 워크플로우를 사용하며 성공적인 결과를 얻어 꽤 자신감이 붙은 모양입니다.
00:06:28저도 나중에 한번 해봐야 할 것 같네요.
00:06:30CLI 명령어가 작동하기 시작했으니, 이제 전체 Bun 테스트 스위트를 실행할 수 있게 되었습니다.
00:06:33이 워크플로우는 실제로 100개의 무작위 테스트 파일을 한 번에 실행했고, 4개의 작업 트리에 걸쳐
00:06:37폴더별로 샤딩한 후, 같은 리뷰 루프로 실패 사례를 수정했습니다.
00:06:40Bun의 테스트 스위트가 상당히 광범위하기 때문에 이 작업은 정말 거대한 도전이었습니다.
00:06:44메모리 누수 테스트, 'next dev'를 실행하는 통합 테스트, 핫 리로딩이
00:06:48변경 사항을 100번이나 제대로 감지하는지 확인하는 테스트도 있죠.
00:06:50기계의 모든 TCP 소켓을 소진하는 스트레스 테스트, 디스크에 기가바이트 단위로 데이터를 쓰는 테스트,
00:06:54약 10,000개의 프로세스를 생성하는 테스트까지 있었습니다.
00:06:58격리, CPU 및 메모리 제한을 걸었음에도 불구하고 기계는 여러 번 디스크 공간이 부족해 크래시되었습니다.
00:07:02그럼에도 불구하고 말이죠.
00:07:03결과적으로 이틀 후 첫 번째 CI 실행이 완료되었고, 실패한 테스트 목록은
00:07:07972개 파일에서 23개로 줄어들었습니다.
00:07:10그로부터 하루 반 뒤, Linux에서 60개의 샤드가 모두 통과했고, macOS와 Windows도 뒤를 이었으며,
00:07:155월 14일, 54,202번째 빌드가 6개 플랫폼 모두에서 성공했습니다.
00:07:21재작성은 성공적인 것처럼 보였습니다.
00:07:24다음으로 제러드가 해야 할 일은 테스트가 실제로 실행되는지, 은밀하게 생략된 것은 없는지 수동으로 확인하고,
00:07:27로컬에서 여러 기능들을 실행해 보는 것이었습니다. 그리고 최종적으로 머지 버튼을 눌렀죠.
00:07:31끝났습니다.
00:07:32이 모든 작업을 위해 소요된 최종 토큰은 59억 개의 캐시되지 않은 입력 토큰, 6억 9천
00:07:37만 개의 출력 토큰, 그리고 720억 개의 캐시된 토큰 읽기였습니다.
00:07:41앞서 말했듯이 약 165,000달러의 API 비용이 들었지만, 제러드의 추산에 따르면 인간 엔지니어 3명이
00:07:46코드베이스를 완벽히 파악하고 1년 동안 작업해야 했을 분량입니다. 그동안은 버그 수정이나 기능 구현은 꿈도 못 꿨겠죠.
00:07:50현실적으로는 시도조차 하지 않았을 겁니다.
00:07:54하지만 실제로 성공했죠.
00:07:54이는 “절대 재작성하지 마라”는 금기를 깬 첫 번째 대규모 사례로 보입니다.
00:07:58제러드의 말대로, 최근까지 프로그래밍 언어 선택은 일방통행이었습니다.
00:08:03첫날 언어를 정하면 프로젝트가 끝날 때까지 그 언어에 갇히는 거죠.
00:08:07하지만 이제 AI 에이전트가 50만 줄의 코드를 2주도 안 되어 165,000달러로,
00:08:11테스트 검증까지 완벽하게 포팅할 수 있다면, 그 공식은 더 이상 성립하지 않습니다.
00:08:15물론 그 금액이 개인에게는 큰돈이지만, 회사 입장에선 인건비를 고려하면 매우 저렴한 비용이죠.
00:08:191년 동안 팀을 운영하는 비용의 아주 작은 일부일 테니까요.
00:08:23그래서 Bun은 Rust로 재작성되었습니다. 그런데 얻은 이점이 있을까요?
00:08:27바이너리는 더 나은 코드 생성과 링커 최적화 덕분에 약 20% 작아졌고,
00:08:32HTTP 서버와 빌드 벤치마크에서는 2~5% 더 빨라졌으며, 주로 언어 간 링크 타임 최적화 덕분입니다.
00:08:37또한 메모리 누수는 극적으로 줄었습니다.
00:08:40예를 들어, 'bun.build'를 반복적으로 호출하면 이전에는 호출당 약 3MB가 누수되었지만,
00:08:45이제는 일정하게 유지됩니다.
00:08:45이 과정에서 128개의 알려진 버그를 수정했지만, 포팅으로 인해 19개의 새로운 회귀 버그가 발생하기도 했습니다.
00:08:50물론 지금은 모두 해결되었습니다.
00:08:53Bun의 Rust 코드 중 약 4%가 'unsafe' 블록 내에 있는데, 이는 약
00:08:5713,000개의 'unsafe' 키워드입니다. 하지만 블록의 78%는 한 줄짜리이며, 주로 C++에서 넘어오는 포인터 처리입니다.
00:09:03이게 재작성 시 감수했던 트레이드오프입니다.
00:09:04포팅을 시작할 때 일단은 안전하게 'unsafe' 키워드로 포팅을 마쳤고,
00:09:07이제 Rust 코드베이스만 남은 상태에서 시간이 지남에 따라 점차 안전하게 수정해 나갈 예정입니다.
00:09:11전반적으로 이는 지속적인 작업이 되겠지만, 성공적인 결과로 보입니다.
00:09:14실제 작업에 필요한 Rust 코드베이스를 다루는 중이죠.
00:09:16결론적으로 재작업은 성공했습니다.
00:09:19Claude Code는 실제로 Bun의 Rust 포팅 버전에서 실행되는데, Linux에서
00:09:24시작 속도가 10% 더 빨라졌고, 교체 사실을 아는 사람이 거의 없었을 만큼 완벽했습니다.
00:09:28대규모 프로덕션 환경에서의 테스트였는데 정말 인상적입니다.
00:09:31하지만 이제 드라마가 시작됩니다. Bun의 이 글이 올라온 며칠 뒤, Zig의 창시자인 앤드류 켈리가
00:09:35“Bun의 Rust 재작성에 대한 내 생각”이라는 글을 올렸거든요.
00:09:39핵심 주장은 이것이 기술적 결정이 아닌, 관계가 파탄 난 결과라는 것입니다.
00:09:43그는 Bun 코드베이스가 땜질식 처방으로 가득 찼고, 버그를 해결하지 않은 채
00:09:47기능을 무모하게 출시했으며, Zig 팀은 이미 Bun을 언어의 위험 요소로 간주하기 시작했다고 말합니다.
00:09:51언어의 대표 사례로 Bun이 꼽히는 것이 불편해졌죠.
00:09:53그뿐만 아니라, Zig 언어로 코드를 작성하지 않는 예시를 보여주는 꼴이 되었다고 했습니다.
00:09:57Zig 코드 작성법의 반면교사가 된 셈이라면서요.
00:10:01뼈 때리는 발언이죠.
00:10:01아프겠네요.
00:10:02그는 이어 리더십 문화까지 공격했는데, Bun이 채용할 때 올린 트윗을 인용했습니다.
00:10:06“일과 삶의 균형이 일을 안 하는 시간을 의미한다면, 여기서 일하기 힘들 것”이라는 내용이었죠.
00:10:09이 문구였습니다.
00:10:10이 평판이 채용을 방해했고, Zig 커뮤니티 사람들은 Bun 회사 근처에도 안 갔다며,
00:10:14이렇게까지 표현했습니다. 인용하자면,
00:10:17“제러드는 최악의 관리자다. 소통 부재, 비현실적인 기대, 공감 능력 부족, 경험 부족, 완전 엉망진창이었다.”
00:10:22진짜로 제러드를 엄청나게 싫어한다는 게 느껴집니다.
00:10:24네, 제러드를 정말 싫어하는 게 확실합니다.
00:10:27또한 Rust 포팅이 필수적이었다는 사실도 반박합니다. 바이너리 크기 최적화나
00:10:30링크 타임 최적화는 Zig에서도 내내 할 수 있었던 구현 사항인데, Bun이 노력을 안 했던 것뿐이라고요.
00:10:34Bun이 노력을 안 한 거죠.
00:10:38Bun 블로그는 마치 버그를 방지하려면 스타일 가이드를 따르거나 언어 기능을 사용하거나 둘 중 하나를 택해야 하는 것처럼 묘사하지만,
00:10:41이는 버그를 없애기 위해 공학적 자원을 쏟아붓는 가장 중요한 본질을 흐리고 있다고 비판합니다.
00:10:45엔지니어링 리소스를 투자해야 한다는 본질을 말이죠.
00:10:48Tiger Beetle이 하는 일에 비하면 Bun은 정말 부족합니다.
00:10:50그들은 단순히 버그를 찾고 없애기 위해 시간을 쏟았고, ZSF와 건강한 관계를 유지하려고 노력했습니다.
00:10:54Bun은 둘 다 하지 않았고요.
00:10:58그는 100만 줄의 검토되지 않은 코드를 출시하는 것에 대한 변명으로 테스트 스위트를 꼽는 건 말이 안 된다고 합니다.
00:11:02그런데 왜 이전 Zig 코드에서 그렇게 많은 성가신 버그들이 발생했다고 불평했냐는 거죠.
00:11:05앞뒤가 안 맞다는 겁니다.
00:11:07쾅!
00:11:07네, 그는 멈추지 않습니다. 이어서 바이너리 크기 이점에 대해 거짓말을 했다고 비난합니다.
00:11:19그 모든 공학적 작업은 재작성과 아무런 상관이 없었다고요.
00:11:22상관없다는 거죠.
00:11:23이게 바로 블로그 포스트가 나오는 데 그렇게 오래 걸린 이유라고 생각합니다.
00:11:26애초에 Zig 코드베이스에서 했어야 할 엔지니어링 작업을 이제야 한 것이니까요.
00:11:29애초에 했어야죠.
00:11:30우리는 수년간 당신의 'comp-time-of-use' 문제를 경고해 왔습니다.
00:11:32심지어 'comp-time', 'inline', 'usage', 'compile-time' 사용량을 감사해야 하는 프로젝트를 위해
00:11:36특별한 리포트 도구까지 만들었었는데 말이죠.
00:11:39또한 그들이 블로그에서 컴파일 시간 비교를 쏙 뺐다고 주장합니다.
00:11:43자기는 깨끗한 캐시에서 처음부터 빌드하는 데 16초, 이후 증분 컴파일로 매번 편집할 때마다 90밀리초가 걸리는데,
00:11:47Rust로 바뀐 Bun은 그에 상응하는 수치를 보여주지 않았다는 겁니다.
00:11:51그 결과가 빠졌다는 거죠.
00:11:52Rust를 써본 사람이라면 16초보다 훨씬 더 걸릴 거라는 걸 알 겁니다.
00:11:56이게 블로그 글에 대한 그의 반응인데, 아직도 안 끝났습니다.
00:11:59Anthropic과의 제휴가 Zig 커뮤니티에 '드라이브 바이 슬롭(drive-by-slop, 날림 AI 생성물)' 기여와
00:12:03AI 애호가들을 끌어들였다고 지적하며, 그 관계가 끊겨서 안심이고,
00:12:08AI와 연관된 언어로 낙인찍힐까 봐 정말 두려웠다고 고백합니다.
00:12:11정말 싫었던 거죠.
00:12:13그는 블로그가 매우 전문적으로 작성되었다며, 수조 달러 규모 회사의 마케팅 부서가
00:12:17이 일에 큰돈을 쏟고 있다는 암시를 줍니다. Anthropic이 이 일을 Claude의
00:12:21능력을 증명하는 대표 사례로 활용하고 싶어 한다는 거죠.
00:12:25그 말이 맞을지도 모르겠네요.
00:12:26그의 사이트에 있는 원래 블로그 글은 이제 수정되었는데, 본인도 이 점을 인정합니다.
00:12:30스스로 성찰하고 친구들과 대화한 후 결론 섹션을 업데이트했다고 말하죠.
00:12:33하지만 내용을 더 좋게 바꾼 건 아닙니다.
00:12:36오히려 그 반대죠.
00:12:37원래 끝맺음은 “오늘 우리가 배운 것은?”이라며 제러드에 대한 개인적 비판은 없다고 말하고
00:12:40어깨를 으쓱하는 이모티콘으로 마무리했는데, 그게 이제는 “다음 단계로”라는 섹션으로 대체되었습니다.
00:12:44거기서 그는 “Bun을 Zig의 수치로 만든 제러드에게 원한을 품고 있으며,
00:12:48우리가 겪은 몇몇 난장판에 대해 그에게 부분적인 책임이 있다고 생각하고,
00:12:52그의 리더십에 대한 비판을 굽히지 않는다”고 명시했습니다.
00:12:55또한 언어의 창시자가 전 사용자를 비난하고 다음 타겟이 될까 봐 걱정했던 Zig 사용자들에게 사과하며,
00:13:00관용을 베풀어 달라고 말합니다. “수조 달러 규모 회사가 먼저 총을 쐈다는 점을 고려해 주세요.”
00:13:03먼저 공격을 받았으니 어쩔 수 없었다는 거죠.
00:13:07솔직히 두 글 모두 어느 정도 진실을 담고 있다고 생각합니다.
00:13:10켈리가 말하는 “Rust 재작성이 필수는 아니었다”는 부분은 맞습니다.
00:13:14Bun은 Zig에서 메모리 안전 규율과 툴링, LTO에 투자할 수 있었을 테니까요.
00:13:18하지만 제러드가 말하는 “수년간의 'use-after-free' 버그를 겪고도 그냥 disciplined(규율)을 지키라니,
00:13:22그게 유효한 전략인가? 컴파일러 수준에서 버그 자체를 불가능하게 만드는 게 낫지 않나”는 말도 일리가 있습니다.
00:13:27충분히 그럴 수 있죠.
00:13:27AI 측면에 대해서는, “AI가 마법처럼 Bun을 재작성했다”고 보긴 어렵습니다.
00:13:32유능한 엔지니어가 포팅 문서, 생명 주기 사양, 대립적인 리뷰어 루프 등을 설계하고,
00:13:37130만 개의 테스트 단언을 동원한 것입니다.
00:13:39오히려 이 사건은 AI 에이전트에게 테스트가 얼마나 중요한지를 잘 보여줍니다.
00:13:43많은 프로젝트가 테스트를 공개하지 않게 된 이유이기도 하죠. AI가 테스트만 통과하면 된다는 식으로
00:13:46작업하는 데는 매우 능숙했거든요.
00:13:50Cloudflare가 Next.js를 처리했던 것처럼요.
00:13:53그게 전체 이야기입니다.
00:13:54Bun은 이제 Rust로 작성되었고, Zig는 대표 프로젝트 하나를 잃었지만,
00:13:58창시자는 꽤 만족하는 것 같네요.
00:13:59여러분의 생각은 어떠신가요?
00:14:00Anthropic이 토큰 비용을 대줄 때만 가능한 일일까요?
00:14:03이제 Bun을 믿으시나요?
00:14:04댓글로 생각을 남겨주세요. 구독도 부탁드리고, 언제나 그랬듯,
00:14:07다음 영상에서 뵙겠습니다.

핵심 요약

Bun은 약 165,000달러의 AI API 비용과 11일간의 집중적인 자동화 워크플로우를 통해 거대 코드베이스를 Zig에서 Rust로 성공적으로 전환하며 메모리 안전성과 성능 최적화를 달성했습니다.

하이라이트

  • Bun은 11일 만에 약 100만 줄의 코드베이스를 Zig에서 Rust로 재작성했습니다.

  • 재작성 과정에서 Claude 인스턴스 64개를 동시에 사용했으며 총 165,000달러의 API 비용이 발생했습니다.

  • Rust 도입의 핵심 동기는 컴파일 타임의 borrow checker를 통한 메모리 안정성 확보입니다.

  • 재작성된 Bun 바이너리는 이전보다 약 20% 작아졌으며, HTTP 서버 성능은 2~5% 향상되었습니다.

  • Zig 창시자 앤드류 켈리는 이번 재작성을 기술적 필요성보다는 Bun 경영진과의 관계 파탄 및 공학적 부채 해결 실패의 결과로 규정했습니다.

타임라인

Bun의 Rust 재작성 프로젝트

  • Bun은 5월 3일부터 14일까지 11일간 100만 줄의 코드를 Zig에서 Rust로 포팅했습니다.
  • 64개의 Claude 인스턴스를 4개의 작업 트리에 분산 배치하여 병렬로 코드를 생성하고 검토했습니다.
  • 메모리 안전성 문제 해결을 위해 수동 메모리 관리의 Zig 대신 Rust의 borrow checker를 선택했습니다.
  • 재작성 과정에서 약 165,000달러의 API 비용이 소요되었습니다.

Bun은 가비지 컬렉션 환경인 JavaScript Core와 수동 메모리 관리 언어인 Zig 사이의 메모리 충돌로 인한 버그를 해결하기 위해 Rust로의 대규모 전환을 단행했습니다. 단순 변환을 넘어 Claude 에이전트들을 구현, 대립적 리뷰어, 수정 에이전트로 분할하여 1,448개의 파일 전체를 체계적으로 포팅했습니다. 이 과정에서 순환 의존성 해결을 위해 100개의 Crate로 코드베이스를 분리하고, CI 테스트를 통해 결과물을 검증했습니다.

포팅 결과 및 성과

  • 100개의 무작위 테스트 파일을 포함한 대규모 테스트 스위트를 성공적으로 통과했습니다.
  • 바이너리 크기가 20% 감소하고 HTTP 서버 처리 속도가 2~5% 향상되었습니다.
  • Rust 코드의 4%가 'unsafe' 블록으로 구성되어 있으며 점진적으로 안전한 코드로 교체 중입니다.
  • 인간 엔지니어 3명이 1년간 수행할 분량의 작업을 2주 미만의 기간에 완료했습니다.

재작성된 Bun은 6개 플랫폼 모두에서 빌드에 성공했습니다. 이 포팅은 인간 엔지니어가 1년 동안 수행할 업무를 AI 에이전트를 통해 단기간에 완료한 사례입니다. 메모리 누수 문제는 현저히 감소했고, 실제 프로덕션 환경에서의 성능과 안정성 수치도 개선되었습니다.

Zig 창시자의 비판과 갈등

  • 앤드류 켈리는 재작성이 기술적 필수 사항이 아니라 공학적 관리 부실의 결과라고 비판했습니다.
  • Bun의 사내 리더십과 소통 방식, 공감 능력 부족을 강하게 질타했습니다.
  • Zig 언어의 툴링을 활용하면 Rust로 바꾸지 않고도 충분히 메모리 안전성을 확보할 수 있었다고 주장했습니다.
  • Anthropic의 AI 기술 마케팅을 위해 Bun이 도구로 사용된 점을 지적했습니다.

Zig의 창시자 앤드류 켈리는 Bun의 재작성 발표에 대해 강경한 비판 글을 올렸습니다. 그는 Bun이 기술적 부채를 방치해 온 점을 문제 삼으며, 재작성 과정에서 강조된 성능 이점들도 Zig 환경에서 이미 달성 가능한 수준이었다고 일축했습니다. 또한 Bun이 언어 공동체와 건강한 관계를 유지하지 못했으며, AI 모델의 성능 증명을 위한 홍보 사례로 전락한 것에 대해 불편함을 드러냈습니다.

커뮤니티 글

모든 글 보기