Bun 런타임 Node.js 마이그레이션 가이드 — 호환성 점검과 3단계 전환

백엔드 2026년 8월 6일  ·  2026. 10. 30 업데이트  ·  junetapa  ·  약 12분

Bun을 Node.js의 «빠른 대체재»로만 보면 마이그레이션 판단이 엇나간다. 두 JavaScript 런타임은 엔진, 들어 있는 도구, TypeScript 처리 방식, 지원 정책이 다르다. 이 글은 Bun 1.4와 Node.js 26 LTS 시점의 공식 문서를 기준으로, 옮기기 전에 확인할 호환성 경계와 되돌릴 수 있게 나눠 옮기는 3단계 순서를 정리했다.

Bun과 Node.js는 무엇이 다른 구조인가

엔진과 구현 언어

Node.js는 Chrome의 V8 엔진과 비동기 I/O 라이브러리 libuv 위에 있고, 런타임은 C++와 JavaScript로 쓰여 있다. Bun은 공식 문서 기준 Safari가 쓰는 JavaScriptCore 엔진 위에 Zig로 구현됐다. 엔진이 다르다는 것은 취향 문제가 아니다. 힙 스냅샷이나 CPU 프로파일을 V8 인터페이스로 모으는 계측 도구는 엔진이 바뀌면 동작을 보장할 수 없다. JIT 최적화와 가비지 컬렉션 동작도 엔진마다 달라서, 같은 코드가 같은 메모리 곡선을 그린다고 가정하면 안 된다.

런타임에 무엇까지 들어 있는가

Node.js는 런타임을 주고, 패키지 매니저(npm 동봉)·번들러·트랜스파일러는 생태계 도구를 골라 붙이는 구조다. 근래 판에서 테스트 러너(node:test), .env 파일 읽기, TypeScript 타입 제거 실행처럼 외부 도구가 맡던 일이 런타임 안으로 들어왔지만 번들링은 여전히 바깥 도구 몫이다. Bun은 반대 방향이다. 런타임, 패키지 매니저(bun install), 테스트 러너(bun test), 번들러(bun build)를 실행 파일 하나에 담는다. 도구 체인이 줄어드는 것은 이점이지만, 각 기능이 전용 도구만큼의 옵션과 플러그인을 갖췄는지는 항목별로 확인해야 한다.

지금 판(2026-10-30 확인)

런타임최신 판나온 날상태
Bun1.4.42026-10-22안정판
Node.js 2626.13.02026-10-28LTS(Lithium) — 2026-10-28 LTS 시작
Node.js 2424.22.22026-10-27LTS(Krypton) — 2026-10-20부터 유지 보수 단계
Node.js 2222.23.42026-10-20LTS(Jod) — 2027-04-30 지원 종료

Node.js 판은 Node.js Release 저장소의 일정표 기준이다. 아직 Node.js 22를 쓰는 서비스라면, Bun으로 옮기는 것과 별개로 2027년 4월 말 전에 24 또는 26으로 올리는 일정이 먼저 잡혀 있어야 한다.

TypeScript 실행 — 같은 .ts라도 규칙이 다르다

Bun은 트랜스파일러를 내장해 .ts·.tsx를 빌드 단계 없이 실행한다. Node.js도 이제 타입 표기를 지우고 바로 실행한다. 다만 Node.js 공식 문서를 보면 조건이 꽤 많다.

항목Node.js(타입 제거)Bun
기본 켜짐v22.18.0·v23.6.0부터, 안정 표시는 v24.12.0·v25.2.0부터처음부터 기본
enum·런타임 코드가 있는 namespace·매개변수 프로퍼티·데코레이터지원 안 함(ERR_UNSUPPORTED_TYPESCRIPT_SYNTAX)트랜스파일로 실행
변환 플래그--experimental-transform-types는 v26.0.0에서 빠짐해당 없음
tsconfig.json읽지 않음(paths 등 안 됨)경로 설정 등을 읽음
import 경로확장자 필수(./file.ts) · 타입만 가져올 때 import type 필수확장자 생략 가능
.tsx · node_modules 안의 .ts지원 안 함 · 거부실행
타입 검사하지 않음(타입 자리를 공백으로 바꿈)하지 않음

두 런타임 모두 타입 검사를 대신하지 않는다는 점은 같다. 그래서 어느 쪽으로 가든 CI에는 tsc --noEmit 단계를 남긴다. Bun에서 잘 돌던 코드를 Node.js로 되돌릴 때 걸리는 것도 대부분 이 표의 enum·확장자·import type 줄이다. 되돌릴 길을 열어 두려면 처음부터 Node.js 규칙 쪽에 맞춰 쓰는 편이 안전하다. 타입 쪽 패턴은 TypeScript 5 실무 필수 패턴 총정리에 따로 모았다.

옮기기 전에 확인할 호환성 경계

Bun 문서는 Node.js API 호환을 거의 100%까지 끌어올리는 것을 목표로 적고, 릴리스마다 프레임워크와 npm 패키지를 Node.js 시험 묶음으로 확인하며, Node.js에서 되는데 Bun에서 안 되는 패키지는 Bun의 버그로 본다고 밝힌다. 바꿔 말하면 호환은 목표이자 진행 중인 상태다. 프로젝트가 실제로 쓰는 API가 호환 표의 어디에 있는지가 판단 기준이다.

번의 노드 에이피아이 호환 경계를 영역별로 정리한 도해
「호환을 목표로 한다」는 말과 「전부 된다」는 말은 다르다.

내장 모듈 — 공식 호환 표에서 갈리는 곳

모듈상태(Bun 문서)걸리는 부분
node:cluster일부 구현프로세스 사이 HTTP 부하 분산은 Linux(SO_REUSEPORT)에서만
node:v8일부 구현힙 스냅샷·통계는 되지만 힙·CPU 프로파일링, promiseHooks 등 빠짐 · 직렬화 형식이 V8과 다름
node:inspector일부 구현Runtime.evaluate·HeapProfiler 미구현, Network 없음
node:worker_threads일부 구현resourceLimits 무시 · 일부 API 없음
node:child_process일부 구현«advanced» 직렬화는 Bun끼리만 → Node.js와 IPC는 JSON
node:vm전체 구현ES 모듈 클래스까지
node:http2전체 구현Node.js 시험 묶음 94% 통과 · 일부 옵션은 받기만 함
node:dgram전체 구현시험 묶음 99% 통과

확인 순서는 코드가 실제로 import하는 node: 내장 모듈 목록을 뽑는 데서 시작한다. 위 표처럼 런타임 내부에 붙은 모듈(cluster·v8·inspector)일수록 차이가 생기기 쉽다.

네이티브 애드온

Bun 문서는 Node-API를 처음부터 새로 구현해 «기존 Node-API 확장 대부분이 그대로 동작한다»고 적고, .node 파일을 require()로 바로 불러올 수 있다고 설명한다. «대부분»이라는 표현이 핵심이다. 의존성 트리에 네이티브 빌드가 든 패키지가 있다면 설치·로딩·실행을 대상 아키텍처에서 각각 확인한다.

운영 도구

애플리케이션이 문제없이 떠도 운영 도구가 따라오지 못하면 옮기기는 실패한다. APM 에이전트, 분산 추적 SDK, 힙 덤프 수집기 상당수는 V8이나 Node.js 내부 훅에 기댄다. 위 표의 node:v8·node:inspector 줄이 바로 그 자리다. 디버거 연결, 프로파일 수집, 커버리지 산출이 기존 파이프라인과 맞물리는지를 코드 옮기기와 같은 무게로 점검한다.

설치 환경과 지원 기간

Bun이 도는 곳

설치는 macOS·Linux에서 curl -fsSL https://bun.com/install | bash, Windows에서 PowerShell 설치 스크립트, 또는 npm install -g bun으로 한다. 오래된 CPU를 쓰는 사내 빌드 서버라면 SSE4.2 조건부터 확인한다. 서버리스 플랫폼은 플랫폼마다 제공하는 런타임 목록이 다르므로 각 플랫폼 문서를 따로 본다. 컨테이너 빌드 파이프라인 구성은 Docker + GitHub Actions CI/CD 완전 가이드에 정리했다.

지원 기간 — Node.js는 일정표가 있다

Node.jsLTS 시작유지 보수 시작지원 종료
22(Jod)2024-10-292025-10-212027-04-30
24(Krypton)2025-10-282026-10-202028-04-30
26(Lithium)2026-10-282027-10-202029-04-30

Node.js는 메이저 판마다 LTS 시작·유지 보수·종료 일정을 공개한다. 도입 심사나 보안 감사에서 이런 문서를 요구하는 조직이라면, Bun 쪽에 같은 형태의 장기 지원 줄과 취약점 대응 절차가 공지돼 있는지를 도입 전에 직접 확인한다. 이 항목은 기술보다 계약·감사 쪽에서 막히는 경우가 많다.

벤치마크를 읽는 기준

숫자보다 조건을 먼저 본다

Bun 공식 사이트와 저장소는 자체 측정한 벤치마크를 싣는다. 만든 쪽이 자기 제품에 맞는 시나리오를 고르는 것은 자연스러운 일이므로, 숫자보다 측정 조건을 본다. 어떤 작업을, 어떤 하드웨어에서, 어떤 판으로, 어떤 프레임워크와 데이터베이스 접근 방식으로 쟀는지다. 조건과 코드가 공개되지 않은 수치는 비교 근거로 쓰지 않는다.

벤치마크 숫자를 읽을 때 확인할 조건을 정리한 도해
자체 측정 벤치마크는 «조건»을 보고 읽는다.

내 서비스에서 재는 두 구간

두 런타임을 직접 비교한 수치는 Node.js와 Bun 성능 비교 글에서 따로 다뤘다. 다만 어느 자료든 자기 워크로드에서 다시 재 본 숫자가 최종 근거다.

3단계로 나눠 옮기기

전면 교체는 되돌리기 비용이 크다. 위험을 낮추는 순서는 도구부터 붙이는 것이다.

단계바꾸는 것그대로 두는 것되돌리는 법
1. 설치bun install서비스 런타임(Node.js)원래 잠금 파일로 npm ci
2. 스크립트·시험bun run · bun test서비스 런타임package.json 스크립트 원복
3. 서비스 런타임프로세스를 bun으로 실행Node.js 이미지·배포 설정(보관)이전 이미지로 재배포

1단계 — 잠금 파일 옮기기

Bun 문서 기준으로 bun.lock이 없는 프로젝트에서 bun install을 돌리면 package-lock.json(잠금 파일 판 2~4)·npm-shrinkwrap.json·yarn.lock·pnpm-lock.yaml을 자동으로 옮기고, 원래 파일은 지우지 않고 남긴다. 설치 없이 옮기기만 하려면 bun pm migrate 또는 bun install --lockfile-only를 쓴다. 기본 잠금 파일은 Bun 1.2부터 텍스트 형식 bun.lock이라 코드 리뷰에서 의존성 변경을 읽을 수 있다. 예전 바이너리 bun.lockb가 남아 있다면 문서의 명령으로 텍스트판을 만든 뒤 지운다.

# 예전 bun.lockb → bun.lock
bun install --save-text-lockfile --frozen-lockfile --lockfile-only

# 설치 없이 npm·yarn·pnpm 잠금 파일만 옮기기
bun pm migrate

1단계만으로도 CI 설치 시간이라는 이득을 먼저 가져오면서 애플리케이션 런타임은 건드리지 않는다. 옮기는 기간에는 두 잠금 파일이 함께 있으므로, 어느 쪽이 기준인지 팀 규칙으로 정해 둔다.

2단계 — 스크립트와 시험

package.json 스크립트와 시험 실행을 Bun으로 옮겨 본다. 이 단계에서 2절의 TypeScript 규칙 차이와 3절의 내장 모듈 차이가 대부분 드러난다. 드러난 비호환 항목은 목록으로 남겨 3단계 판단 근거로 쓴다.

3단계 — 서비스 런타임

그때까지 드러난 비호환 항목을 정리한 뒤에야 서비스 프로세스의 런타임 교체를 논의한다. 되돌릴 기준은 미리 문장으로 적어 둔다. 예를 들어 «특정 내장 모듈 미지원이 확인되거나, 관측 파이프라인이 일주일 안에 복구되지 않으면 되돌린다» 같은 식이다. Express 기반 서버라면 Node.js Express 서버 가이드의 미들웨어 구성을 기준으로 하나씩 확인한다.

어떤 경우에 맞는가 — 정리

항목Node.jsBun
엔진V8JavaScriptCore
구현 언어C++ · JavaScriptZig
패키지 매니저npm 동봉, pnpm·yarn 선택bun install 내장(다른 잠금 파일 자동 옮김)
테스트 러너node:test 내장bun test 내장
번들러없음(외부 도구)bun build 내장
TypeScript 실행타입 제거 · enum 등 안 됨 · .tsx 안 됨.ts·.tsx 바로 실행
네이티브 애드온기준 구현Node-API 대부분 동작 · 패키지별 확인
지원 기간메이저별 LTS 일정 공개도입 전 공식 공지 확인

Bun을 검토할 조건

Node.js를 유지할 조건

결론은 양자택일이 아니다. Bun과 Node.js는 겹쳐 쓸 수 있는 도구이고, 패키지 설치와 시험 실행만 먼저 붙여 보는 1·2단계가 대부분의 팀에 위험 대비 효용이 가장 좋다. 어느 쪽을 고르든 근거는 공식 호환 표에서 확인한 지원 범위와, 자기 워크로드에서 직접 잰 수치여야 한다.

Bun 런타임 Node.js 마이그레이션 가이드 대표 그림 — 왼쪽에 제목 글자가 있고, 오른쪽에 두 개의 엔진 블록 사이로 짐 상자가 세 단계 다리를 건너 옮겨지는 장면
Bun 런타임 Node.js 마이그레이션 가이드 — 호환성 점검과 3단계 전환.

자주 묻는 것

Bun으로 바꾸면 Node.js 패키지가 그대로 돌아가나요?

Bun 문서는 Node.js API 호환을 거의 100%까지 목표로 하고, Node.js에서 되는데 Bun에서 안 되는 패키지는 Bun의 버그로 본다고 적습니다. 다만 node:cluster·node:v8·node:inspector 같은 모듈은 일부 구현 상태이므로, 프로젝트가 쓰는 내장 모듈을 호환 표와 대조한 뒤 옮깁니다.

package-lock.json을 bun.lock으로 바꿔야 하나요?

bun.lock이 없는 프로젝트에서 bun install을 돌리면 package-lock.json·yarn.lock·pnpm-lock.yaml을 자동으로 옮기고 원래 파일은 남깁니다. 설치 없이 옮기려면 bun pm migrate를 씁니다. 옮기는 기간에는 어느 잠금 파일이 기준인지 팀 규칙으로 정해 둡니다.

Node.js도 TypeScript를 바로 실행하는데 차이가 있나요?

Node.js는 v22.18.0부터 타입 표기를 지우고 실행하지만 enum·데코레이터 같은 문법과 .tsx를 지원하지 않고, tsconfig.json을 읽지 않으며 import에 확장자가 필요합니다. Bun은 .ts와 .tsx를 바로 실행합니다. 두 런타임 모두 타입 검사는 하지 않으므로 tsc 검사는 따로 둡니다.

운영 서비스까지 한 번에 Bun으로 옮겨도 되나요?

되돌리기 비용을 줄이려면 패키지 설치, 스크립트와 시험 실행, 서비스 런타임 순서로 나눠 옮기는 편이 안전합니다. 앞의 두 단계에서 드러난 비호환 항목과 운영 도구 동작을 확인한 뒤 서비스 런타임 교체를 정합니다.

참고 자료

  1. Bun Docs. Node.js compatibility — 호환 목표·모듈별 상태(cluster·v8·inspector·worker_threads·child_process 일부, vm·http2·dgram 전체)(2026-10-30 확인). bun.com
  2. Bun Docs. Node-API — 대부분의 Node-API 확장 동작·.node require(2026-10-30 확인). bun.com
  3. Bun Docs. Lockfile — bun.lock 텍스트 기본(1.2)·다른 잠금 파일 자동 옮김·bun pm migrate(2026-10-30 확인). bun.com
  4. Bun Docs. Installation — 지원 OS·CPU 조건·oven/bun 이미지(2026-10-30 확인). bun.com
  5. Bun GitHub 릴리스 — bun-v1.4.4(2026-10-22)(2026-10-30 확인). github.com
  6. Node.js Docs. Modules: TypeScript — 타입 제거 기본(v22.18.0·v23.6.0)·안정(v24.12.0·v25.2.0)·지원 안 하는 문법·--experimental-transform-types 제거(v26.0.0)·tsconfig 무시·확장자 필수(2026-10-30 확인). nodejs.org
  7. Node.js Release 일정표·배포 목록 — 22·24·26 LTS 시작·유지 보수·종료일, 26.13.0·24.22.2·22.23.4(2026-10-30 확인). github.com
Bun Node.js JavaScript 런타임 백엔드 junetapa
junetapa(박준철)
개발자가 아니라 쓰는 사람. IT 현장 27년의 기준으로 도구를 고르고 기록한다.
Share Twitter Facebook URL 복사