JavaScript 런타임 Bun이 7월 8일, 사상 처음으로 메이저 버전 2.0과 함께 Rust 기반 네이티브 런타임으로 전환한다고 발표했습니다. 월 2,200만 회 이상 다운로드되는 이 프로젝트는, Zig 535,496줄을 1년 동안 사람이 옮기는 대신 Claude Code의 동적 워크플로우로 단 며칠 만에 마이그레이션했습니다. 본문에서는 Bun이 왜 Zig를 버렸고, Rust로 가면서 무엇이 좋아졌고, 개발자 입장에서 어떤 의미가 있는지를 정리합니다.

1) Bun이 Zig를 떠나 Rust로 간 이유
Bun은 처음부터 Zig로 시작했습니다. Zig는 C/C++에 견주는 저수준 제어와 빠른 컴파일 속도를 제공했지만, Bun이 커지면서 세 가지 문제가 누적됐습니다.
- GC(garbage collection) 기반 JavaScript 엔진 + 수동 메모리 관리 충돌: JS 객체 그래프와 Zig의 수동 lifetime이 반복적으로 어긋나며 segfault와 메모리 누수가 다수 발생
- 빌드 시스템의 불안정성: Zig의 staged allocator, comptime reflection이 JS·네이티브 모듈 경계에서 미묘한 ABI 차이를 만들었고, 디버깅이 매우 어려움
- 컨트리뷰터 풀의 한계: Zig 숙련자는 풀 자체가 작고, JS 런타임을 손볼 수 있는 사람은 더 적음
특히 2025년 후반기부터 동시성·에이전트형 워크로드가 Bun의 주 사용 패턴이 되면서, 메모리 안전성과 GC와의 정합성이 더 큰 병목이 됐습니다.
2) Claude Code로 535,496줄을 옮기다
Bun 팀은 사람이 1년 동안 옮길 분량을 Claude Code의 동적 워크플로우로 단 며칠 만에 끝냈습니다. 그 흐름은 다음과 같습니다.
2-1. AST → 의미 단위 분할
먼저 Zig 소스 53만 줄을 AST로 파싱한 뒤, 함수·구조체·FFI 경계 단위로 의미 청크로 분할합니다. 단순 줄 단위가 아니라 외부에서 관찰 가능한 인터페이스 경계로 자른 것이 핵심입니다.
2-2. 클로드 코드의 동적 컨텍스트 로딩
Claude Code는 컨텍스트 윈도우가 제한적이므로, Bun 팀은 토픽별 동적 컨텍스트 로더를 만들었습니다. 파일이 바뀌면 의존성 그래프를 다시 계산해 관련 청크만 컨텍스트에 올립니다. 이로써 53만 줄 전체를 한 번에 모델에 넣는 비효율을 피했습니다.
2-3. Rust의 `unsafe` 격리 + 인터페이스 동등성 검증
이식된 Rust 코드는 FFI 경계 외에는 unsafe를 쓰지 않음을 정책으로 강제했습니다. 사람이 직접 짜는 부분은 unsafe 블록과 그 위에 얹힌 safe wrapper로 분리되고, Claude Code는 wrapper만 작성합니다. 변환 후에는 양쪽 언어에서 동일한 입력 → 동일한 출력을 검증하는 differential test로 동작 동등성을 자동으로 확인합니다.
3) Rust로 가면서 좋아진 것
3-1. GC와 메모리 모델의 정합성
Rust의 ownership 모델이 JS 객체 그래프와 더 자연스럽게 맞물립니다. Bun의 JSCore 바인딩은 이제 Arc 패턴으로 단일화되었고, lifetime 추적이 컴파일 타임에 끝납니다.
3-2. 빌드 속도와 패키징
Zig의 comptime 단계가 사라지면서 cold build 시간이 약 40% 단축됐고, cargo의 incremental compile + sccache 조합으로 CI 캐시 효율도 크게 올랐습니다.
3-3. 컨트리뷰터 풀 확대
Zig 숙련자는 한정적이지만 Rust 개발자는 10배 이상 많습니다. Bun 2.0은 첫 주 만에 Zig 시점의 6배에 가까운 PR이 들어왔고, 외부 컨트리뷰터가 작성한 모듈이 30% 이상을 차지합니다.
4) 개발자가 체감할 변화
4-1. Node 호환성은 유지
Bun 2.0은 Node.js API 호환성 99.5%를 유지합니다. 기존 node:fs, node:http, node:stream을 그대로 쓸 수 있고, npm 레지스트리도 그대로 사용 가능합니다.
4-2. 성능은 평균 1.4~1.7배 향상
HTTP 서버, 파일 I/O, SQLite 바인딩에서 평균 1.4~1.7배, 일부 워크로드(스트리밍·압축)에서는 2배 가까운 속도 향상이 측정됩니다. 콜드 스타트도 빨라져 서버리스 환경에 더 적합해졌습니다.
4-3. 디버깅 경험 개선
Zig 시절의 "어디서 segfault가 났는지 추적하기 어려움" 문제가 사라졌습니다. Rust의 panic backtrace + cargo-flamegraph, tokio-console 조합으로 런타임 가시성이 크게 개선됐습니다.
5) 다른 JS 런타임과 비교
| 런타임 | 언어 | 출시 시점 | 주요 사용처 |

| --- | --- | --- | --- |
| Bun 2.0 | Rust (JSCore) | 2026-07 | 풀스택(Node 호환), 서버리스, 스크립팅 |
| Node.js | C++ (V8) | 2009 | 범용 서버, npm 생태계 |
| Deno 2 | Rust (V8) | 2018/2024 | 보안·권한 모델, 엣지 |
| Hermes (React Native) | C++ (custom) | 2019 | 모바일 JS 엔진 |
Rust 기반 런타임이 둘(Bun, Deno)로 늘었지만, Bun은 Node 호환성에 집중한 것이 가장 큰 차별점입니다. 기존 Node 프로젝트를 그대로 가져와 1.5배 정도 빨라지는 마이그레이션 경로가 표준화됐습니다.
6) 실전에서 Bun 2.0 써보기
# 설치
curl -fsSL https://bun.sh/install | bash
# 프로젝트 부트스트랩
bun create next-app my-app --template ts
cd my-app
bun install
bun run dev # Next.js 서버가 Bun 2.0으로 구동
// src/server.ts
import { serve } from "bun";
serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
if (url.pathname === "/health") return new Response("ok");
return new Response("Hello from Bun 2.0 (Rust)", { status: 200 });
},
});
7) 마이그레이션 체크리스트
기존 Node/Bun 1.x 프로젝트를 Bun 2.0으로 가져올 때 다음 4가지만 확인하면 대부분 무리 없이 동작합니다.
- 네이티브 모듈 사용처 확인: node-gyp 기반 패키지는 대부분 그대로 동작하지만, Zig 시절 Bun 전용 FFI를 쓰던 코드는 Rust 바인딩으로 재작성 필요
- 시그널 핸들러 패턴: process.on("SIGTERM") 등의 시그널 처리는 Rust 측 tokio runtime과 정합성 확인
- child_process 동작: Bun.spawn은 Node의 child_process와 옵션명이 일부 다름, stdio: "pipe" 명시가 안전
- TypeScript 컴파일러 경로: tsconfig.json의 target을 ES2022 이상으로 두면 Bun 2.0이 더 빠르게 처리
8) FAQ
- Q1. Bun 2.0은 기존 Bun 1.x 스크립트와 100% 호환되나요?*
대부분의 스크립트는 그대로 동작합니다. 다만 Bun.Transpiler.transform 같은 저수준 API는 Rust 측 구현에 맞춰 일부 시그니처가 바뀌었고, 마이너 버전 업데이트 가이드를 따라 한두 줄만 수정하면 됩니다.
- Q2. Deno 2와 Bun 2.0 중 무엇을 골라야 하나요?*
권한·보안 모델이 필요하면 Deno 2, Node 호환성과 npm 생태계 그대로가 필요하면 Bun 2.0이 더 적합합니다. 서버리스 워크로드에서는 Bun 2.0의 콜드 스타트와 HTTP 성능이 우위입니다.
- Q3. AI 에이전트 워크로드에서 정말 빨라졌나요?*
함수 호출과 다단계 도구 사용 패턴에서 평균 1.6배, 토큰 스트리밍 응답은 2배 가까이 빨라집니다. 이유는 Rust의 nonblocking I/O가 JSCore 콜백 큐와 더 잘 맞물리기 때문입니다.
- Q4. 컨트리뷰션은 어떻게 시작하나요?*
Bun GitHub 저장소의 good first issue 라벨이 Rust 컨트리뷰터 풀을 대상으로 다시 태깅됐습니다. 2.0 출시 후 첫 1주일이 가장 진입하기 좋은 시점입니다.
9) 한 줄 결론
- Bun 2.0 = Rust 런타임 + JSCore + Node 호환성
- Zig 53만 줄을 Claude Code 동적 워크플로우로 며칠 만에 이식, 사람이 1년 걸릴 분량을 단축
- 메모리 안전성·빌드 속도·컨트리뷰터 풀 모두 개선, Node 프로젝트의 1.4~1.7배 성능 향상이 기본값
> Bun 2.0이 AI-네이티브 런타임 시대를 본격적으로 여는 신호탄입니다. 53만 줄을 며칠 만에 이식한 사례는, 단순한 코드 변환이 아니라 동적 컨텍스트 로딩 + 의미 단위 분할 + differential test가 한 묶음일 때 가능하다는 걸 보여줍니다.
📰 원본 출처 · https://news.hada.io/topic?id=31263 (#N=31263)
이 글은 GeekNews(긱뉴스)에 게제된 글을 기반으로 작성되었습니다. 원본의 라이선스와 저작권은 원작자에게 있습니다.
'개발 팁' 카테고리의 다른 글
| Repo-rter — 깃허브 레포 통계를 14일 블랙아웃 없이 영구 저장하는 15MB 로컬 데스크탑 앱 (0) | 2026.07.13 |
|---|---|
| Ant, 경량 JavaScript 런타임과 생태계 — 8.6MB 단일 바이너리로 V8/JSC 우회하는 새로운 접근 (0) | 2026.07.13 |
| Microsoft, id Software의 idTech 팀 해고 — 게임 엔진 생태계의 거대한 균열 (0) | 2026.07.09 |
| 한국 선거 공개 데이터, CLI 한 줄로 끝내기 — k-vote-cli 완전 가이드 (0) | 2026.07.07 |
| AI 코딩 시대의 개발자 역할 변화 - 실행자에서 설계자로 (0) | 2026.07.07 |