TrendShift 딥다이브 · 2026-07-11 · Daily #8

Bun 딥다이브
— 런타임·번들러·테스트러너·패키지매니저를 "단일 실행파일 하나"로 합친 JS 도구

BunJavaScript·TypeScript를 위한 올인원 툴킷이다. Node.js를 대체하는 런타임이면서, 동시에 번들러 · 테스트 러너 · 패키지 매니저까지 하나의 실행파일(bun) 안에 들어 있다. Node에서 "런타임은 node, 번들은 webpack/esbuild, 테스트는 jest, 설치는 npm"으로 4개 도구를 조합하던 걸, Bun은 전부 하나로 끝낸다. 엔진은 V8이 아니라 WebKit의 JavaScriptCore(JSC)를 쓰고, 코어는 원래 Zig로 짜였다가 지금은 Rust로 다시 쓰였다(이 클론 시점 기준 src/에 Zig 파일 0개 · Rust 파일 약 1,475개). 빠른 시작 시간과 낮은 메모리가 최대 무기다. (저장소: oven-sh/bun · 언어 Rust + C++ · 엔진 JavaScriptCore · MIT · 릴리스 v1.3.14 / main v1.4.0 · macOS·Linux·Windows · TrendShift 오늘 Daily 8위)
목차
  1. 프로젝트 한줄 요약
  2. 왜 주목받는가
  3. 기술 스택 전체 지도
  4. 아키텍처 심화 분석
  5. 디렉토리 구조 해부
  6. 학습 포인트 (기술별)
  7. 하드웨어 · 빌드 요구사항
  8. 직접 해볼 수 있는 실습 과제
  9. 관련 기술 심화 학습 로드맵
  10. 핵심 키워드 사전
  11. 참고 링크

1프로젝트 한줄 요약

이 저장소가 대체 무엇인가.

Bun"JavaScript를 실행하고, 묶고, 테스트하고, 패키지를 설치하는 일"을 전부 담당하는 하나의 프로그램이다. 명령어 bun 하나로 bun run app.ts(실행), bun install(설치), bun test(테스트), bun build(번들)이 모두 된다. TypeScript와 JSX는 별도 설정 없이 곧바로 돌아간다 — tscts-node 없이 bun app.ts가 바로 실행된다.

한 줄 개념
JavaScript 런타임 (JavaScript runtime)
브라우저 밖에서 JS/TS 코드를 실행해 주는 프로그램. 파일 읽기·네트워크·타이머 같은 "브라우저엔 없는 시스템 기능"을 JS에 열어준다. Node.js가 대표주자이고, Bun은 Node를 그대로 대체하도록(drop-in) 설계된 새 런타임이다. 여기에 번들러·테스트러너·패키지매니저까지 얹은 게 Bun의 정체성.
비유로 이해하기

"칼·가위·병따개가 따로 놀던 주방을, 스위스 아미 나이프 한 자루로 합친 것"

Node.js 시대의 개발자는 도구 서랍을 열 때마다 런타임(node) · 번들러(webpack/esbuild) · 테스트(jest/vitest) · 패키지매니저(npm/yarn/pnpm)를 따로 꺼내 조립했다. 버전이 안 맞아 싸우고, 설정 파일만 대여섯 개가 됐다.

Bun은 이 도구들을 단일 실행파일 하나에 통째로 내장한다. 게다가 그 칼날을 V8(구글 엔진)이 아니라 JavaScriptCore(애플 Safari 엔진)로 갈았고, 손잡이는 Rust로 깎았다 — 그래서 "켜는 순간(시작 시간)"이 유난히 빠르다.

라이선스는 관대한 MIT다(단, 내부에 정적 링크된 JavaScriptCore/WebCore는 LGPL-2라 재링크 조건이 붙는다). 개발사는 Oven이고, 최신 공개 릴리스는 v1.3.14, 개발 중인 main 브랜치는 v1.4.0이다. TrendShift에 오늘 Daily 8위로 올라 있다.

먼저 짚고 갈 것 — 이 문서의 초점
"빠른 Node 대체품"이 아니라 "언어 툴체인을 통째로 만드는 법의 교재"

"Node보다 빠르다"는 건 겉모습이다. 이 레포의 진짜 가치는 JS 엔진(JSC)을 시스템 언어(Rust/C++)로 임베딩하는 법 · TS/JSX 트랜스파일러와 번들러를 밑바닥부터 짜는 법 · npm 호환 패키지 매니저의 병렬 설치·락파일 설계 · 크로스플랫폼 셸(Bun.$)을 파서부터 구현하는 법 · Postgres·MySQL·Redis·S3 프로토콜을 네이티브로 구현하는 법하나의 실전 코드베이스에서 볼 수 있다는 점이다. "현대 JS 런타임은 실제로 무엇으로 이뤄지는가"의 해부도에 가깝다.

정확성 노트 — Zig가 아니라 Rust
"Bun = Zig"는 옛말이 됐다 (이 클론 기준)

널리 알려진 상식은 "Bun은 Zig로 짰다"이다. 실제로 초창기 Bun은 Zig로 작성됐다. 하지만 이 문서가 분석한 클론 시점의 소스는 Rust로 재작성돼 있다src/ 안 Zig 파일은 0개, Rust(.rs) 파일은 약 1,475개이며, 루트에 Cargo.toml·rust-toolchain.toml이 있고 저장소 자체의 CLAUDE.md도 "written primarily in Rust"라 명시한다. 남아 있는 "zig" 단어는 ZigGlobalObject처럼 이관 과정의 잔재다. 이 문서는 현재 소스 기준(Rust + C++)으로 서술한다.

2왜 주목받는가

트렌딩 이유와, Node.js·Deno 같은 경쟁 런타임 대비 결정적 차이.

① "네 개의 도구"를 "한 개의 파일"로 — 조립의 소멸

Node 생태계의 고질병은 도구 파편화였다. 실행은 node, 번들은 webpack/rollup/esbuild, 테스트는 jest/vitest, 설치는 npm/yarn/pnpm — 각각 설정 파일과 버전 궁합이 따로 놀았다. Bun은 이 넷을 단일 바이너리에 내장해, 설정 없이 bun install → bun test → bun build가 한 흐름으로 이어진다. "새 프로젝트를 시작할 때 도구 고르고 설정하는 시간"을 통째로 없앤 게 커뮤니티의 폭발적 반응을 만들었다.

② V8이 아니라 JavaScriptCore — 시작이 빠르다

Node와 Deno는 구글의 V8 엔진을 쓴다. Bun은 애플이 Safari에 쓰는 JavaScriptCore(JSC)를 임베딩한다. JSC는 일반적으로 프로세스 시작 시간이 짧고 초기 메모리가 가볍다는 특성이 있어, CLI 스크립트·서버리스 함수처럼 "짧게 켜졌다 꺼지는" 워크로드에서 체감 이득이 크다. 여기에 코어를 Rust로 짜고 마이크로소프트의 mimalloc 할당자를 링크해 오버헤드를 더 깎았다.

핵심 통찰

V8 = 시동에 시간이 걸리는 대형 디젤 엔진(정상 주행은 강력). JavaScriptCore = 즉시 붕 뜨는 경량 엔진(켜는 순간이 빠름). 웹 서버가 하루 종일 켜져 있다면 차이가 작지만, "함수가 요청마다 새로 켜지는" 서버리스나 매번 새로 뜨는 CLI에선 시작 시간이 곧 성능이다 — Bun이 노리는 지점이다.

③ Node.js 호환을 "1급 기능"으로 취급

새 런타임의 성패는 결국 "기존 npm 코드가 그대로 도나"에 달렸다. Bun은 Node.js drop-in 대체를 목표로, test/js/node/(Node 호환), test/napi/(N-API), test/v8/(V8 C++ API 호환)에 방대한 호환 테스트를 둔다. 이 클론의 최신 커밋조차 "node:worker_threads: Node.js 테스트 48개 추가 통과"라는 호환성 작업일 만큼, 호환은 계속 굴러가는 최우선 트랙이다. 패키지 매니저도 package.json·.npmrc·워크스페이스·overrides를 읽는 npm 호환이다.

④ "배터리 포함" 내장 API

Node에서 라이브러리를 깔아야 했던 기능들이 Bun엔 런타임에 내장돼 있다: Bun.serve(라우팅·WebSocket 포함 HTTP 서버), bun:sqlite(내장 SQLite), Bun.sql(Postgres·MySQL 클라이언트), Bun.redis(Redis/Valkey), Bun.s3(S3 클라이언트), Bun.$(크로스플랫폼 셸). "DB 붙이려고 드라이버 3개 설치"하던 과정이 사라진다.

한눈에 비교
측면Node.jsDenoBun
JS 엔진V8V8JavaScriptCore
코어 언어C++RustRust + C++
번들러외부(webpack 등)내장내장(bun build)
테스트러너node --test내장내장(bun test)
패키지매니저npm(별도)자체+npm내장·npm 호환
TS 실행별도 도구 필요기본 지원기본 지원
내장 DB없음KV 등SQLite·SQL·Redis·S3

※ 셋은 배타적이지 않다. 기존 Node 프로젝트에 Bun을 패키지 매니저로만 얹거나(bun install), CI의 테스트 러너로만 쓰는 식의 부분 도입도 흔하다.

3기술 스택 전체 지도

"런타임 + 툴체인 + 네이티브 프로토콜"을 한 바이너리에 담기 위한 스택.

코어 (뼈대)

영역사용 기술역할
코어 언어Rust (nightly, 툴체인 고정)런타임·번들러·패키지매니저 등 대부분. Cargo.toml 워크스페이스
엔진 바인딩C++20 (~575 .cpp · ~729 .h)JavaScriptCore와 Rust를 잇는 바인딩 계층
JS 엔진JavaScriptCore (WebKit 포크)정적 링크. 특정 WebKit 커밋에 고정
빌드 시스템CMake + Ninja + CargoTS 오케스트레이터(scripts/build.ts)가 지휘
컴파일러LLVM/Clang 21.1.8 (버전 엄격)C++ 컴파일. 버전 어긋나면 런타임 오류
메모리 할당mimalloc (마이크로소프트)기본 할당자 대비 빠른 멀티스레드 할당

내장 서브시스템 (Rust 크레이트로 분리)

기능소스 위치쓰임
CLI 서브커맨드src/cli/install·build·test·bunx·audit·publish 등 전부
패키지 매니저src/install/병렬 네트워크·타르볼 스트리밍·매니페스트 캐시
번들러/링커src/bundler/그래프·청크·링커 컨텍스트·HTML 스캐너
JS/TS 파이프라인src/js_parser · js_printer · transpiler · ast파싱→변환→출력. TS·JSX를 JS로
src/shell_parser/Bun.$ 크로스플랫폼 셸 파서(braces 확장 포함)
DB 클라이언트src/sql/postgres · mysql, src/valkey/Postgres·MySQL·Redis 프로토콜 네이티브 구현
CSSsrc/css/네이티브 CSS 파서·번들러·미니파이어
네트워킹src/http · src/uws (uSockets)고성능 HTTP·소켓 계층
JS 빌트인src/js/ (TypeScript)Node/Web API를 TS로 구현한 상위 계층
왜 언어가 세 개(Rust·C++·TS)인가
계층별 언어 분업
C++은 JavaScriptCore가 C++로 짜여 있어 엔진과 직접 맞닿는 바인딩에 불가피하다. Rust는 메모리 안전성을 얻으면서 시스템 성능을 내기 위한 코어 언어다. TypeScript는 Node/Web API처럼 "JS로 표현하는 게 자연스러운 상위 로직"과 빌드 스크립트에 쓴다. codegen(generate-classes.ts)*.classes.ts 정의 하나에서 Rust·C++ 바인딩을 자동 생성해 세 계층을 이어 붙이는 게 핵심 패턴이다.

번들 네이티브 라이브러리 (정적 링크)

Bun은 수많은 C/Rust 라이브러리를 정적 링크해 단일 바이너리로 만든다: boringssl(TLS) · zlib-ng·brotli·zstd(압축) · c-ares(DNS) · libuv(Windows 이벤트루프) · simdutf(초고속 UTF-8) · mimalloc(할당) · lol-html(HTML 스트리밍 파싱) · tinycc(FFI용 C 컴파일) · libarchive. *_sys 크레이트가 이들에 대한 FFI 바인딩을 담당한다.

4아키텍처 심화 분석

bun app.ts 한 줄이 실행되기까지, 그리고 코어가 어떻게 세 언어를 엮는가.

전체 구조도

$ bun app.ts (또는 bun install / test / build) | v ┌───────────────────────────────────────────────────────────┐ │ bun (단일 실행파일) │ │ │ │ src/cli/* ── 서브커맨드 라우팅 │ │ run / install / test / build / bunx / audit ... │ │ | │ │ ┌──────────┴──────────────┐ │ │ v v │ │ [JS/TS 파이프라인] [패키지매니저 / 번들러 / 셸] │ │ js_parser → transpiler install/ bundler/ shell/ │ │ → js_printer → ast (네트워크·링커·braces 확장) │ │ | │ │ v │ │ ╔═════════════════════════════════════════╗ │ │ ║ JavaScriptCore (JSC) 엔진 · C++ 바인딩 ║ │ │ ║ src/jsc/(Rust FFI) + *.cpp/*.h(C++) ║ │ │ ║ ← codegen이 *.classes.ts 에서 자동 생성 ║ │ │ ╚═════════════════════════════════════════╝ │ │ | │ │ [내장 API] Bun.serve · Bun.file · bun:sqlite · │ │ Bun.sql · Bun.redis · Bun.s3 · Bun.$ │ │ | │ │ [네이티브] uSockets · boringssl · mimalloc · simdutf │ └───────────────────────────────────────────────────────────┘ | v OS (파일·소켓·프로세스)

설계 패턴 ① — TS 정의 하나에서 바인딩을 "자동 생성"

JS 엔진을 시스템 언어에 임베딩할 때 가장 지겨운 일은 "JS에서 보이는 객체 ↔ 네이티브 구현"을 잇는 접착 코드(binding)를 손으로 쓰는 것이다. Bun은 src/codegen/generate-classes.tsFoo.classes.ts라는 선언 하나를 읽어 Rust와 C++ 양쪽 바인딩을 자동 생성하게 만들었다. 개발자는 "이 클래스에 이런 메서드가 있다"만 TS로 선언하면, JSC에 노출되는 C++ glue와 Rust 쪽 핸들이 함께 찍혀 나온다. 반복 실수를 없애는 코드 생성(codegen)의 교과서적 사례다.

비유

세 나라 말을 쓰는 팀(Rust·C++·JS)에서 회의록을 각자 번역하면 오역이 난다. Bun은 "원문(.classes.ts)을 한 번 쓰면 세 언어 번역본이 자동으로 찍히는 번역기"를 만들어 뒀다. 원문만 관리하면 되니 세 계층이 어긋날 일이 없다.

설계 패턴 ② — 번들러: 그래프 → 링커 → 청크

src/bundler/는 esbuild와 겨루는 자체 번들러다. 흐름은 모듈 의존 Graph 구성 → LinkerContext가 심볼을 잇고 트리셰이킹 → Chunk로 출력 분할이다. HTML을 진입점으로 받아 스크립트·CSS를 스캔하는 HTMLScanner, 전용 BundleThread까지 있어 "정적 사이트 빌드"도 런타임 안에서 처리한다. 파서(js_parser)·프린터(js_printer)가 번들러와 같은 코드베이스를 공유하는 게 속도 비결 — 트랜스파일과 번들이 중간 표현을 다시 만들지 않는다.

설계 패턴 ③ — 패키지 매니저: 병렬 네트워크 + 스트리밍 해제

bun install이 npm보다 빠른 이유는 src/install/에 있다. NetworkTask여러 패키지를 동시에 내려받고, TarballStream으로 타르볼을 디스크에 다 쓰기 전에 스트리밍으로 풀며, PackageManifestMap으로 매니페스트를 캐시한다. 락파일은 텍스트 기반 bun.lock이고, 워크스페이스·catalogs·overrides·isolated install까지 지원한다.

// bun install 의 개념 흐름 (src/install/)
1) package.json + bun.lock 파싱 → 의존성 그래프 해석
2) NetworkTask 병렬 실행    // 레지스트리에서 동시 다운로드
3) TarballStream 스트리밍 해제 // 받으면서 바로 풀기
4) 전역 캐시에 하드링크 → node_modules 구성
5) bun.lock 갱신            // 재현 가능한 설치

설계 패턴 ④ — 크로스플랫폼 셸 Bun.$

Bun.$Windows에서도 동일하게 도는 셸을 목표로, OS의 sh/cmd에 의존하지 않고 src/shell_parser/셸 문법 파서를 직접 구현했다. parse.rs(토큰·파이프·리다이렉트), braces.rs({a,b} 확장)가 핵심이다. 덕분에 await $`ls *.js | wc -l` 같은 코드가 macOS·Linux·Windows에서 똑같이 동작한다.

성능은 "숫자"가 아니라 "메커니즘"으로 이해하라
Bun이 빠른 진짜 이유
README는 특정 "N배 빠르다" 벤치 수치를 앞세우지 않는다(실측은 bench/ 디렉토리에 Node·Deno 대조군으로 있다). 빠름의 원천은 ① JSC의 짧은 시작 시간, ② Rust 네이티브 구현, ③ mimalloc 할당자, ④ simdutf 같은 SIMD 최적화, ⑤ 파서·번들러가 중간 표현을 공유하는 설계다. "왜 빠른가"를 이 다섯 축으로 설명할 수 있으면 충분하다.

5디렉토리 구조 해부

약 1.8만 개 파일 · 300MB 규모. 처음 열었을 때 길을 잃지 않도록.

bun/ ├─ src/ ← 코어 (104개 하위 디렉토리, Cargo 워크스페이스) │ ├─ cli/ · 모든 서브커맨드 (install/build/test/bunx/audit/publish...) │ ├─ jsc/ · JavaScriptCore Rust 바인딩 (CallFrame, CachedBytecode...) │ ├─ bun_core/ · 런타임 원시타입 (Global, 할당자) │ ├─ install/ · 패키지 매니저 (PackageInstaller, NetworkTask, TarballStream) │ ├─ bundler/ · 번들러/링커 (LinkerContext, Graph, Chunk, HTMLScanner) │ ├─ shell_parser/ · Bun.$ 셸 (parse.rs, braces.rs) │ ├─ sql/ · DB 클라이언트 (postgres/, mysql/, shared/) │ ├─ valkey/ · Redis/Valkey 클라이언트 │ ├─ css/ · 네이티브 CSS 파서·번들러 │ ├─ js_parser/ js_printer/ · JS/TS 파싱·출력 │ ├─ transpiler/ ast/ · 트랜스파일 파이프라인 │ ├─ http/ uws/ · HTTP·소켓 (uSockets) │ ├─ s3_signing/ dns/ · S3 서명·DNS 해석 │ ├─ resolver/ watcher/ · 모듈 해석·파일 감시(--hot) │ ├─ sourcemap/ semver/ glob/ · 소스맵·버전·글롭 │ ├─ crash_handler/ · 크래시 리포팅 │ ├─ js/ · TS로 짠 Node/Web API 빌트인 (builtins/, node/, bun/) │ └─ codegen/ · generate-classes.ts (Rust·C++ 바인딩 자동 생성) ├─ packages/ ← npm 배포 패키지 (bun-types, @types/bun ...) ├─ test/ ← 방대한 테스트 (js/node = Node 호환, napi, v8 ...) ├─ bench/ ← Node·Deno 대조 벤치마크 (37개 하위 디렉토리) ├─ docs/ ← 공식 문서 ├─ scripts/ ← 빌드 오케스트레이션 (build.ts, deps/webkit.ts) ├─ patches/ ← 의존성 패치 ├─ Cargo.toml ← Rust 워크스페이스 (핵심!) ├─ rust-toolchain.toml ← nightly 툴체인 고정 ├─ CMakeLists.txt ← C++/링크 빌드 ├─ package.json ← version 1.4.0 (main) └─ LATEST ← 1.3.14 (공개 릴리스)

번들러가 궁금하면 src/bundler/Graph.rsLinkerContext.rsChunk.rs 순서로, 패키지 매니저는 src/install/PackageInstaller.rsNetworkTask.rs로 읽으면 흐름이 잡힌다. "엔진을 어떻게 붙였나"가 궁금하면 src/codegen/generate-classes.ts와 아무 *.classes.ts 하나를 나란히 열어 선언 → 생성된 바인딩을 대조해 보라.

6학습 포인트 (기술별 배울 것)

이 레포를 "읽어서" 얻을 수 있는 구체적 기술 자산.

① JS 엔진을 시스템 언어에 임베딩하는 법 난이도 ★★★

JavaScriptCore를 C++로 붙이고 Rust에서 다루는 src/jsc/"엔진 임베딩"이라는 고급 주제의 실물 교재다. CachedBytecode.rs(바이트코드 캐시)·CallFrame.rs(호출 프레임)를 통해 JS 값이 네이티브에서 어떻게 표현·전달되는지 볼 수 있다.

② 코드 생성(codegen)으로 반복 접착 코드를 없애기 난이도 ★★★

generate-classes.ts단일 선언에서 두 언어 바인딩을 찍어내는 패턴은, 규모 있는 시스템에서 "손으로 쓰면 반드시 어긋나는 반복 코드"를 다루는 정석이다. DSL·codegen 설계 감각을 기르는 데 최적.

③ 번들러/트랜스파일러 내부 난이도 ★★★

파서→AST→링커→청크로 이어지는 src/bundler/·src/js_parser/esbuild류 번들러가 실제로 어떻게 동작하는지를 Rust로 보여준다. 트리셰이킹·심볼 링킹·소스맵 생성을 코드로 추적할 수 있다.

④ 빠른 패키지 매니저 설계 난이도 ★★☆

src/install/병렬 다운로드 · 스트리밍 타르볼 해제 · 전역 캐시 하드링크 · 텍스트 락파일은 "npm은 왜 느리고 무엇을 고치면 빨라지는가"의 답지다.

⑤ 크로스플랫폼 셸 파서 난이도 ★★☆

src/shell_parser/OS 셸에 의존하지 않는 셸을 직접 구현한 드문 사례. 토큰화·파이프·리다이렉트·brace 확장을 밑바닥부터 짜는 파서 실전.

실습 아이디어 (가볍게)

· *.classes.ts 하나를 골라 codegen이 만든 바인딩과 대조해 "선언 → 생성물" 매핑 그려보기.
· bench/의 벤치 하나를 Node·Bun으로 각각 돌려 시작 시간 차이를 직접 재보기.
· test/js/node/에서 실패하는 Node 호환 테스트를 찾아 "무엇이 아직 안 되나" 관찰하기.

7하드웨어 · 빌드 요구사항

그냥 쓰는 건 쉽지만, "소스에서 빌드"는 만만치 않다.

실행(사용) 요구사항 — 매우 가볍다

항목요구/권장
OSLinux(x64/arm64, 커널 ≥5.6 권장) · macOS(Intel/Apple Silicon) · Windows(x64/arm64)
설치curl -fsSL https://bun.sh/install | bash 또는 npm/brew/도커. 단일 바이너리라 별도 런타임 불필요
비용무료(MIT)

소스 빌드 요구사항 — 무겁다 (CONTRIBUTING.md 기준)

항목요구
디스크~10GB 여유 (JSC를 소스에서 빌드하면 WebKit 폴더만 8GB+)
Rustnightly (툴체인 rust-toolchain.toml에 고정, rustup 자동 설치)
컴파일러LLVM/Clang 21.1.8 — 버전 엄격 강제(어긋나면 런타임 메모리 오류)
빌드 도구CMake · Ninja · Go · Ruby · pkg-config · libtool · icu 등
초기 셋업10~30분 소요. 디버그 빌드는 기본 AddressSanitizer(빌드 ~2배 느림)
실전 팁
"쓰는 것"과 "빌드하는 것"의 난이도 차를 구분하라

Bun을 사용만 한다면 설치 스크립트 한 줄이면 끝이고 요구사항이 극히 가볍다. 하지만 소스를 빌드해 기여하려면 LLVM 버전·10GB 디스크·nightly Rust 등 장벽이 높다. 코드를 "읽기"만 할 거라면 빌드 없이 shallow clone(git clone --depth 1)으로 소스만 받아 src/를 탐색하는 게 효율적이다.

8직접 해볼 수 있는 실습 과제

읽기만 하지 말고 손을 움직여 볼 것. 난이도별로.

실습 1 · ★☆☆

TS 파일을 설정 없이 바로 실행

bun init으로 프로젝트를 만들고 index.ts에 타입을 붙인 코드를 짠 뒤 bun index.ts컴파일 단계 없이 실행. 같은 파일을 node로 돌려보며 "왜 Node는 안 되나"를 체감한다.

실습 2 · ★★☆

Bun.serve로 3분 만에 HTTP 서버 + WebSocket

Bun.serve({ fetch, websocket })로 라우팅·WebSocket이 내장된 서버를 띄워본다. Express·ws를 설치하던 것과 비교해 의존성 0개로 되는 범위를 확인.

실습 3 · ★★☆

내장 SQLite + Bun.$ 셸 섞어 쓰기

import { Database } from "bun:sqlite"로 DB를 만들고, await $`ls -la` 같은 셸 명령과 조합해 "런타임에 DB와 셸이 함께 있는" 워크플로를 만들어 본다.

실습 4 · ★★★

Node 프로젝트를 Bun으로 마이그레이션

기존 npm 프로젝트에서 bun install로 재설치하고 bun test·bun run으로 돌려본다. 무엇이 그대로 되고 무엇이 깨지는지(네이티브 애드온 등) 기록해 호환성의 경계를 파악한다.

실습 5 · ★★★

codegen 산출물 역추적

소스에서 *.classes.ts 하나를 골라 bun run build 과정에서 생성되는 Rust·C++ 바인딩을 찾아 대조한다. "선언 하나 → 두 언어 접착 코드"의 자동화 파이프라인을 눈으로 확인.

9관련 기술 심화 학습 로드맵

이 레포를 발판으로 "언어 런타임·툴체인"을 4주에 걸쳐 넓히는 경로.

주차주제할 것
1주런타임 기초이벤트 루프·JS 엔진 개념 정리 → Node vs Deno vs Bun 아키텍처 비교 → Bun 내장 API 실습
2주파서·트랜스파일렉서/파서·AST 개념 → 미니 JS 트랜스파일러 작성 → src/js_parser 구조 읽기
3주번들러모듈 그래프·트리셰이킹·소스맵 학습 → esbuild/Bun 번들러 흐름 추적 → 초미니 번들러 구현
4주엔진 임베딩·FFIRust FFI·C++ 상호운용 → JavaScriptCore/V8 임베딩 API 개관 → codegen 패턴 실습
함께 보면 좋은 것
JS 런타임 생태계 지도
Node.js(비교 기준·libuv 이벤트루프) · Deno(같은 "올인원" 철학의 Rust 런타임, 대조군) · esbuild(Bun 번들러의 벤치마크 상대, Go로 작성) · JavaScriptCore / V8(엔진 자체) · WinterCG(런타임 간 Web API 표준화). Bun을 이해했다면 이들의 관계가 한눈에 들어온다.

10핵심 키워드 사전

문서에 나온 용어를 한 곳에.

용어
JavaScript 런타임
브라우저 밖에서 JS를 실행하는 프로그램. 파일·네트워크 등 시스템 기능을 JS에 연결한다. Node·Deno·Bun이 대표.
용어
JavaScriptCore (JSC)
애플이 Safari에 쓰는 JS 엔진. Bun은 V8 대신 이걸 임베딩한다 — 짧은 시작 시간·낮은 초기 메모리가 특징.
용어
번들러 (bundler)
여러 소스·의존성을 배포용 파일(들)로 묶는 도구. Bun은 bun build로 내장한다. 그래프→링커→청크 흐름.
용어
트랜스파일 (transpile)
TS·JSX처럼 브라우저/엔진이 모르는 문법을 표준 JS로 변환하는 것. Bun은 이를 런타임 안에서 자동으로 한다.
용어
drop-in 대체
기존 것을 "거의 그대로" 바꿔 끼울 수 있다는 뜻. Bun은 Node.js drop-in 대체를 목표로 npm 호환·Node API 호환에 공을 들인다.
용어
codegen (코드 생성)
선언·명세로부터 반복적인 코드를 자동으로 찍어내는 기법. Bun은 *.classes.ts 하나에서 Rust·C++ 바인딩을 생성한다.
용어
FFI (Foreign Function Interface)
한 언어에서 다른 언어(주로 C)로 짠 함수를 호출하는 다리. Bun의 *_sys 크레이트가 C 라이브러리 FFI 바인딩이다.
용어
mimalloc
마이크로소프트의 고성능 메모리 할당자. Bun이 기본 할당자로 링크해 멀티스레드 할당 오버헤드를 줄인다.
용어
Bun.$ (셸 API)
OS 셸에 의존하지 않는 크로스플랫폼 셸. await $`...`로 Windows·macOS·Linux에서 동일하게 명령을 실행한다.
용어
bun.lock / 락파일
설치된 의존성 버전을 고정해 "누가·언제 설치해도 같은 결과"를 보장하는 파일. Bun은 텍스트 기반 bun.lock을 쓴다.

11참고 링크

원 소스로 가는 길.