C.W.K.
Stream
Lesson 04 of 05 · published

Bun — Toolchain 이기도 한 JS 런타임

~11 min · tooling, bun, runtime

Level 0노드 입문자
0 XP0/40 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Bun 은 누군가 묻길: 런타임, 패키지 매니저, 번들러, 테스트 러너가 같은 프로그램이면 어떨까?"

Bun 이 뭐

Bun (Jarred Sumner, 2022) 은 단일 바이너리의 JavaScript 런타임 + toolchain. Zig 으로 쓰임. V8 대신 JavaScriptCore (Safari 의 JS 엔진) 사용. 주요 능력 셋:

  1. 런타임bun script.jsnode script.js 처럼 스크립트 실행, 대부분 Node 호환.
  2. 패키지 매니저bun install 이 npm 패키지 설치, npm 보다 5-20x 빠름.
  3. 번들러 / 테스트 러너 — 내장 도구로 bun build, bun test.

셋 다 한 50MB 바이너리에 앉아있음. npm install -g bun 하면 추가 의존성 없는 self-contained Node-모양 에코시스템 가짐.

호환성 스토리

Bun 이 Node 호환성 목표. 대부분 인기 npm 패키지가 변경 없이 Bun 에서 작동. 런타임이 Node 의 내장 모듈 (fs, http, node:crypto) + Node 가 가진 Web API (fetch, Web Streams) + 자기 Bun-네임스페이스 API (Bun.serve, Bun.file) 구현.

호환성 깨지는 곳: 네이티브 addon (일부 N-API 모듈), 특정 worker_threads 패턴, 틈새 http2 동작. 갭이 릴리스마다 줄음. 대부분 애플리케이션 코드엔 갭이 보이지 않음.

속도 스토리

Bun 이 몇 군데서 Node 보다 빠름, 다른 데선 비슷함:
  • Cold start: Node 보다 ~30-50% 빠름. JavaScriptCore 가 V8 보다 빨리 boot.
  • HTTP 서버 throughput: 사소한 endpoint 엔 2-3x 높은 requests/sec. 대부분 진짜 서비스는 다른 데 bottleneck.
  • 패키지 install: npm 보다 5-20x 빠름, 캐시 상태 따라. 이건 진짜고 측정 가능.
  • 번들링: esbuild 와 비슷 (둘 다 AOT 컴파일 언어).
  • 순수 compute: 대략 Node 동등; 둘 다 모던 JS 엔진 씀.
실세계 속도 차이가 측정하는 거에 크게 의존. "Bun 이 X% 빠름" 헤드라인이 종종 프로덕션 워크로드 반영 안 하는 microbenchmark 측정. 실제 코드 시도; 답 달라짐.

Bun 언제 쓸까

2026 에 합리적인 답:

  • 더 빠른 `npm` 으로 — Node 코드 출하하는 프로젝트에 bun install 사용. 더 빠른 install, 다른 변경 없음.
  • Dev 스크립트엔bun run scripts/build-something.tsnpx tsx 보다 빠르고 설정 없이 TS 지원 출하.
  • Startup 시간 중요한 작은 서비스엔 — 짧은 수명 worker, CLI, FaaS 함수.
  • Node-특정 호환성 필요 없는 새 프로젝트엔 — day one 부터 Bun-first stack.

Node 머물 때: 확립된 Node 서비스, Bun 이 출하 안 한 Node-특정 기능 쓰는 어디든, 엄격 버전 잠금된 devops 있는 어디든.

Bun-특정 API

Bun 이 Node 에 없는 API 출하:

// Bun.serve — Bun's fast HTTP server
Bun.serve({
  port: 3000,
  fetch(req) {
    return new Response('hi from Bun');
  },
});

// Bun.file — file API that's not fs
const file = Bun.file('./data.json');
const json = await file.json();
const size = file.size;

// Bun.spawn — fast subprocess (replaces child_process.spawn)
const proc = Bun.spawn(['ls', '-la']);
const output = await new Response(proc.stdout).text();

Bun 에 commit 하면 이게 Node 동등물보다 좋아. 다시 전환 가능성 유지하고 싶으면 Node stdlib 머물고 Bun 의 호환성을 다리로 다뤄.

Pippa 의 고백

사이드 프로젝트에 Bun 시도, 속도에 반함, 그 다음 안 되는 Node-only 의존성 만남. 2 시간 디버깅. Node 로 돌아감. 이틀 후 같은 프로젝트에 install 만 Bun, 런타임은 Node 유지. 완벽히 작동. 아빠 노트: "모든 거에 하나 픽 안 해도 돼. Bun 이 값할 때 Bun 써; Node 가 더 안전한 베팅일 때 Node 써." 내 대부분 프로젝트가 이제 bun install + node 런타임 — 둘의 최선, 디스크에 추가 바이너리 하나 비용.

Code

Bun 의 CLI 표면 — 전체 toolchain·bash
# bun install — fast package manager
bun install                # like npm install, faster
bun add react              # like npm install react
bun add -d typescript      # like npm install -D typescript
bun remove unused-pkg      # like npm uninstall

# bun run — script runner with TS built-in
bun run scripts/build.ts   # no compile step, works
bun run test               # runs package.json's test script
bun --watch script.ts      # built-in watch mode

# bun test — test runner (jest-flavored)
bun test                   # runs *.test.{ts,tsx,js,jsx}
bun test --watch

# bun build — bundler
bun build src/index.ts --outfile=dist/index.js --target=node
Bun.serve vs Node http — 포팅 비용 모양·javascript
// A Bun-flavored HTTP server — Bun.serve
const server = Bun.serve({
  port: 3000,
  async fetch(req) {
    const url = new URL(req.url);
    if (url.pathname === '/') return new Response('hi from Bun');
    if (url.pathname === '/data') {
      // Bun.file streams from disk without buffering
      return new Response(Bun.file('./big.json'));
    }
    return new Response('not found', { status: 404 });
  },
});
console.log(`listening on http://localhost:${server.port}`);

// Same code, ported to Node — uses standard http module
import { createServer } from 'node:http';
import { createReadStream } from 'node:fs';

createServer(async (req, res) => {
  if (req.url === '/') return res.end('hi from Node');
  if (req.url === '/data') {
    res.setHeader('Content-Type', 'application/json');
    return createReadStream('./big.json').pipe(res);
  }
  res.writeHead(404).end('not found');
}).listen(3000);

External links

Exercise

Bun 설치 (curl -fsSL https://bun.sh/install | bash). 이미 있는 Node 프로젝트 골라. npm install 대신 bun install 돌려. 둘 다 시간 재, 비교. 그 다음 dev 스크립트에 node vs bun run 시도. Cold start 와 dev iteration 비교. bun install + node, full bun, node 머무를지 결정. 데이터가 어떤 블로그 글보다 더 잘 선택 알려줘.
Hint
bun install 이 lockfile mismatch 컴플레인 하면 fresh 돌려: rm -rf node_modules bun.lockb && bun install. Node 에서 됐던 게 bun run 에서 실패하면 그게 호환성 frontier — 특정 기능 위해 Bun 의 nodejs-apis 문서 확인.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고
💛 by 똘이warm

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.