ESC

Type to search the knowledge base.

globalThis

globalThis as the standard global object across browsers, workers, and Node — replacing window/self/global checks.

beginner3 min read
  • 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

  1. Polluting globalThis — name collisions, hard tests.
  2. Assuming SSR window — in Node SSR, window is missing; use globalThis carefully and still guard DOM APIs.
  3. 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.”

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