Bun Install의 비하인드 스토리
(bun.com)- Bun의 패키지 설치는 기존 패키지 매니저들에 비해 매우 빠른 속도로 동작함
- 빠른 설치의 핵심은 시스템 프로그래밍 관점의 접근과 시스템 콜 최소화에 있음
- Zig 언어 기반의 네이티브 코딩, 바이너리 캐시 사용, OS별 최적화 등의 세밀한 전략 적용을 통한 성능 향상 제공
- tarball 압축 해제 및 파일 복사 과정에서도 하드웨어 특성을 활용한 고성능 방법을 도입함
- 의존성 그래프와 lockfile 등 데이터 구조 최적화를 통해 CPU 캐시 효율과 메모리 접근성을 높임
Bun Install이 빠른 이유
- Bun의
bun install
은 평균적으로 npm보다 7배, pnpm보다 4배, yarn보다 17배 더 빠른 패키지 설치 성능을 제공함 - 이는 단순 벤치마크가 아닌, 패키지 설치 문제를 자바스크립트가 아닌 시스템 프로그래밍 관점으로 접근했기 때문임
- 시스템 콜 최소화, 매니페스트 바이너리 캐싱, tarball 추출 최적화, OS 네이티브 파일 복사 등 여러 계층에서 성능 최적화를 적극적으로 적용함
Node.js와 패키지 매니저 아키텍처의 한계
- 2009년 Node.js 출시 이후, 이벤트 루프와 쓰레드풀 기반의 비동기 IO 모델이 패키지 매니저에도 전파됨
- 당시에는 하드웨어 한계(느린 디스크, 느린 네트워크) 때문에 비동기 IO와 높은 시스템 콜 빈도 전략이 합리적이었음
- 그러나 현대 시스템은 NVMe SSD, 빠른 네트워크, 고성능 CPU가 보편적이고, 진짜 병목은 IO가 아닌 시스템 콜 오버헤드임
시스템 콜과 모드 스위치의 비용
- 프로그램이 파일 읽기와 같은 작업을 요청하면, user mode에서 kernel mode로 전환해야 하며, 이 과정은 고가의 CPU 사이클(1000~1500 cycles)이 소모됨
- 패키지 설치는 기본적으로 수만~수십만 번 이상의 시스템 콜을 요구하여 실제 작업 전환 비용만으로도 수초의 CPU 시간 소모 발생
- 예를 들어, React 및 의존성 설치시 npm은 약 100만 번, yarn은 400만 번, pnpm은 50만 번, bun은 16만 번의 시스템 콜 사용
기존 패키지 매니저와 Bun의 접근 방식 차이
- npm, pnpm, yarn은 모두 Node.js 기반으로, 자바스크립트를 여러 추상 레이어(libuv, 이벤트 루프, 쓰레드풀, 시스템 콜 중개)로 실행해야 함
- 이때 아규먼트 변환, 워커풀 큐, 이벤트 루프 작업 분기, futex(락 동기화) 시스템 콜 등이 누적되어, IO보다 시스템 콜 관리가 오히려 더 느려지는 결과 초래함
- Node.js로 만든 패키지 매니저는 이런 구조적 한계 때문에 실제 네이티브에 근접한 성능을 내기 어려움
Bun: Zig로 구현한 네이티브 설치 엔진
- Bun은 Zig 언어로 직접 시스템 콜을 호출하여, 자바스크립트 엔진/추상화 레이어를 모두 생략함
- 예를 들어 파일 읽기는 Zig 코드에서 곧바로 openat() 시스템 콜을 실행하여 바로 데이터를 반환함
- 따라서 수만 개의 파일을 읽는 과정이 별도의 쓰레드풀·이벤트 루프·데이터 변환 과정 없이 초고속으로 동작함
- 벤치마크상 Bun은 초당 146,057개의 package.json을 읽을 수 있으며, Node.js는 6만개 대로 2배 이상 느림
의존성 관리 및 DNS 최적화
- Bun은
bun install
실행시 의존성 분석과 동시에 DNS prefetch를 비동기적으로 트리거함 - 예를 들어 macOS에서는 Apple의 비공식 async DNS API(getaddrinfo_async_start())를 사용, 쓰레드 블로킹 없이 네트워크 작업 동시 처리를 지원함
- 기존 패키지 매니저는 libuv 쓰레드풀 기반으로 실제로는 내부적으로 블로킹 코드가 실행되어 자원 낭비 발생
패키지 매니페스트 바이너리 캐싱
- npm 등은 매니페스트를 JSON으로 캐싱하나, Bun은 한 번 파싱한 후, 이 결과를 바이너리(.npm 파일)로 변환해 저장함
- 문자열 중복/파싱 오버헤드 최소화, 실제 메모리에선 오프셋 계산만으로 바로 값 접근이 가능해짐(새 객체 생성, 파싱, 가비지 컬렉션 불필요)
- ETag와 If-None-Match 헤더로 변경 점만 확인, 불필요한 데이터 파싱 없이 최신성 검증 가능
- 벤치마크상, Bun의 캐시 설치가 npm fresh install보다도 빠름
Tarball(압축 파일) 처리 성능
- 일반 패키지 매니저는 tarball을 스트림으로 받아, 버퍼 메모리 부족시마다 재할당·복사·리사이즈가 연속 발생함
- Bun은 tarball 전체 수신 후 패킹 해제하며, gzip 마지막 4바이트로 언컴프레스 사이즈를 사전 파악→** 한 번만 메모리 할당**
- libdeflate 등을 활용해 빠른 해제, 불필요한 중복 복사와 사이즈 리사이즈 모두 제거
의존성 그래프 & 데이터 구조 최적화
- 기존 패키지 매니저는 자바스크립트 오브젝트/포인터 기반 의존성 트리를 만들어, 메모리 랜덤 분산 및 CPU 캐시 미스를 빈번하게 만듦(pointer chasing 문제)
- Bun은 Structure of Arrays(SoA) 패턴을 적용해, 모든 패키지 및 문자열, 의존성을 큰 연속 메모리 덩어리로 저장함
- 오프셋/길이 기반 접근으로 CPU가 한 번에 여러 패키지를 캐시 라인 단위로 읽을 수 있음(캐시 친화적 구조)
- lockfile 역시 JSON/YAML 대신 SoA 패턴에 맞게, 문자열 중복 제거 및 순차 메모리 접근이 용이하게 저장
- lockfile의 바이너리 형식(bun.lockb)도 실험적으로 도입했으나, Git 협업성 저하로 가독성 높은 플레인 포맷으로 전환
OS별 파일 복사 최적화
macOS
- clonefile 사용: 통째로 디렉토리를 Copy-On-Write 방식의 한 번의 시스템 콜로 복제
- 디스크 공간 중복 사용 최소화, 설치 속도 최대화 제공
- clonefile 실패시 폴백으로 per-directory cloning→copyfile로 단계적 폴백
Linux
- 하드링크 우선 시도: 새로운 파일을 생성하지 않고 기존 파일의 새로운 참조만 만듦(디스크 데이터 이동 없음)
- 하드링크 불가시 Btrfs/XFS에서는 ioctl_ficlone으로 Copy-On-Write 적용
- 이후에는 copy_file_range, sendfile, 그리고 마지막으로 일반 copyfile 방식으로 폴백
총평
- Bun은 시스템 콜 최소화, 바이너리 구조, OS 최적화, 데이터 구조 개선을 통해 패키지 매니저의 전통적인 성능 한계를 뛰어넘었음
- 이로 인해 초고속 설치와 더불어, 메모리/CPU 효율까지 모두 개선하는 장점 제공
- 기존 Node.js 기반 매니저 대비 별도 런타임 교체 없이도 프로젝트 적용 가능(호환성 유지)
- 실제 대규모 코드베이스에서 수분 걸리던 설치 과정을 수 밀리초~수 초 이내로 단축시키는 경험 제공
- 시스템, 하드웨어, OS 레벨에 맞춘 맞춤 최적화의 우수사례로 연구·참고 가치가 높음
Hacker News 의견
-
내가 사용하는 M4 Max MacBook이 2009년 기준 TOP500 슈퍼컴퓨터 50위 안에 들었을 것이라는 주장에 대해 검증 시도함
2009년 TOP500에 들려면 75 TFlop/s 이상의 성능이 필요함
M4 Max는 FP32에서 18.4 TFlop/s이지만, TOP500은 FP64(LINPACK)을 사용함
M2 벤치마크 기준으로 FP64는 FP32의 1/4 수준이므로, 대략 9 TFlop/s 예상됨
그 정도론 2009년 TOP500에 못 들어감
2009년 TOP500 목록 참고-
각 연결이 동시에 여러 I/O 작업을 하는 경우 수천 개의 연결로 곱셈해야 함
서버는 대략 전체 시간의 95%를 I/O 대기라고 들었지만, 실제로 전체 서버가 아닌 개별 스레드 기준임
실제 서버는 CPU 사용률이 70~80%까지 올라가는 경우가 많음(이 이상이면 tail latency가 급격히 나빠짐)
풀로드에서 CPU 5% 쓰면 병렬 프로세스 부족이나 메모리 부족 문제임
기술적으로 작은 디테일이지만, 이런 실수가 포스트 신뢰성을 떨어뜨릴 수 있음(Bun의 팬 입장에서 말함) -
저 결론은 뭔가 LLM이 만들어낸 환각같다는 생각이 듦
결론 부분이 특히 LLM에서 뽑은 듯한 느낌이 있음
"벤치마크한 패키지 매니저들이 잘못된 게 아니라, 그 시절에 맞는 해법이었음을 이해함"
"Bun의 방식은 혁명적이라기보다, 현재 속도가 느려지는 원인을 냉철하게 바라본 결과라는 점이 강조됨"
"패키지 설치가 25배 빨라진 것은 마법이 아니라, 최신 하드웨어에 맞게 툴을 만들었기 때문에 자연스럽게 일어난 현상임"
-
-
복잡한 주제임에도 읽기 쉽고 단순하게 잘 설명되어서 너무 좋았음
아직도 열정적인 사람들이 현상 유지를 깨고 어려운 과제에 도전하는 것이 감탄스러움
매달 컴퓨터 하드웨어는 발전하는데 소프트웨어는 더 느려지는 현상이 비정상적으로 느껴짐
효율적인 코딩을 모두가 더 잘했으면 하는 바람임- bun이 Zig로 작성된지 몰랐음
Zig는 굉장히 새로운 언어인데, 실무에서 본격적으로 쓰이는 모습이 흥미로움
- bun이 Zig로 작성된지 몰랐음
-
bun을 처음 써봤는데 매우 인상적이었음
내장 서버와 SQLite 덕분에 bun 하나만 설치하면 되어서 개발이 훨씬 편함
평소에 vanilla js만 쓰면서도 node 생태계를 별로 좋아하지 않았는데, 더 일찍 bun을 써봤어야 했다고 생각함-
Bun을 여러 번 시도해봤는데 사용 경험이 매우 만족스러웠음
Node보다 더 좋게 느꼈음
하지만 항상 결정적인 문제에 부딪히게 되어 결국 Node로 돌아감
처음엔 crypto 모듈이 Nodejs와 호환 안 됐고(지금은 수정됨), 다음엔 Playwright가 Bun에서 작동하지 않았음 -
요즘 Node도 내장 서버와 SQLite 지원함
더 많은 기능이 필요하다면 Hono도 좋은 대안임
-
-
기사에서 리눅스의 하드링크와 MacOS의 clonefile이 동등하다고 설명한 부분이 잘 이해가 안 됨
하드링크의 경우 하나의 복사본을 수정하면 모든 프로젝트의 파일이 예상치 않게 바뀌는 것 아닌지 궁금함 -
기술적으로 꽤 복잡한 설명인데도 정말 읽기 쉽고 유쾌하게 작성됨에 감탄함
- Lydia는 복잡한 개념을 쉽게 전달하는 데 매우 능숙함
그녀의 대부분 작업물과 영상을 봤는데, 깊이 있게 준비하는 게 느껴짐
시간이 된다면 그녀의 아티클과 YouTube 컨텐츠 적극 추천함
최근엔 아마 현 직장 때문에 활동이 줄어든 것 같음
- Lydia는 복잡한 개념을 쉽게 전달하는 데 매우 능숙함
-
Binary Manifest Caching 섹션에서 "npm (cached)"의 벤치마크 시간이 누락된 것 같음
bun, bun (cached), npm만 있고, 요약 통계도 제대로 안 맞는 것 같음 -
이 게시물의 문체가 너무 마음에 들었음
io_uring의 중요성을 설명하기에 이 글이 아주 좋은 사례로 리포지션 가능할 것 같음
Zig의 최근 v0.15 io 업데이트가 Bun의 성능에 추가적인 이점을 줄 수 있을지 궁금함 -
1년 넘게 bun을 기대해오고 있음
2025년이 bun의 대중화 원년이 될 거라 생각했는데, 의외로 아직 그렇게 인기 있지 않음
GitHub 상위 10만개 레포에서 2025년 기준 신규 레포는 npm이 35배, pnpm이 11배 더 많이 쓰임
Deno도 생각보다 인기가 그렇게 높지 않음
이유가 뭘까 궁금함
런타임은 패키지 매니저보다 호환성 맞추기가 더 어렵기 때문인지?
bun을 시도했다가 채택하지 않은 분들의 의견이 듣고 싶음
관련 참고 통계
관련 HN 댓글-
Bun과 Deno 둘 다 좋아하고 싶어서 여러 번 시도했지만, 결국 결정적 결함을 만나서 더 이상 못 써본 경험임
최근 Bun에서 겪은 가장 큰 문제는 스트림이 조기에 닫히는 이슈였고
관련 이슈 링크
Deno에선 메모리 누수 문제를 만났음
관련 이슈 링크
결국 Node 생태계가 Bun/Deno의 장점들을 먼저 받아들일 것 같다는 생각임 -
Bun은 신규 벤처캐피털 자금이 들어간, 검증된 오픈소스 대세 제품(Node)과 경쟁하는 신예임
락인 유인이 있고, 결국 Node와 근본적으로 크게 다르지 않음
전략적인 강점이 뚜렷하지 않고, Node로 할 수 없는 뭔가 새로운 걸 제공하지 않음
실제로 진지하게 쓰는 사례는 못 봤고, 가볍게 쓰는 사례만 봤음 -
이슈 트래커를 보면 Zig라는 언어가 굉장히 안전하지 않아서 그런지 크래시가 자주 발생함
나는 Node에 남을 예정임 -
나도 다른 분 의견이 궁금함
내 생각엔 Node는 프로젝트로서 성숙하고, 민주적이며 커뮤니티 주도 느낌이 강함
io.js 포크 사태도 잘 극복했기 때문임
반면 bun이나 deno는 둘 다 VC 지원을 받는 프로젝트라서 민주적인 커뮤니티 주도라고 느껴지지 않음 -
나는 Bun의 열렬한 팬임
가능한 모든 프로젝트에 Bun을 쓰고, 각종 one-off 스크립트도 Bun/TS로 씀
다만 소수지만 걱정되는 이슈가 있어서 프로덕션 배포는 아직 망설여짐
예를 들어, 단순한 Express 웹서버를 Docker에서 띄웠을 때 bun으로 구동하면 멈추는 현상이 있었음
node로만 바꾸면 정상작동함
1년 전엔 Bun + Prisma 조합에서 메모리 누수로 서버가 죽는 현상도 있었음(아마 지금은 고쳐졌으리라 예상함)
그럼에도 Bun이 워낙 좋아서 이런 단점 감수해도 전체적으로 개발 시간을 줄여줌
트랜스파일, 모듈, 워크스페이스 등에서 오는 편의성이 엄청남
아직 npm만큼 대중화되지 않은 것도 충분히 이해함
-
-
이 글을 읽는 게 너무 즐거웠음
소프트웨어 개발에서 컴퓨터과학 원리가 실제로 얼마나 중요한지 잘 보여주는 사례임
Big O, 시간/공간 지역성, 알고리즘 복잡도, 유저/커널스페이스, 파일 시스템, copy-on-write 등
이런 저수준 패키지 개발에선 CS 프로그램에서 배우는 모든 개념이 실제로 활용됨- 이건 사실 컴퓨터과학(CS)이 아니라 소프트웨어공학(SE)에 가까움
CS는 계산과 이론(프로그래밍 언어, 알고리즘, 암호화, 머신러닝 등)을 연구하고
SE는 확장성 있고 신뢰성 높은 소프트웨어를 구축하는 엔지니어링 원칙을 적용함
- 이건 사실 컴퓨터과학(CS)이 아니라 소프트웨어공학(SE)에 가까움
-
압축 파일을 다 읽고 나서 풀기를 기다리는 게 왜 유리한지 잘 이해가 안 됨
다운로드가 끝나기 전부터 압축 해제를 시작하는 게 메모리 재복사 횟수 늘어나는 불이익보다 도리어 더 이득이 있을 것이라고 추정함