{"id":12710,"library":"zone.js","title":"Zones for JavaScript","description":"Zone.js implements the 'Zone' concept for JavaScript, inspired by Dart, providing an execution context that persists across synchronous and asynchronous tasks. It acts like thread-local storage for JavaScript VMs, allowing developers to track context (like request IDs or user data) across complex asynchronous operations. Zone.js achieves this by monkey-patching most standard web APIs (e.g., DOM events, `XMLHttpRequest`, `setTimeout`, `Promise`) and Node.js APIs (`EventEmitter`, `fs`). The current stable version is `0.16.1`, although the project's recent releases align with Angular's major versions (e.g., `v21.2.9`). While historically a core part of Angular's change detection, Angular is transitioning to a zoneless model, using Signals for reactivity. Consequently, Zone.js is no longer accepting new features or low-priority bug fixes, with critical fixes limited to Angular's direct use cases, and its use outside Angular is strongly discouraged.","status":"maintenance","version":"0.16.1","language":"javascript","source_language":"en","source_url":"git://github.com/angular/angular","tags":["javascript","typescript"],"install":[{"cmd":"npm install zone.js","lang":"bash","label":"npm"},{"cmd":"yarn add zone.js","lang":"bash","label":"yarn"},{"cmd":"pnpm add zone.js","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Zone.js patches global APIs upon import, making the `Zone` global object available. Since `v0.11.1+`, `import 'zone.js'` loads the ES2015 ESM bundle for modern environments.","wrong":"import { Zone } from 'zone.js';","symbol":"Zone","correct":"import 'zone.js';"},{"note":"This import path specifically loads the ES5 UMD bundle, maintaining backward compatibility for legacy browsers like IE11, especially for applications built before Zone.js `v0.11.1`.","wrong":"import 'zone.js';","symbol":"Zone","correct":"import 'zone.js/dist/zone';"},{"note":"For CommonJS environments (Node.js), `require('zone.js')` loads the UMD bundle and applies patches, making `Zone` available globally. There is no direct `Zone` export to assign to a variable.","wrong":"const Zone = require('zone.js');","symbol":"Zone","correct":"require('zone.js');"}],"quickstart":{"code":"import 'zone.js'; // Ensure zone.js is loaded to patch global APIs\n\n// The global Zone object is now available\nconsole.log(`Initial Root Zone Name: ${Zone.current.name}`);\n\n// Create a new zone with custom properties\nconst requestScopedZone = Zone.current.fork({\n  name: 'requestZone',\n  properties: {\n    requestId: 'req-' + Math.random().toString(36).substring(2, 9)\n  }\n});\n\nconsole.log(`\nStarting a new request simulation...`);\n\n// Run a synchronous task within the new zone\nrequestScopedZone.run(() => {\n  const currentRequestId = Zone.current.get('requestId');\n  console.log(`  Inside requestZone (sync): Request ID = ${currentRequestId}`);\n\n  // Schedule an asynchronous task. Zone.js patches setTimeout to preserve context.\n  setTimeout(() => {\n    // This callback will automatically run within 'requestScopedZone'\n    console.log(`  Inside requestZone (async setTimeout): Request ID = ${Zone.current.get('requestId')}`);\n    if (Zone.current.get('requestId') === currentRequestId) {\n      console.log('  Async context correctly preserved!');\n    }\n  }, 50);\n\n  // Another async operation (e.g., a Promise)\n  Promise.resolve().then(() => {\n    console.log(`  Inside requestZone (async Promise): Request ID = ${Zone.current.get('requestId')}`);\n  });\n});\n\nconsole.log(`\nBack in Root Zone: Current Zone Name = ${Zone.current.name}`);\n\n// Demonstrating another independent zone\nconst userContextZone = Zone.current.fork({\n  name: 'userContextZone',\n  properties: {\n    userId: 'user-' + Math.floor(Math.random() * 1000)\n  }\n});\n\nuserContextZone.run(() => {\n  console.log(`\n  Inside userContextZone: User ID = ${Zone.current.get('userId')}`);\n  setTimeout(() => {\n    console.log(`  Inside userContextZone (async): User ID = ${Zone.current.get('userId')}`);\n  }, 20);\n});","lang":"typescript","description":"This quickstart demonstrates how to initialize Zone.js and use `Zone.current.fork()` to create custom execution contexts that persist properties across synchronous and patched asynchronous tasks like `setTimeout` and `Promise` callbacks."},"warnings":[{"fix":"For applications requiring ES5 or IE11 compatibility, explicitly change the import statement to `import 'zone.js/dist/zone';` to load the ES5 UMD bundle.","message":"Starting with Zone.js `v0.11.1`, the default import `import 'zone.js';` now loads the ES2015 (ESM) bundle instead of the ES5 UMD bundle. This change can break applications in legacy environments, particularly IE11, which relies on ES5.","severity":"breaking","affected_versions":">=0.11.1"},{"fix":"If not using Angular, consider refactoring asynchronous context management using native `AsyncLocalStorage` in Node.js or other patterns. For Angular applications, investigate transitioning to the experimental or stable zoneless mode with Signals in Angular 18+.","message":"Zone.js is no longer actively accepting new features or low-priority bug fixes, and its use outside of Angular application contexts is strongly discouraged. Angular is moving towards a zoneless application development model with Signals, reducing its dependency on Zone.js for change detection.","severity":"deprecated","affected_versions":">=0.11.0"},{"fix":"Ensure Zone.js is imported *before* any libraries that perform global monkey-patching of native browser or Node.js APIs to ensure Zone.js can correctly wrap them. Consult the Zone.js README for specific recommendations on import order.","message":"When integrating Zone.js with certain third-party libraries (e.g., `newrelic`, `async-listener`, `continuation-local-storage`), the import order matters. These libraries may patch global objects like `Promise`, `setTimeout`, or `setInterval` before Zone.js, leading to unexpected behavior if Zone.js patches are applied afterwards.","severity":"gotcha","affected_versions":"all"},{"fix":"Regularly update Zone.js to the latest stable version, especially when updating Angular, to incorporate critical security patches and avoid known vulnerabilities.","message":"Several versions of Zone.js, particularly those aligned with recent Angular releases, have included security fixes related to Server-Side Request Forgery (SSRF) bypasses and Content Security Policy (CSP) nonce issues. Failing to update may leave applications vulnerable.","severity":"gotcha","affected_versions":">=19.2.21, >=20.3.19, >=21.2.9"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Change the Zone.js import from `import 'zone.js';` to `import 'zone.js/dist/zone';` in your polyfills or main entry file to explicitly load the ES5 UMD bundle for IE11 compatibility.","cause":"This error typically occurs in Internet Explorer 11 after upgrading Zone.js to `v0.11.1` or later, due to the default import now loading the ES2015 (ESM) bundle which uses modern JavaScript features unsupported by IE11.","error":"TypeError: Object doesn't support property or method 'Symbol.iterator'"},{"fix":"Ensure `import 'zone.js';` (or `import 'zone.js/dist/zone';` for legacy) is at the very top of your application's entry point or polyfills file, before any other application code or frameworks that rely on Zone context.","cause":"This usually means Zone.js was not imported or loaded correctly before its global `Zone` object was accessed. This can happen if the import path is incorrect, or if `Zone.js` is loaded too late in the application bootstrap process.","error":"ReferenceError: Zone is not defined"},{"fix":"Review the load order of libraries that perform global monkey-patching. Ensure Zone.js is loaded first. If using custom Zone hooks (`onHandleError`, `onInvokeTask`, etc.), ensure they correctly delegate to `parentZoneDelegate` to avoid infinite loops. For specific issues, check the Zone.js GitHub issues for known incompatibilities with other libraries.","cause":"This can occur when Zone.js's patching mechanism leads to infinite recursion, often due to improperly wrapping or monkey-patching APIs that Zone.js itself has already patched, or when certain libraries interfere with Zone.js's internal hooks.","error":"Maximum call stack size exceeded (or similar recursion error)"}],"ecosystem":"npm"}