Chapter 3: Node.js vs Browser
Node.js vs Browser JavaScript — written as if I’m sitting next to you, comparing both environments side by side, showing real code examples, and explaining what actually confuses most people when they switch from frontend to backend (or the other way around).
Let’s go slowly and clearly.
1. The most important sentence first
The same language (JavaScript), but completely different runtime environments.
| Aspect | Browser JavaScript | Node.js JavaScript |
|---|---|---|
| Where it runs | Inside Chrome / Firefox / Safari / Edge | Directly on your computer / server (no browser) |
| JavaScript engine | V8, SpiderMonkey, JavaScriptCore | V8 (same as Chrome) |
| Main purpose | Manipulate web page (DOM), handle user events | Build servers, CLIs, file processing, APIs… |
| Has DOM? | Yes — document, window, navigator… | No — there is no webpage |
| Has window object? | Yes | No |
| Has fetch? | Yes (native) | Yes (since Node 18 – but older versions no) |
| Has console.log? | Yes | Yes |
| Can read/write files? | No (very limited) | Yes — fs module |
| Can listen on port 3000? | No | Yes — http, express, etc. |
| Can make network requests? | Yes (but CORS restrictions) | Yes (no CORS, full control) |
| Single-threaded? | Yes | Yes |
| Has event loop? | Yes | Yes (very similar, but different priorities) |
2. Side-by-side comparison – real code examples
Example 1: Hello World
Browser (put in <script> or console)
|
0 1 2 3 4 5 6 7 8 |
console.log("Hello from browser!"); alert("Hi there!"); document.body.style.background = "lightblue"; |
Node.js
|
0 1 2 3 4 5 6 7 8 9 10 |
console.log("Hello from Node.js!"); // These will throw errors: // alert("Hi there!"); → ReferenceError: alert is not defined // document.body.style... → ReferenceError: document is not defined |
→ Lesson: In Node.js there is no webpage, so no document, window, alert, localStorage, sessionStorage, history, location…
Example 2: Reading a file
Browser — almost impossible without user interaction
|
0 1 2 3 4 5 6 7 8 9 10 11 12 |
// You need <input type="file"> and user must pick file input.addEventListener('change', e => { const file = e.target.files[0]; const reader = new FileReader(); reader.onload = () => console.log(reader.result); reader.readAsText(file); }); |
Node.js — very natural & powerful
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import { readFile } from 'node:fs/promises'; async function main() { try { const content = await readFile('data.txt', 'utf-8'); console.log(content); } catch (err) { console.error("File error:", err); } } main(); |
→ Big difference: Node.js can freely access the filesystem
Example 3: Starting a web server
Browser — you cannot do this
Node.js — very common task
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
import { createServer } from 'node:http'; createServer((req, res) => { res.writeHead(200, { 'Content-Type': 'text/plain' }); res.end('Hello from my Node.js server!\n'); }).listen(3000, () => { console.log('Server running → http://localhost:3000'); }); |
→ Browsers are clients — they connect to servers Node.js is often used to be the server
Example 4: Making an HTTP request
Browser (very common)
|
0 1 2 3 4 5 6 7 8 9 |
fetch('https://api.example.com/data') .then(res => res.json()) .then(data => console.log(data)) .catch(err => console.error(err)); |
Node.js — exactly the same since Node 18+
|
0 1 2 3 4 5 6 7 8 |
const response = await fetch('https://api.example.com/data'); const data = await response.json(); console.log(data); |
→ Very similar today — but older Node versions used http, https, axios, node-fetch…
3. Global objects – what exists where?
| Global object / feature | Browser? | Node.js? | Replacement in Node.js (if missing) |
|---|---|---|---|
| window | Yes | No | — |
| document | Yes | No | — |
| navigator | Yes | No | — |
| localStorage | Yes | No | Use fs or database |
| setTimeout, setInterval | Yes | Yes | Same API |
| fetch | Yes | Yes (18+) | node-fetch, axios, undici (older versions) |
| process | No | Yes | Very important in Node! |
| require / module.exports | No | Yes (CJS) | — |
| import / export | Yes | Yes | Same (with “type”: “module”) |
| globalThis | Yes | Yes | Universal way to access global scope |
| global | No | Yes | Similar to window in Node |
| Buffer | No | Yes | For binary data |
| fs, path, os, child_process | No | Yes | Core modules — only in Node |
4. Very common confusion points (beginner → intermediate)
| Confusion / Question | Explanation |
|---|---|
| “Why does window not exist in Node?” | Because there is no browser window. Node is a server runtime, not a webpage renderer. |
| “Can I use React in Node.js?” | Yes — but only server-side (SSR, SSG, static generation). No browser DOM. |
| “Why can’t I use document.getElementById?” | There is no HTML page in Node. Use frontend frameworks in browser only. |
| “Is this the same in Node and browser?” | Arrow functions behave the same. Regular functions — in Node this defaults to global, not window. |
| “Can I share code between frontend and backend?” | Yes — very popular! (utils, validation, types, constants…) but avoid DOM/browser APIs |
| “Why do people use process.env in Node?” | Environment variables — very common for secrets, ports, API keys, dev/prod mode… |
5. Quick reference table – what to use when
| Task / Need | Browser | Node.js |
|---|---|---|
| Show something on screen | DOM, React, Vue… | Send HTML/JSON via HTTP response |
| Store user data between refreshes | localStorage / sessionStorage | Database, Redis, files |
| Read configuration | Usually hardcoded or from backend | process.env + .env files |
| Handle file uploads | <input type=”file”> + FormData | multer, formidable, busboy… |
| Listen for incoming requests | — | http, Express, Fastify, Hono… |
| Schedule background tasks | setInterval, Web Workers | setInterval, cron jobs, BullMQ, Agenda… |
| Access command line arguments | — | process.argv |
6. Summary – one-liners people usually remember
- Browser = client — renders pages, reacts to clicks, talks to servers
- Node.js = server (or tool) — listens for requests, reads/writes files, talks to databases, runs scripts
- Same language, different globals, different standard library
- You can write almost the same logic in many places (validation, formatting, calculations…) → but never write DOM manipulation or window.alert() in Node.js
Would you like to go deeper into any of these directions?
- How to share code between frontend and backend (very practical topic)
- Writing the same validation logic in browser + Node.js
- Understanding process object in Node (very important)
- Real example: isomorphic JavaScript function that works in both places
- Why Node.js event loop feels different from browser event loop
- Migrating from browser thinking to server thinking (common traps)
Just tell me what interests you most — I’ll continue with concrete examples. 😄
