TechFeedTechFeed
Programming Languages

Bun, 노드, pnpm | 패키지 설치가 5배 빠르면 실제로 바꿔야 하나?

2026년 기준 Bun이 npm·pnpm보다 빠른 이유(JavaScriptCore·하드링크 캐시)와 실제 속도 비교 수치, Next.js 프로젝트 설치 방법, 네이티브 바인딩 패키지·Vercel 배포·Windows 호환 문제까지 1인 개발자 관점으로 정리한다. TypeScript 스크립트 직접 실행 사례 포함.

by

Bun이 npm보다 패키지 설치가 5배, 스크립트 실행이 3배 빠르다는 벤치마크는 2023년부터 돌았습니다. 2026년 기준으로는 Bun이 쓸 만한 수준인지, 아니면 호환성 구멍이 여전한지가 실제 질문입니다. 저는 Next.js 12개 사이트를 운영하면서 pnpm을 기본으로 쓰다가 Bun을 세 프로젝트에 적용했고, 속도는 확실히 체감했지만 막히는 자리도 뚜렷했습니다.


이 글은 npm·pnpm·Bun의 속도 비교, Next.js 프로젝트에서 Bun이 막히는 패턴, 1인 개발자 기준으로 언제 쓰고 언제 안 쓰는지를 정리합니다. Bun 런타임을 테스트 러너·번들러로 쓰는 이야기는 별도 글로 뺐고, 여기는 패키지 매니저와 스크립트 실행만 봅니다.


Bun이 빠른 이유

Bun은 Node.js가 아닙니다. 내부 엔진이 V8이 아니라 JavaScriptCore(WebKit)입니다. 단지 Node.js 호환 API를 구현한 별도 런타임입니다. 패키지 설치 속도가 빠른 이유는 세 가지입니다.


첫째, 전역 캐시를 하드링크로 씁니다. 같은 패키지 버전은 디스크에 한 번만 쓰고 프로젝트마다 링크만 이어 붙입니다. pnpm의 symlink 방식과 비슷하지만 Bun은 기본적으로 더 공격적으로 캐시를 재사용합니다. 둘째, lockfile 파싱과 의존성 해석을 Zig으로 구현해서 V8 위에서 도는 npm·pnpm보다 파싱 단계가 빠릅니다. 셋째, HTTP 요청을 병렬로 때리는 concurrency가 npm보다 높습니다.


항목npmpnpmBun
엔진Node.js (V8)Node.js (V8)JavaScriptCore (Zig)
캐시 방식node_modules 복사전역 store + symlink전역 store + 하드링크
lockfilepackage-lock.jsonpnpm-lock.yamlbun.lock (바이너리)
설치 속도 (캐시 없음, Next.js 신규)약 40~60초약 20~30초약 6~12초
설치 속도 (캐시 있음)약 15~25초약 4~8초약 0.3~1초
workspace 지원있음있음있음 (v1.0+)

숫자는 2026년 8월 M2 맥북에서 Next.js 15 신규 프로젝트 기준입니다. 캐시가 채워진 뒤 bun install의 0.3초는 처음 보면 당황스럽습니다. 실제로 설치가 된 건지 의심이 될 정도입니다.


터미널에 bun install 실행 결과가 0.3초로 표시된 화면
Bun 캐시가 채워진 뒤 재설치는 1초 미만이 일반적이다

Next.js 프로젝트에 Bun을 붙이는 순서

Bun을 설치하는 방법은 공식 문서 기준으로 단순합니다. 맥이나 리눅스는 curl 스크립트 한 줄, 윈도우는 PowerShell입니다. 버전 관리가 필요하면 miseasdf에 Bun 플러그인을 붙이는 게 낫습니다.


Bun 설치와 기본 확인
# macOS / Linux curl -fsSL https://bun.sh/install | bash # 버전 확인 bun --version # 1.x.x # 기존 Next.js 프로젝트에서 node_modules 지우고 bun으로 재설치 rm -rf node_modules .next bun install # 개발 서버 실행 bun run dev # 빌드 bun run build

기존 package.json은 그대로 씁니다. bun installbun.lock을 새로 만듭니다. 팀 프로젝트라면 lockfile 전환을 공유하기 전에 먼저 로컬에서 충분히 테스트해야 합니다. npm이나 pnpm으로 설치한 node_modules와 Bun으로 설치한 node_modules의 구조가 다를 수 있기 때문입니다.


CI 환경에서는 bun install --frozen-lockfile을 씁니다. npm의 ci나 pnpm의 --frozen-lockfile과 같은 역할입니다. lockfile이 바뀌면 실패합니다.


bun.lock은 바이너리 포맷 | bun.lock은 텍스트가 아닙니다. git diff에서 보기 어렵습니다. PR 리뷰에서 lockfile 변경을 검토하려면 bun install --save-text-lockfilebun.lockb를 텍스트 포맷으로 저장하는 옵션을 씁니다. 팀이 있으면 이 설정을 통일하는 게 좋습니다.


Next.js에서 Bun이 막히는 패턴

속도는 확실히 빠르지만 막히는 자리가 있습니다. 제가 직접 만난 세 가지입니다.


⚠️ 네이티브 모듈(better-sqlite3, sharp 등) | Bun이 Node.js ABI 호환 레이어를 제공하지만, 네이티브 바인딩 패키지는 Bun용 사전 빌드가 없으면 설치 실패가 납니다. sharp는 Bun 공식 지원 목록에 들어갔지만 버전에 따라 달라집니다. better-sqlite3는 Bun 자체 SQLite API(bun:sqlite)로 교체하면 더 빠릅니다.


⚠️ Node.js-only API 의존 패키지 | child_process.fork, cluster 모듈을 직접 쓰는 패키지는 Bun에서 동작이 다릅니다. Vercel 배포 환경에서 bun run build를 쓰는 게 아니라 서버 런타임을 Bun으로 교체하는 경우라면 특히 주의합니다.


⚠️ Vercel 배포는 여전히 Node.js | Vercel 빌드 환경은 Node.js를 씁니다. bun run build로 로컬 프리빌트를 만들어 올리는 방식이 아니면, Vercel 서버에서 Bun을 쓰지 않습니다. 로컬 개발 속도를 올리는 용도로는 충분하지만, 프로덕션 런타임이 Bun으로 바뀌는 건 아닙니다.


개발 서버 터미널과 패키지 매니저 설치 속도 비교 화면
캐시 없는 첫 설치에서도 Bun은 npm 대비 4~6배 빠르다

Bun을 쓰면 이득인 경우, 아닌 경우

모든 프로젝트에 Bun을 권하지는 않습니다. 제가 판단 기준으로 쓰는 분류입니다.


상황Bun 적합이유
신규 개인 프로젝트✅ 추천lockfile 전환 비용 0, CI도 직접 설정
팀 프로젝트 (3명+)⚠️ 논의 필요lockfile 형식 통일, Windows 개발자 있으면 확인 필수
네이티브 바인딩 패키지 다수❌ 보류호환 여부를 패키지마다 확인해야 함
CI 캐시가 없는 환경✅ 효과 큼캐시 없는 콜드 설치에서 속도 차이가 가장 뚜렷
스크립트 실행 속도✅ 체감 확실ts-node 대신 bun {파일}.ts로 바로 실행, 타입 체크 없음

1인 개발자라면 진입 비용이 거의 없습니다. 신규 프로젝트를 시작할 때 bun create next-app으로 시작해 보는 게 빠른 방법입니다. 기존 프로젝트는 node_modules만 지우고 bun install을 돌려보면 막히는지 바로 나옵니다.


TypeScript 스크립트를 Bun으로 바로 실행하기

저는 자동화 스크립트를 TypeScript로 씁니다. 예전에는 ts-nodetsx를 써서 실행했는데, Bun은 설치 없이 .ts 파일을 바로 실행합니다. 타입 검사는 하지 않고 트랜스파일만 합니다. 빠르게 돌릴 스크립트에는 충분합니다.


Bun으로 TypeScript 스크립트 바로 실행
# ts-node 대신 bun scripts/generate-sitemap.ts # 환경 변수 주입 SITE_ID=tech bun scripts/daily-runner.ts # 의존성이 있어도 node_modules 없이 실행 (bun이 자동 설치) bun --install=auto scripts/fetch-data.ts

Bun이 타입을 무시하고 실행한다는 점은 로컬 스크립트에서는 크게 불편하지 않습니다. 타입 검사가 필요하면 tsc --noEmit으로 따로 돌리면 됩니다. 스크립트 실행 속도만 보면 ts-node보다 체감이 확실합니다.


공식 문서는 bun.sh/docs에서 확인합니다. 런타임으로 Bun을 쓰는 케이스는 Node.js 호환 API 목록을 먼저 체크합니다.


TypeScript 스크립트를 Bun으로 실행하는 터미널 화면
bun scripts/generate-sitemap.ts — ts-node 없이 바로 실행된다

자주 묻는 것들

Bun으로 바꾸면 package.json scripts도 바꿔야 하나?

바꿀 필요 없습니다. bun run devpackage.jsonscripts.dev를 실행합니다. Node.js를 쓰던 스크립트를 그대로 씁니다. 단, 스크립트 안에 node -e 같이 명시적으로 Node.js를 부르는 부분이 있으면 Bun이 개입하지 않고 시스템의 Node.js를 그대로 씁니다.


기존 pnpm workspace 프로젝트를 Bun으로 바꿀 수 있나?

가능합니다. pnpm-workspace.yamlbun 섹션을 package.json에 추가하는 방식으로 전환합니다. Bun도 workspaces 필드를 읽습니다. 다만 pnpm-lock.yamlbun installbun.lock으로 교체합니다. 팀 전체가 Bun을 설치해야 하는 전제 조건이 있습니다.


CI(GitHub Actions)에서 Bun을 쓰려면?

oven-sh/setup-bun 공식 액션을 씁니다. Node.js setup과 비슷하게 버전을 고정합니다. bun install --frozen-lockfile으로 lockfile과 다르면 실패하게 합니다. 캐시는 ~/.bun/install/cache를 actions/cache로 잡으면 됩니다.


Windows에서도 Bun이 잘 되나?

Bun 1.0부터 Windows 공식 지원이 들어갔습니다. 단, 일부 Unix 전용 API(Bun.spawn의 signal 처리 등)는 Windows에서 동작이 다릅니다. 팀에 Windows 개발자가 있으면 먼저 테스트해 보는 게 안전합니다.


Bun과 pnpm 중 어느 쪽이 더 성숙한가?

pnpm은 2016년부터 프로덕션에서 쓰인 패키지 매니저입니다. Bun은 2023년부터입니다. 엣지 케이스 안정성은 pnpm이 앞섭니다. 반면 속도와 개발 경험은 Bun이 앞섭니다. 저는 신규 개인 프로젝트에는 Bun, 기존 팀 프로젝트에는 pnpm을 유지하는 방식을 씁니다.


Bun노드pnpmnpm런타임패키지 매니저개발자백엔드프론트엔드Next.js성능마이그레이션

함께 보면 좋은 문제 해결

EXPLORE / Programming Languages

이어서 읽어보기

전체 토픽 둘러보기