finds.dev← search

// the find

mafintosh/why-is-node-running

★ 1,947 · JavaScript · MIT · updated Jan 2025

Node is running but you don't know why? why-is-node-running is here to help you.

A debugging tool that tells you which async handles (timers, sockets, file descriptors) are keeping a Node.js process alive when it should have exited. Indispensable when you have a test suite or server that hangs on shutdown and you can't figure out why.

Works three ways — imported inline, as a CLI wrapper, or preloaded via --import — so you can instrument without touching the source. The stack trace output includes the call site where each handle was created, not just the handle type, which is the actually useful part. It's tiny and dependency-free, so there's no risk in dropping it into a dev dependency. The SIGUSR1/SIGINFO signal approach in CLI mode lets you inspect a running process without modifying it.

Only surfaces handles Node exposes through async_hooks; if something is keeping the loop alive through a native addon or a C-level reference, you won't see it here. No output filtering — in a large process with hundreds of handles you get a wall of text with no grouping or sorting. The inline usage requires it to be your very first import, which is easy to forget and silently breaks if anything async runs before it. No Windows support for the SIGUSR1 signal path, so the CLI mode is degraded on Windows (you're stuck with inline usage).

View on GitHub →

// want more like this?

We dig through GitHub every week and send a few repos picked for what you actually care about — each with an honest take like this one.

Get finds in your inbox → Search again →