Same Language, Different Environment
JavaScript in the browser and Node.js share the same core language (ECMAScript), but their environments are completely different:
Browser Environment Node.js Environment
ββββββββββββββββββββ ββββββββββββββββββββ
β ECMAScript β β ECMAScript β
β DOM, BOM, fetch β β fs, http, path β
β window, document β β global, process β
β user interaction β β server/CLI ops β
ββββββββββββββββββββ ββββββββββββββββββββ
Global Objects
| Browser | Node.js | Purpose |
|---|---|---|
window | global | Global scope |
document | β | DOM access |
history | β | Browser history |
| β | process | System/process info |
| β | require() | Module loading |
fetch() | fetch() (v18+) | HTTP requests |
localStorage | β | Client-side storage |
What Node.js Has That the Browser Doesnβt
1. File System Access
const fs = require('fs');
// Read a file
const data = fs.readFileSync('/etc/hostname', 'utf8');
console.log('Hostname:', data.trim());
// Write a file
fs.writeFileSync('log.txt', 'Server started at ' + new Date());
Security: Browsers can never access your local file system β that would be a massive security risk.
2. Process & System Info
console.log('PID:', process.pid);
console.log('Platform:', process.platform);
console.log('Memory:', process.memoryUsage());
console.log('Args:', process.argv);
console.log('CWD:', process.cwd());
3. Environment Variables
// Set: PORT=3000 node app.js
const port = process.env.PORT || 3000;
console.log('Listening on port', port);
4. HTTP Server (No Browser Required)
const http = require('http');
const server = http.createServer((req, res) => {
res.end('Hello from Node.js!');
});
server.listen(3000);
// Visit http://localhost:3000
What the Browser Has That Node.js Doesnβt
1. The DOM
// β This does NOT work in Node.js
document.getElementById('app') // ReferenceError
document.querySelector('div') // ReferenceError
2. Window & BOM APIs
// β Node.js errors
alert('Hi') // ReferenceError
confirm('Sure?') // ReferenceError
localStorage // ReferenceError
Module Systems
| Feature | Browser | Node.js |
|---|---|---|
| Module system | ES Modules (<script type="module">) | CommonJS (require) + ES Modules |
| Code loading | <script src="..."> | require() / import |
| Bundling needed? | Often yes (Webpack, Vite) | No β native module resolution |
// Node.js β CommonJS
const fs = require('fs');
const path = require('path');
// Node.js β ES Modules (with "type": "module")
import fs from 'fs';
import path from 'path';
Event Loop Differences
Both use the same event loop concept, but Node.js adds extra phases:
Browser Event Loop: Node.js Event Loop:
ββββββββββββββββ ββββββββββββββββββββ
β Microtasks β β timers β
β (Promises) β β pending callbacksβ
β Render β β idle, prepare β
β Macro tasks β β poll β
ββββββββββββββββ β check (setImmediate)β
β close callbacks β
ββββββββββββββββββββ
Node.js phases include timers (setTimeout), I/O callbacks, poll (retrieve I/O events), and setImmediate.
Practical Test
Run this file in both environments to see the difference:
// env-test.js
console.log('Global:', typeof globalThis);
console.log('process:', typeof process);
console.log('window:', typeof window);
console.log('document:', typeof document);
console.log('fs:', typeof require);
# Node.js output:
Global: object
process: object
window: undefined
document: undefined
fs: function
In the browser console, window exists but process and require donβt.
Key Takeaways
- Node.js and browser share ECMAScript but have totally different APIs
- Node.js adds fs, process, http, path, crypto for server-side work
- Browsers add DOM, BOM, localStorage for client-side interaction
- Node.js uses CommonJS by default (
.require); browsers use ES Modules - The V8 engine is the same β only the environment APIs differ