globalThis is a standard JavaScript global property that provides a universal way to access the global object, regardless of the JavaScript environment.
It was introduced in ES2020 to solve the problem of accessing the global object consistently across different JavaScript environments.
1. What is globalThis?
JavaScript runs in different environments, such as browsers and Node.js. Each environment has its own name for the global object.
| Environment | Global object |
|---|---|
| Browser | window |
| Web Worker | self |
| Node.js | global |
| Modern JavaScript (all environments) | globalThis |
Previously, developers had to use different global object references depending on the environment.
With globalThis, you can access the global object using the same syntax everywhere.
console.log(globalThis);
In a browser, it refers to the global object, which is normally window.
In Node.js, it refers to the global object, which is also accessible through global.
To write cross-platform libraries or isomorphic code (code that runs on both the client and server), developers relied on boilerplate polyfills like this:
// The old, cumbersome way of getting the global object
const getGlobal = function() {
if (typeof self !== 'undefined') return self;
if (typeof window !== 'undefined') return window;
if (typeof global !== 'undefined') return global;
throw new Error('Unable to locate global object');
};
const myGlobal = getGlobal();
globalThis eliminates this boilerplate entirely, standardizing the global namespace access into a single, native keyword.
Core Characteristics
-
Standardized Across Environments: It always points to the true global object, whether you are in a browser (
window), Node.js (global), or a worker (self). -
Consistent in Strict Mode: In ES modules or strict-mode scripts, top-level
thisisundefined. However,globalThisalways correctly references the global object. -
Readily Available: It is a global property itself, meaning it is part of the global scope in any standard-compliant modern JavaScript engine.
Detailed Examples
1. Attaching and Accessing Global Properties
You can attach custom properties to the global scope and access them uniformly across environments using globalThis.
// Setting a global configuration flag
globalThis.APP_VERSION = '2.4.1';
// Later in your code, or in another module:
console.log(globalThis.APP_VERSION); // Output: '2.4.1'
// In a browser, this is equivalent to:
console.log(window.APP_VERSION); // Output: '2.4.1' (in a browser environment)
// In Node.js, this is equivalent to:
console.log(global.APP_VERSION); // Output: '2.4.1' (in a Node.js environment)
2. Feature Detection (Polyfilling Safely)
globalThis is exceptionally useful for feature detection and safely applying polyfills without crashing engines that lack specific native APIs.
// Safely check for and polyfill a missing global API (e.g., a custom logger or utility)
if (typeof globalThis.CustomLogger === 'undefined') {
globalThis.CustomLogger = {
log(message) {
console.log(`[Default Logger]: ${message}`);
}
};
}
globalThis.CustomLogger.log('System initialized successfully.');
3. Writing Isomorphic (Universal) Libraries
If you are building an npm package meant to run in both Node.js and web browsers, globalThis lets you check for host-specific features cleanly.
function detectEnvironment() {
if (typeof globalThis.document !== 'undefined') {
return 'Browser Environment (DOM available)';
} else if (typeof globalThis.process !== 'undefined' && globalThis.process.versions && globalThis.process.versions.node) {
return 'Node.js Environment';
} else {
return 'Web Worker or Edge Environment';
}
}
console.log(detectEnvironment());
Browser Compatibility and Polyfill
globalThis is supported in all modern browsers (Chrome 71+, Firefox 65+, Safari 12.1+, Edge 79+) and Node.js (v12.0.0+).
If you need to support legacy environments (such as Internet Explorer 11 or older Node.js versions), you can use a simple polyfill at the very entry point of your application:
(function() {
if (typeof globalThis === 'object') return;
try {
Object.defineProperty(Object.prototype, '__globalThis__', {
get: function() { return this; },
configurable: true
});
__globalThis__.globalThis = __globalThis__;
delete Object.prototype.__globalThis__;
} catch (e) {
// Fallback if Object.defineProperty fails
if (typeof self !== 'undefined') {
self.globalThis = self;
} else if (typeof window !== 'undefined') {
// @ts-ignore
window.globalThis = window;
} else if (typeof global !== 'undefined') {
// @ts-ignore
global.globalThis = global;
}
}
})();
