why-is-node-running

3.2.2 · active · verified Sun Apr 19

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.

Common errors

Warnings

Install

Imports

Quickstart

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.

import whyIsNodeRunning from 'why-is-node-running'; // Should be the first import for best results
import { createServer } from 'node:net';

console.log('Starting application...');

// Function to simulate a long-running task or server
function startServerAndInterval() {
  // A setInterval keeps the process alive
  setInterval(() => {
    // console.log('Interval running...');
  }, 1000);

  // A TCP server also keeps the process alive
  const server = createServer();
  server.listen(0, () => {
    const address = server.address();
    console.log(`Server listening on port ${typeof address === 'string' ? address : address?.port}`);
  });

  // Add a listener that might not be cleaned up
  process.on('SIGINT', () => {
    console.log('Received SIGINT. Shutting down...');
    server.close(() => {
      console.log('Server closed.');
      process.exit(0);
    });
  });
}

// Call the function multiple times to create several handles
startServerAndInterval();
startServerAndInterval();

// Use setImmediate to log active handles after the current event loop turn
// This will show what's keeping Node.js running.
setImmediate(() => {
  console.log('\nChecking for active handles:');
  whyIsNodeRunning();
  console.log('\nIf the process does not exit, inspect the output above.');
});

view raw JSON →