JavaScript 런타임 3파전: Node.js vs Deno vs Bun 실전 비교

프론트엔드

Node.jsDenoBunJavaScript 런타임성능 비교

이 글은 누구를 위한 것인가

  • 새 프로젝트에서 어떤 JS 런타임을 써야 할지 고민하는 팀
  • Bun/Deno로 전환을 검토하는 Node.js 개발자
  • 각 런타임의 장단점을 객관적으로 비교하고 싶은 개발자

들어가며

2026년 현재 JavaScript 런타임은 Node.js 독점에서 3파전으로 바뀌었다. Bun은 속도, Deno는 보안과 현대성, Node.js는 안정성과 생태계를 내세운다. 모든 상황에 맞는 단일 답은 없다.

이 글은 bluefoxdev.kr의 JavaScript 런타임 비교 가이드 를 참고하여 작성했습니다.


1. 런타임 3파전 심층 비교

[엔진]
  Node.js: V8 (Google)
  Deno:    V8 (Google)
  Bun:     JavaScriptCore (Apple, Safari와 동일)

[TypeScript 지원]
  Node.js: 네이티브 미지원 (tsx/ts-node 필요)
           Node.js 22+: --experimental-transform-types (실험적)
  Deno:    네이티브 지원 (설정 불필요)
  Bun:     네이티브 지원 (설정 불필요)

[패키지 관리]
  Node.js: npm/pnpm/yarn, node_modules
  Deno:    JSR + npm(deno:npm 접두사), 중앙 캐시
  Bun:     npm 완전 호환, bun install (10x 빠름)

[보안]
  Node.js: 모든 권한 기본
  Deno:    명시적 권한 필요 (--allow-net 등)
  Bun:     Node.js와 동일 (모든 권한 기본)

[Web Standard API]
  Node.js 18+: fetch, crypto, Web Streams (부분)
  Deno:         완전한 Web API (fetch, WebSocket, URL, etc.)
  Bun:          대부분 Web API (fetch, WebSocket, etc.)

[HTTP 성능 (req/s, 간단한 JSON 응답)]
  Bun.serve():          ~180,000
  Deno (Hono):          ~150,000
  Node.js (Hono):       ~100,000
  Node.js (Fastify):    ~80,000
  Node.js (Express):    ~45,000

[시작 시간]
  Bun:     ~5ms
  Deno:    ~15ms
  Node.js: ~50ms

[메모리 사용 (idle)]
  Node.js: ~30MB
  Deno:    ~15MB
  Bun:     ~12MB

2. 동일 코드의 런타임별 차이

// HTTP 서버 - 각 런타임별 최적 방식

// Node.js (http 모듈)
import { createServer } from 'node:http';

const server = createServer(async (req, res) => {
  if (req.method === 'GET' && req.url === '/api/health') {
    res.writeHead(200, { 'Content-Type': 'application/json' });
    res.end(JSON.stringify({ status: 'ok' }));
  }
});
server.listen(3000);

// Bun (내장 서버)
const server = Bun.serve({
  port: 3000,
  fetch(req) {
    if (new URL(req.url).pathname === '/api/health') {
      return Response.json({ status: 'ok' });
    }
    return new Response('Not Found', { status: 404 });
  },
});

// Deno (표준 라이브러리 또는 Hono)
Deno.serve({ port: 3000 }, (req) => {
  const url = new URL(req.url);
  if (url.pathname === '/api/health') {
    return Response.json({ status: 'ok' });
  }
  return new Response('Not Found', { status: 404 });
});

// 크로스 런타임 (Hono - Node/Deno/Bun 모두 동일)
import { Hono } from 'hono';

const app = new Hono();

app.get('/api/health', (c) => c.json({ status: 'ok' }));
app.get('/api/users', async (c) => {
  const users = await fetchUsers();
  return c.json(users);
});

export default app;  // Deno Deploy, Cloudflare Workers, Bun 모두 동작
// 파일 I/O - 런타임별 차이
import { readFile, writeFile } from 'node:fs/promises';  // Node.js

// Node.js
const data = JSON.parse(await readFile('./data.json', 'utf-8'));
await writeFile('./output.json', JSON.stringify(data));

// Deno
const data = JSON.parse(await Deno.readTextFile('./data.json'));
await Deno.writeTextFile('./output.json', JSON.stringify(data));

// Bun
const data = await Bun.file('./data.json').json();
await Bun.write('./output.json', JSON.stringify(data));

// 환경변수
// Node.js: require('dotenv').config() 또는 dotenv 패키지
// Deno:    Deno.env.get('KEY')
// Bun:     process.env.KEY (dotenv 자동 로드)

// 실행 방법
// Node.js: node --loader ts-node/esm app.ts
// Deno:    deno run --allow-net --allow-read app.ts
// Bun:     bun app.ts
[사용 사례별 추천]

새 API 서버 (성능 최우선):
  → Bun (최고 처리량 + 빠른 시작)

보안이 중요한 스크립트/서버:
  → Deno (명시적 권한 모델)

엣지 컴퓨팅 (Cloudflare Workers):
  → Deno (Web Standard API 완전 지원)

기존 Node.js 앱 + 빠른 패키지 설치:
  → Bun (npm 호환, 패키지 10x 빠름)

대규모 팀, 안정성 최우선:
  → Node.js LTS (가장 큰 생태계)

CLI 도구:
  → Bun 또는 Deno (빠른 시작 시간)

서버리스 함수:
  → 플랫폼에 따라 다름
  Vercel Edge: Deno/Node.js
  Cloudflare Workers: Deno
  AWS Lambda: Node.js 또는 Bun (레이어)

[마이그레이션 난이도]
Node.js → Bun: ★★☆ (npm 호환, 대부분 동작)
Node.js → Deno: ★★★ (권한 모델, import 방식 변경)
Deno → Bun: ★★☆ (API 차이 있음)

마무리

2026년 런타임 선택 가이드: 성능과 빠른 시작 → Bun, 보안과 Web 표준 → Deno, 안정성과 생태계 → Node.js. 새 프로젝트라면 Bun이 가장 균형 잡힌 선택이다. Node.js와 npm 완전 호환에 3-10배 빠른 패키지 설치와 TypeScript 내장 지원은 즉각적인 생산성 향상을 가져온다. 기존 프로젝트는 bun install만 먼저 적용해도 팀 전체의 개발 경험이 달라진다.