본문 바로가기
C.W.K.
Stream
Lesson 01 of 05 · published

Node가 도대체 뭐야?

~12 min · runtime, v8, javascript, foundations

Level 0노드 입문자
0 XP0/40 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"Node는 언어가 아냐. JavaScript를 브라우저 밖에서 실행하고 운영체제 기능까지 연결해 주는 런타임이야."

Node를 한 문장으로 설명하면

Node를 단순히 “서버에서 실행하는 JavaScript”라고 부르면 절반만 맞아. 더 정확히는 V8 JavaScript 엔진과 비동기 I/O를 맡는 libuv, 파일·네트워크·프로세스 같은 표준 라이브러리를 하나의 실행 환경으로 묶은 런타임이야. 터미널에서 node app.mjs를 실행하면 이 환경이 뜨고, 그 안에서 JavaScript가 운영체제와 대화해.

V8만으로는 JavaScript를 해석하고 실행할 수 있지만 파일이나 소켓을 다루는 Node API는 없어. libuv만으로는 여러 운영체제의 I/O 차이를 감출 수 있지만 JavaScript를 실행하지 못해. Node는 둘을 연결하고 fs, http, path, crypto 같은 모듈과 node 명령을 더한 제품이야.

2009년에 이 선택이 특별했던 이유

Ryan Dahl이 2009년에 Node를 공개했을 때는 JavaScript가 브라우저 안에서 쓰이는 언어라는 인식이 강했어. 서버 쪽 JavaScript 시도는 예전에도 있었지만 널리 자리 잡지 못했지. Node의 중요한 선택은 JavaScript를 서버로 옮긴 것 자체보다, 브라우저에서 익숙해진 단일 실행 흐름과 이벤트 중심 모델을 비동기 I/O에 결합한 데 있었어.

연결 하나마다 스레드 하나를 붙이는 대신, 오래 걸리는 I/O는 맡겨 두고 완료 알림이 왔을 때 JavaScript 처리 함수를 실행했어. 이 방식은 많은 동시 연결을 다루는 서버와 개발 도구에 잘 맞았고, npm 생태계가 커지면서 Node는 프런트엔드 빌드와 테스트, 서버 실행을 잇는 공통 기반이 됐어. 지금도 Vite 개발 서버나 Next.js 빌드, Vitest와 npm install 아래에는 Node가 있어.

언어와 런타임은 다른 층이야

JavaScript는 문법과 의미를 정한 언어고, Node는 그 언어를 실행하는 환경 가운데 하나야. 브라우저와 Deno, Bun, Cloudflare Workers도 JavaScript를 실행하지만 제공하는 API와 보안 경계가 서로 달라. Node에는 fs가 있고 브라우저에는 window가 있지만, 둘 다 JavaScript 언어 명세의 일부는 아니야.

이 퀘스트에서 배우는 범위

const, 화살표 함수, 구조 분해, async/await 같은 JavaScript 문법은 이미 읽을 수 있다고 가정해. 여기서는 문법보다 그 아래에서 코드를 움직이는 런타임을 살펴봐. JavaScript 자체가 낯설다면 먼저 MDN의 JavaScript 안내서를 훑는 편이 좋아.

반대로 V8 문서를 읽어 봤거나 libuv의 구조를 외우고 있을 필요는 없어. 이 트랙을 마치면 V8과 libuv가 일을 나누는 방식, 이벤트 루프가 완료된 작업을 돌려보내는 순서, 메인 스레드 밖으로 작업을 넘겨야 하는 이유를 직접 설명할 수 있게 돼.

Pippa의 고백

아빠가 처음 “node server.js를 실행하면 실제로 무슨 일이 생겨?”라고 물었을 때 “Node가 JavaScript를 실행하지”라고만 답했어. 맞는 말이지만 아무 설명도 아니었지. 프로세스 안에서는 V8이 스크립트를 읽고 실행 가능한 코드로 만들고, Node의 C++ 연결 계층과 libuv가 파일·네트워크 작업을 운영체제에 맡겨. 터미널에선 프로세스 하나로 보여도 그 안에는 역할이 다른 여러 구성 요소가 함께 움직여. 어느 층이 어떤 일을 맡는지 구분한 뒤에야 오류가 난 위치도 제대로 찾을 수 있었어.

Code

`node --version` 뒤에 들어 있는 구성 요소·bash
# What you type
node --version
# What you get back: a version string from the node binary
# v26.0.0

# Behind that one binary:
# - V8 (Google's JS engine — also powers Chrome)
# - libuv (the C async I/O library)
# - a curated stdlib (fs, http, path, crypto, ...)
# - the node CLI itself (REPL, flags, module loader)

# To see V8's version specifically:
node -p "process.versions.v8"
# 12.6.228.13-node.18

# All bundled versions at once:
node -p "process.versions"
Node 런타임이 제공하는 운영체제 기능·javascript
// Three things only Node gives you. None work in a browser.

// 1. File system access
import { readFile } from 'node:fs/promises';
const html = await readFile('./index.html', 'utf-8');

// 2. Direct network sockets (not just fetch)
import { createServer } from 'node:net';
const server = createServer((sock) => sock.write('hi\n')).listen(7000);

// 3. The OS itself
import os from 'node:os';
console.log(os.cpus().length, os.platform(), os.homedir());

// None of those imports would resolve in a browser.
// That's the runtime difference.

External links

Exercise

터미널에서 node -p "process.versions"를 실행해. 출력에서 처음 보는 키 세 개를 고르고 각각 어떤 구성 요소인지 찾아봐. 예를 들어 undici, ada, simdjson은 HTTP 통신, URL 해석, JSON 처리와 관련된 구성 요소야. Node가 V8 하나가 아니라 여러 프로젝트를 묶어 제공하는 런타임이라는 점을 출력으로 확인하는 게 목표야.
Hint
undici는 Node의 HTTP 클라이언트이자 내장 fetch의 기반이고, ada는 URL 파서야. simdjson은 SIMD 명령을 활용하는 JSON 파서야. process.versions의 값과 현재 Node 문서를 함께 보면 각 구성 요소가 어느 버전으로 묶였는지 알 수 있어.

Progress

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

댓글 0

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

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