My closest guess … it keeps track of the active things happening in your code, when there is nothing else happening, it simply exits.
This is essentially correct. Node keeps a reference count of things like timers and network requests. When you make a network, or other async request, set a timer, etc. Node adds on to this ref count. When the times/request resolve Node subtracts from the count.
This count is how Node decides whether to exit at the end of the event loop. When you get to the end of the event loop Node looks at this count and if it’s zero exits. Simply making a promise, doesn’t add to the ref count because it’s not an async request.
There’s a good talk about some of this by [Node core developer] Bert Belder that’s helpful: https://www.youtube.com/watch?v=PNa9OMajw9w