{"id":12669,"library":"why-is-node-running","title":"why-is-node-running","description":"why-is-node-running is a diagnostic utility for Node.js environments, designed to identify active handles (like timers, network connections, and event listeners) that prevent a Node.js process from exiting gracefully. The current stable version is 3.2.2. Releases are active but somewhat irregular, typically driven by Node.js version updates or small feature enhancements and bug fixes. Its key differentiator lies in its ability to pinpoint the exact code locations responsible for these lingering handles, providing stack traces to aid in debugging unexpected process longevity or potential memory leaks, which is crucial for server-side applications and long-running scripts. It supports both programmatic integration and CLI usage, including a convenient `--import` flag for preloading. The package also provides TypeScript type definitions for enhanced developer experience.","status":"active","version":"3.2.2","language":"javascript","source_language":"en","source_url":"https://github.com/mafintosh/why-is-node-running","tags":["javascript","debug","devops","test","events","handles","typescript"],"install":[{"cmd":"npm install why-is-node-running","lang":"bash","label":"npm"},{"cmd":"yarn add why-is-node-running","lang":"bash","label":"yarn"},{"cmd":"pnpm add why-is-node-running","lang":"bash","label":"pnpm"}],"dependencies":[],"imports":[{"note":"Since v3.0.0, this package is ESM-only and requires Node.js 20.11 or higher. Direct `require()` statements will result in an `ERR_REQUIRE_ESM` error.","wrong":"const whyIsNodeRunning = require('why-is-node-running');","symbol":"whyIsNodeRunning","correct":"import whyIsNodeRunning from 'why-is-node-running';"},{"note":"The `why-is-node-running/include` entrypoint is specifically designed for Node.js's `--import` CLI flag for preloading. Importing it directly in application code is not the intended use and may not yield the expected behavior or could lead to errors if not handled carefully within an ESM context.","wrong":"import 'why-is-node-running/include';","symbol":"include entrypoint for --import","correct":"node --import why-is-node-running/include my-app.js"},{"note":"The package ships with TypeScript type definitions. While the main export is a default function, specific types like `ActiveHandle` can be imported for detailed typing.","wrong":"const whyIsNodeRunning: any = require('why-is-node-running');","symbol":"Types","correct":"import whyIsNodeRunning from 'why-is-node-running';\nimport type { ActiveHandle } from 'why-is-node-running';"}],"quickstart":{"code":"import whyIsNodeRunning from 'why-is-node-running'; // Should be the first import for best results\nimport { createServer } from 'node:net';\n\nconsole.log('Starting application...');\n\n// Function to simulate a long-running task or server\nfunction startServerAndInterval() {\n  // A setInterval keeps the process alive\n  setInterval(() => {\n    // console.log('Interval running...');\n  }, 1000);\n\n  // A TCP server also keeps the process alive\n  const server = createServer();\n  server.listen(0, () => {\n    const address = server.address();\n    console.log(`Server listening on port ${typeof address === 'string' ? address : address?.port}`);\n  });\n\n  // Add a listener that might not be cleaned up\n  process.on('SIGINT', () => {\n    console.log('Received SIGINT. Shutting down...');\n    server.close(() => {\n      console.log('Server closed.');\n      process.exit(0);\n    });\n  });\n}\n\n// Call the function multiple times to create several handles\nstartServerAndInterval();\nstartServerAndInterval();\n\n// Use setImmediate to log active handles after the current event loop turn\n// This will show what's keeping Node.js running.\nsetImmediate(() => {\n  console.log('\\nChecking for active handles:');\n  whyIsNodeRunning();\n  console.log('\\nIf the process does not exit, inspect the output above.');\n});","lang":"typescript","description":"This quickstart demonstrates how to programmatically use `why-is-node-running` to identify open handles (like `setInterval` and `net.Server`) that prevent a Node.js process from exiting. It intentionally creates multiple handles and then uses `whyIsNodeRunning()` to print a detailed report of these active handles and their associated stack traces to the console."},"warnings":[{"fix":"Migrate your project to use ES modules (`import` syntax and `\"type\": \"module\"` in `package.json`) or ensure your Node.js version is 20.11+. For CommonJS projects, explicitly install `why-is-node-running@2.x`.","message":"Version 3.0.0 of `why-is-node-running` introduced significant breaking changes by moving to ECMAScript Modules (ESM) only and raising the minimum required Node.js version to 20.11 or higher. This makes the package incompatible with CommonJS-based environments. Existing projects using `require()` will need to migrate to `import` statements or use `why-is-node-running@v2.x` for CommonJS compatibility.","severity":"breaking","affected_versions":">=3.0.0"},{"fix":"Instead of `import 'why-is-node-running/include';` in your code, execute your Node.js application with `node --import why-is-node-running/include your-app.js`.","message":"When using `why-is-node-running/include` for preloading, it must be specified via Node.js's `--import` CLI flag, not as a direct `import` statement within your application code. Attempting to `import 'why-is-node-running/include'` might lead to unexpected behavior or errors.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Be aware that stack traces will now show relative paths for files within your project, which can be beneficial for readability across different environments. No fix is required, but adjust expectations for log parsing.","message":"The output for file paths in stack traces became relative to the current working directory as of v3.2.0. While not a breaking change in functionality, users accustomed to absolute paths might notice a difference. Full absolute paths are still used if a file is outside the current working directory.","severity":"gotcha","affected_versions":">=3.2.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Update your code to use `import whyIsNodeRunning from 'why-is-node-running';` and ensure your project is configured for ESM (e.g., by adding `\"type\": \"module\"` to your `package.json` file or renaming files to `.mjs`). If migration is not feasible, downgrade to `why-is-node-running@2.x`.","cause":"Attempting to `require()` `why-is-node-running` in a CommonJS module after upgrading to v3.0.0 or later.","error":"Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: ... why-is-node-running/index.js"},{"fix":"Ensure you are using a default import: `import whyIsNodeRunning from 'why-is-node-running';`. If in a CJS context (and using v2.x), it would be `const whyIsNodeRunning = require('why-is-node-running');`.","cause":"Incorrect import of the default export, often trying to destructure a named export that doesn't exist, or a mismatch in ESM/CJS expectations.","error":"TypeError: whyIsNodeRunning is not a function"}],"ecosystem":"npm"}