globalThis
globalThis as the standard global object across browsers, workers, and Node — replacing window/self/global checks.
- javascript
- globalThis
- globals
- runtime
Every JS realm has a global object. In browsers it’s window (or self in workers). In Node it was global. Polyfill libraries used to sniff:
const g =
typeof global !== 'undefined'
? global
: typeof window !== 'undefined'
? window
: self;
globalThis is the standard name that works across those environments (ES2020).
Usage
globalThis.MY_APP_VERSION = '1.2.3';
// feature detect on the global
if (typeof globalThis.structuredClone === 'function') {
// ...
}
// same as window in a window realm
globalThis === window; // true in browser page
In web workers:
// no window
globalThis === self; // true
In Node:
globalThis === global; // true (modern Node)
Why not always window?
| Environment | Global |
|---|---|
| Browser window | window / globalThis |
| Web Worker | self / globalThis (no window) |
| Service Worker | self / globalThis |
| Node | global / globalThis |
| Embedded engines | varies |
Libraries that only touch window break in workers. Prefer globalThis for portable code.
Modules vs scripts
In browsers, classic scripts put top-level var on the global object. ES modules do not become globalThis properties:
// type=module
var secret = 1;
globalThis.secret; // undefined
Attach explicitly if you must export a global for a legacy script tag:
globalThis.MyLib = { version: '1' };
Avoid new globals when a module export will do.
Polyfill note
Old environments without globalThis used a Function constructor trick or the sniff above. Today, browsers you target for modern apps include it. Bundlers can polyfill if your baseline requires it.
// defensive only for ancient targets
const root = typeof globalThis !== 'undefined' ? globalThis : window;
Footguns
- Polluting globalThis — name collisions, hard tests.
- Assuming SSR window — in Node SSR,
windowis missing; useglobalThiscarefully and still guard DOM APIs. - Security — anything on the global is reachable by other scripts on the page (XSS surface).
// SSR-safe DOM access still needs typeof document
function onClient(fn) {
if (typeof globalThis.document !== 'undefined') fn();
}
Interview answer
“globalThis is the standard reference to the global object across browsers, workers, and Node, replacing window/self/global sniffing. Modules don’t auto-publish top-level bindings to it. I use it for portable feature detection and avoid attaching new globals when modules suffice.”
Related
Feature detection table
const g = globalThis;
export const can =
typeof g.matchMedia === 'function'
? {
hover: () => g.matchMedia('(hover: hover)').matches,
}
: { hover: () => true };
export const has = {
intersectionObserver: typeof g.IntersectionObserver === 'function',
resizeObserver: typeof g.ResizeObserver === 'function',
structuredClone: typeof g.structuredClone === 'function',
};
Centralizing capability flags on checks against globalThis keeps worker-safe code from referencing window directly. In tests, you can stub globalThis.fetch carefully — restore after each case so parallel suites don’t bleed state.
Avoid accidental globals in demos
// bad in a shared playground
globalThis.state = {};
// better
const state = Object.create(null);
export { state };
Teaching materials sometimes assign to globalThis for REPL convenience. In app code, that creates hidden coupling and test pollution. If a legacy script must call into your bundle, attach one namespaced object (globalThis.MyApp) and freeze what you can.
Further reading
Related guides
- AbortControllerCancel fetch and other async work with AbortController and AbortSignal — timeouts, race conditions, and cleanup when components unmount.
- Array find, some, every, includesShort-circuiting array predicates: find, findIndex, some, every, and includes — when to use each and common interview traps.
- Array map, filter, reducemap, filter, and reduce as the core transform toolkit — immutability, chaining costs, reduce patterns, and when a plain loop is clearer.
- Arrow Functions Deep DiveLexical this, no arguments object, no construct, concise bodies — when arrows help and when methods and generators need classic functions.
- Async Iteration and for await...ofAsync iterables, for await...of, and streaming data — how async iterators differ from Promise.all and when to use each.