자바스크립트는 프로그래밍 언어이고, Node.js는 런타임, 즉 브라우저 밖에서 자바스크립트를 실행하는 프로그램입니다. 문법, 타입, 표준 객체(Array, Promise, JSON)는 양쪽이 같습니다. 달라지는 것은 코드를 둘러싼 환경입니다. 브라우저는 웹 페이지를 다루도록 window와 document를 주고, Node.js는 파일, 서버, 운영체제를 다루도록 global, process, require, 그리고 fs 같은 모듈을 줍니다.
브라우저 전역은 undefined, Node.js 전역은 object나 function이 출력되었고, 마지막 줄은 true였습니다. Node.js에서는 globalThis와 global이 같은 객체이기 때문입니다. 앞의 여섯 줄을 브라우저 콘솔에 붙여 넣으면 결과가 반대로 나옵니다.
표 하나로 보는 차이
| 브라우저의 자바스크립트 | Node.js의 자바스크립트 | |
|---|---|---|
| 정체 | 언어. 브라우저 엔진이 실행 | 같은 언어. Node.js 런타임(V8)이 실행 |
| 전역 객체 | window | global |
| 다루는 대상 | 페이지: document, DOM, 이벤트 | 컴퓨터: fs, http, process, os |
| 모듈 | <script type="module">, import | require(CommonJS)와 import(ES 모듈) |
| 패키지 | 페이지에 번들링 | npm으로 node_modules에 설치 |
| 입력 | 클릭, 폼, 키보드 이벤트 | 명령줄 인자, 표준 입력, HTTP 요청 |
Array, Promise, JSON, setTimeout, console | 있음 | 있음 |
가장 많이 헷갈리는 것은 모듈 줄입니다. Node.js는 require와 import를 모두 지원하지만, 브라우저는 import만 압니다. 어느 쪽을 고를지는 CommonJS vs ES 모듈 페이지에서 설명합니다.
언어는 같습니다
언어 기능만 쓰는 함수는 어디서나 실행됩니다. 이 블록에는 Node.js 전용인 것이 하나도 없어서, 브라우저에서도 같은 줄을 출력합니다.
{"best":95,"average":85}와 Passed: 2 of 3이 출력되었습니다. 스프레드 문법, reduce, 템플릿 문자열, JSON은 ECMAScript 표준이 정한 언어의 일부라서 모든 런타임에 있습니다.
Node.js에만 있는 것
Node.js 전용인 부분은 운영체제와 대화하는 내장 모듈과 전역입니다.
파일을 쓰고 다시 읽어 .txt 2 lines를 출력한 다음, 빈 인자 목록을 출력했습니다. 파일 접근도 process.argv도 브라우저에는 없습니다. 페이지는 디스크를 건드릴 수 없기 때문입니다.
어떤 언어 기능을 쓸 수 있나
언어에는 버전(ES2015, ES2020, ES2024 등)이 있고, 엔진마다 새 기능을 받아들이는 속도가 다릅니다. Node.js는 릴리스마다 특정 V8 엔진 하나를 넣어 배포하므로, 어떤 기능이 동작할지는 Node.js 버전이 정합니다. 예를 들어 Object.groupBy와 Array.prototype.findLast는 최신 버전이 필요합니다. 그래서 브라우저 기능 지원표에는 Chrome, Firefox, Safari 옆에 Node.js가 열 하나로 들어가 있습니다. 새 문법이 SyntaxError로 실패하거나 메서드가 undefined라면 node --version을 실행해 보고, 폴리필을 찾기 전에 먼저 업그레이드하세요.
양쪽에서 동작하는 코드 쓰기
라이브러리 작성자는 환경 전용 API를 쓰기 전에 코드가 어디서 실행되는지 확인하기도 합니다.
const isNode = typeof process !== 'undefined' && process.versions?.node != null;
const isBrowser = typeof window !== 'undefined';
가능하면 환경 이름이 아니라 필요한 기능 자체를 확인하세요. "이게 Node인가"보다 typeof fetch === 'function'이 더 많은 것을 알려 줍니다. 지금은 양쪽 모두 fetch, URL, TextEncoder, setTimeout, structuredClone을 가지고 있어서, 몇 년 전보다 확인이 필요한 코드가 줄었습니다.
흔한 실수
Node.js 스크립트에서 document나 window를 쓰는 것. ReferenceError: document is not defined가 납니다. 그 코드는 브라우저에서 실행해야 합니다.
브라우저에서 require를 쓰는 것. 브라우저에는 없습니다. import를 쓰거나, require 호출을 파일 하나로 합쳐 주는 번들러를 쓰세요.
Node.js를 다른 언어라고 생각하는 것. 그렇지 않습니다. 자바스크립트 튜토리얼에서 배우는 내용은 DOM을 쓰지 않는 한 Node.js에서도 그대로 동작합니다.
자주 묻는 질문
자바스크립트를 배우지 않고 Node.js를 배울 수 있나요?
사실상 어렵습니다. Node.js에서 쓰는 모든 줄이 자바스크립트이니 언어가 먼저입니다. 함수, 객체, Promise를 알고 나면 Node.js는 추가 API를 익히는 일입니다.
Node.js에서 "document is not defined" 에러가 나는 이유는 뭔가요?
document는 브라우저의 DOM이고, Node.js에는 그것을 만들어 줄 페이지가 없습니다. document나 window를 건드리는 코드는 브라우저에서, 또는 jsdom처럼 DOM을 흉내 내는 테스트 환경에서 실행해야 합니다.
TypeScript와 Node.js는 같은 건가요?
아닙니다. TypeScript는 타입이 있는 자바스크립트로, 자바스크립트로 컴파일됩니다. 결과물은 Node.js에서도 브라우저에서도 실행할 수 있고, 최신 Node.js는 타입을 제거해서 많은 .ts 파일을 직접 실행할 수도 있습니다.