JAVASCRIPT / GETTING STARTED
What JavaScript is and where it runs
Tell apart the JavaScript language from the runtime that hosts it, and predict which globals exist in a browser tab but not in Node.js.
What you will learn
- Tell apart language built-ins (Array, Math, JSON) from host globals (document, process).
- Check for a global safely with typeof name !== 'undefined' instead of assuming it.
- Predict which globals a browser tab has and a Node process does not.
- Keep pure logic free of host APIs so one file runs under both runtimes.
Understanding What JavaScript is and where it runs
JavaScript is a language specification, standardized under the name ECMAScript, and an engine is a program that implements it. The specification covers syntax, the type system, and a fairly small standard library: Object, Array, String, Number, Math, JSON, RegExp, Map, Promise. It says nothing about web pages, files, sockets, or even printing text. An engine on its own, whether V8, SpiderMonkey, or JavaScriptCore, can evaluate 2 + 2 but has no way to show you the answer.
A runtime, also called the host, embeds an engine and adds globals of its own. A browser tab adds document, window, localStorage, fetch, and event listeners so a script can change a page; Node.js adds process, Buffer, module loading, and libraries like fs so a script can read files and answer network requests. Deno, Bun, Electron, Cloudflare Workers, and the scripting layers inside tools such as Photoshop and MongoDB each do the same thing with a different set of globals. The mental model worth carrying: the language gives you grammar plus a core library, and the host gives you capabilities.
That split explains most of the early "why doesn't this work" moments. A snippet that dies on document is not defined is not bad JavaScript; it was written for a host that owns a page. The same split explains why feature availability is a property of the runtime version rather than of "JavaScript" itself, since optional chaining or Array.prototype.at works only if the embedded engine is new enough. Even console.log, the first thing everyone types, is a host-provided API that happens to be nearly universal rather than part of the language.
// The language core: identical behaviour in every runtime
const nums = [3, 1, 2];
nums.sort((a, b) => a - b);
console.log(nums.join(","));
console.log(Math.max(...nums), typeof Math.max(...nums));
console.log(0.1 + 0.2 === 0.3); // number rules come from the language
// Host globals: whoever embeds the engine decides what exists
console.log("has DOM:", typeof document !== "undefined");
console.log("has Node process:", typeof process !== "undefined");
// Output below is from `node where.js`; in a browser tab the last
// two lines print true and false instead.JavaScript is only a language plus a small core library; every ability to touch a page, a file, or a network comes from the host runtime that embeds the engine.
Worked examples
Portable logic, host-specific effect
Shows that string work is language-level and portable, while changing a page title needs a browser host.
// run with: node slug.js
function slugify(title) {
return title.trim().toLowerCase().replace(/\s+/g, "-");
}
const slug = slugify(" What JavaScript Is ");
console.log(slug);
if (typeof document === "undefined") {
console.log("no document: this host has no page to change");
} else {
document.title = slug;
console.log("page title set to", document.title);
}Example explained
Line 1slugify uses trim, toLowerCase, replace, and a regular expression, all defined by the language, so it behaves the same in any runtime.
Line 2typeof document returns the string "undefined" rather than throwing, which is why typeof is the safe way to probe a global you are not sure about.
Line 3document.title = slug is the only host-dependent line; document is an object the browser injects, not a language feature.
Line 4Moving that assignment outside the guard would throw ReferenceError: document is not defined under node.
Naming the host at runtime
Uses globalThis and typeof probes to identify which host is running the code and which globals are standard.
// run with: node host.js
console.log(typeof globalThis, globalThis === globalThis.globalThis);
const host =
typeof window !== "undefined" ? "browser window" :
typeof process !== "undefined" ? "Node process" :
"some other host";
console.log("host:", host);
console.log(typeof JSON.stringify, typeof setTimeout);Example explained
Line 1globalThis, added in ES2020, is the language's portable handle on the global object; window and Node's global are host-specific names for the same kind of thing.
Line 2The global object exposes itself under the property globalThis, so the strict comparison on line 2 is true.
Line 3JSON is specified by the language, while setTimeout is not; both browsers and Node supply setTimeout anyway, which shows host APIs can overlap without being part of ECMAScript.
Important notes
console is not part of the ECMAScript standard. Almost every host provides it, but formatting differs: Node prints [ 1, 2, 3 ] where Chrome shows an expandable array you can click open.
"JavaScript runs everywhere" means many hosts embed an engine, not that every API is available everywhere; fetch, localStorage, and require each depend on the host and its version.
Common mistakes
Expecting console.log to write text into the web page: the string goes to the console or terminal, the page stays blank, and the reader concludes the script never ran.
Pasting browser code into a file run with node and getting ReferenceError: document is not defined, then editing the syntax; the syntax is fine, the host simply has no DOM.
Searching for Java answers when stuck on JavaScript: the languages are unrelated, so advice about compiling, class Main, and fixed-size arrays leads nowhere.
Try it yourself
Change, predict, then run
In a browser editor or console, print typeof for document, localStorage, process, and Math, then write down which two results would change if the same four lines ran under node and explain why.
Open the JavaScript workspaceCheck your understanding
A snippet copied from a browser tutorial fails with ReferenceError: document is not defined when you run it with node. What is the most accurate conclusion?
- Node runs an older version of the JavaScript language that does not include document.
- document is a browser-supplied host global that the language never defined, so Node has no reason to provide it.
- The file must be turned into a module or compiled before Node can use DOM APIs.
- Node's engine differs from Chrome's, so its standard library is smaller.
Show answer
The DOM comes from the browser host, not from ECMAScript, so no language version, module format, or build step will make document appear in Node. The engine answer is tempting because runtimes really do differ in feature support, but Node and Chrome both embed V8, and engine choice affects which language features exist, not whether a page object is available.