Bun의 Rust 재작성에 대한 내 생각

3 hours ago 1
  • Bun의 Rust 재작성은 Zig로 만든 기존 아키텍처와 자료구조를 유지한 채 더 주류 기술 스택으로 옮기는 결정에 가까움
  • 재작성 PR은 6,755개 커밋 규모였고 5월 8일 오픈 후 5월 14일 병합돼, 프로덕션급 런타임 변경의 리뷰 깊이에 의문이 남음
  • 테스트 통과는 알려진 경로만 검증하며, 에러 경로·동시성·극단적 메모리 조건 같은 전역 불변식까지 보장하기 어려움
  • 핵심은 Zig의 실패가 아니라 빠른 출시를 중시하는 Bun 팀 문화와 수동 메모리 관리 비용 사이의 구조적 불일치에 있음
  • 실제 베팅은 Zig 대 Rust가 아니라, AI가 생성하고 충분히 리뷰되지 않은 코드를 장기 유지보수할 수 있는지에 있음

Zig가 만든 Bun의 기반

  • Bun의 Rust 재작성 PR을 보기 전에, Bun이 현재 위치에 오른 데에는 Zig의 역할이 컸음
  • Jarred가 Zig를 선택한 이유는 “멋있어서”가 아니라, 가비지 컬렉션 없는 고성능 JS 런타임을 작은 팀이 빠르게 프로토타입으로 만들 수 있었기 때문임
  • Zig의 낮은 마찰, 직접적인 메모리 조작, 단순한 C 상호 운용성이 Bun 초기 성능과 작은 팀 규모를 가능하게 했음
  • Jarred가 “아키텍처는 바뀌지 않고, 자료구조도 바뀌지 않는다”고 말한 만큼, Rust 재작성은 Zig로 만들어진 골격을 이어받는 구조에 가까움
  • Zig로 기반을 만들고, 제품을 출시하고, 투자 유치까지 한 뒤 회사가 인수되고 커진 다음 더 주류 기술 스택으로 옮기는 일은 정상적인 비즈니스 결정으로 볼 수 있음
  • 다만 이를 Zig 자체의 부적합성으로 포장하기는 어려움

6일 만에 병합된 대규모 재작성의 위험

  • 재작성 PR6,755개 커밋, 브랜치명 claude/phase-a-port, 5월 8일 오픈 후 5월 14일 병합이라는 기록을 남김
  • 프로덕션급 JS 런타임 전체 재작성이 6일 만에 병합됐다는 점이 핵심 문제임
  • 소프트웨어 엔지니어링의 기본 원칙은 “이해하지 못한 코드는 프로덕션에서 실행해서는 안 된다”는 것임
  • 이 원칙은 코드에 반드시 버그가 있어서가 아니라, 버그가 발생했을 때 어디서부터 봐야 할지 모르게 되기 때문에 유지보수성의 기준선이 됨
  • PR의 리뷰어 목록에는 coderabbitai[bot], claude[bot]이 있었고, 유일한 인간 리뷰어 alii는 “Awaiting requested review” 상태였음
  • Claude가 작성하고 Claude가 리뷰한 폐쇄 루프는 논리적으로 불가능한 일은 아니지만, 결과적으로 전체 코드베이스를 인간이 실제로 끝까지 읽지 않았다는 뜻이 됨

테스트 통과가 보장하지 못하는 것

  • 모든 플랫폼에서 테스트 스위트가 통과하더라도, 이는 알려진 동작과 알려진 경로의 올바름만 검증함
  • 테스트 스위트는 다음 영역을 충분히 보장하기 어려움
    • 에러 경로가 올바르게 처리되는지
    • 스트레스 상황의 경계 조건에서 어떤 동작을 하는지
    • 동시성 상황에서 상태 일관성이 유지되는지
    • 극단적 조건에서 메모리 모델이 의도와 맞는지
  • Jarred도 JS 경계를 다시 진입할 때의 메모리 문제는 Rust 컴파일러가 처리할 수 없고 여전히 인간에 의존한다고 인정한 것으로 정리됨
  • 문제는 인간에 의존해야 하는 그 부분을 인간이 리뷰하지 않았다는 점
  • AI의 코드 번역은 각 함수가 원본과 고립된 상태에서 동일하게 동작하도록 맞추는 국소적 의미 동등성에 가까움
  • 함수 사이의 전역 불변식, 테스트에 적히지 않고 원저자의 머릿속에만 있는 설계 제약은 AI 번역만으로 보장하기 어려움
  • 이런 제약은 현재 테스트에서는 드러나지 않다가 6개월 뒤 특정 프로덕션 부하에서 설명하기 어려운 충돌로 나타날 수 있음
  • 이는 Claude만의 문제가 아니라, 충분한 리뷰 없이 번역하는 모든 도구와 인간 프로그래머에게도 해당함
  • 6,755개 커밋 규모에서는 이런 위험이 크게 증폭됨

인수 이후 바뀐 위험 부담자

  • 초기 Bun은 Jarred가 스스로에게 베팅한 프로젝트였고, Zig 사용, 빠른 반복, 기술 부채 수용은 스스로 위험을 떠안는 스타트업 논리로 볼 수 있음
  • Bun이 대기업에 인수되고 실제 프로덕션 시스템에서 쓰이는 사용자 기반을 갖게 된 지금, 재작성의 위험 부담자는 Jarred가 아니라 프로덕션에서 Bun을 실행하는 엔지니어와 그 뒤의 사용자들로 바뀜
  • Jarred는 해당 버전이 아직 canary이고, 공식 릴리스 전 최적화와 정리 작업이 남아 있다고 말함
  • canary는 방어선이지만 인간 리뷰의 대체물은 아님
  • 최적화와 정리는 코드 품질의 문제이지, 유지보수자가 코드를 이해했는지의 문제를 해결하지 못함
  • 팀 누구도 전체를 완전히 읽지 않은 코드베이스는 테스트가 포괄적이거나 canary 기간이 길어도 유지보수자에게 내부 상태가 블랙박스로 남음
  • 이 문제는 향후 심각한 버그를 디버깅하는 현장에서 실제 고통으로 드러날 수 있음

Zig 문제 진단의 오류

  • Jarred가 제시한 이전 이유는 Zig 코드베이스에 use-after-free, double-free, 에러 경로의 메모리 누수가 많았다는 것임
  • 이 진단 자체는 맞지만, 여기서 “Zig가 작동하지 않는다”는 결론을 내리기는 어려움
  • 더 정확한 진단은 빠른 반복을 우선하는 상업 프로젝트에서 수동 메모리 관리의 인지 비용이 팀의 예산을 초과했다는 것임
  • 이는 Zig의 버그가 아니라, Zig의 설계 목표와 Bun의 비즈니스 모델 사이의 구조적 불일치로 볼 수 있음
  • Zig의 대상 사용자는 자신이 무엇을 하는지 알고, 최종적인 제어를 위해 비용을 지불할 의지가 있는 시스템 프로그래머임
  • TigerBeetle은 Zig로 사실상 메모리 버그가 거의 없는 데이터베이스를 작성했는데, 팀 문화와 프로젝트 성격이 Zig의 철학과 맞았기 때문으로 정리됨
  • Bun 팀 문화는 빠른 반복, 빠른 출시, 빠른 버그 수정에 가깝고, 이는 Zig가 요구하는 엄격한 메모리 규율과 근본적으로 긴장 관계에 있음
  • “우리 팀이 이 도구로 자주 실수한다”를 “이 도구가 부적합하다”로 해석하는 것은 귀인 오류에 가까움
  • 망치가 맞지 않았다고 해서 망치 자체의 잘못은 아니라는 비유가 사용됨

단기 전망과 장기 위험

  • 단기적으로는 재작성 버전이 대체로 괜찮을 가능성이 높음
  • 주요 경로는 테스트로 커버되고, canary 단계에서 명백한 문제가 드러나며, Rust 컴파일러 보장은 메모리 버그의 한 종류를 제거하기 때문임
  • 표면적으로는 모든 것이 정상처럼 보일 수 있음
  • 장기적으로는 인간이 완전히 읽지 않은 6,755개 커밋이 구조적 위험으로 남음
  • 6개월 뒤 기묘한 동시성 버그가 나타나거나, 특정 부하에서 경계 조건이 이상 동작을 유발하면, 디버깅 엔지니어는 누구도 진정으로 이해한 적 없는 시스템을 마주하게 됨
  • 이해된 적 없는 시스템이라는 말은 버그가 없다는 뜻이 아니라, 버그가 나타났을 때 왜 그런지 아무도 모른다는 뜻임
  • 이번 재작성의 실제 기술적 베팅은 Zig 대 Rust가 아니라, AI가 생성하고 리뷰되지 않은 코드를 프로덕션 환경에서 장기 유지보수할 수 있는지에 있음
  • 이 질문은 “테스트가 모두 통과한다”보다 복잡하고, “Rust의 메모리 안전성”보다 더 깊은 문제임
  • 결론은 “Zig가 기반을 만들고, Claude가 건물을 세웠으며, 인간 리뷰어는 아직 오는 중”이라는 비유로 압축됨
  • 이 건물이 얼마나 오래 거주 가능한지는 처음 누수가 발생했을 때 누군가가 설계도를 읽을 수 있는지에 달려 있음
Read Entire Article