"Why does simple "Hello world"-program exit immediately after printing to console but starting an HTTP server keeps running forever?"
Consider the classic "Hello world!"-program. It prints short text to the screen and then exits. The control is immediately returned to the originating shell.
However, starting an HTTP server behaves differently. It will not return to console but keeps on running indefinitely.
Why does this happen?
Node.js keeps track of active event listeners
Deep in the internals of Node.js there is bookkeeping being done. The number of active event listeners is being counted.
Events and event-driven programming model are what make Node.js special. Events are also the life blood that keep a Node.js program alive. Event listeners can be for example
a timer waiting for a specific time to elapse
a handler to be invoked whenever a new HTTP connection is established
a code that's waiting for a file read to complete
And Node.js keeps track of them.
Program lives as long as there are active event listeners
A Node.js program will keep running as long as there are active event listeners present. After the last event listener has finished or otherwise terminated the Node.js program will also terminate.
This is exactly what happens in the example. Node.js reads the source for the Hello world program and executes it. The program prints to the console. When it reaches the end there are no active event listeners left and the program exits. In fact, the program is so simple that there never were any event listeners at all.
However, the HTTP server behaves differently. The program creates an HTTP server and binds it to a port. By doing that, it registers a handler to be invoked whenever a new HTTP connection is established. At the point where the program code reaches the end there is exactly one event listener active. The program will not terminate but keeps on running instead.
You could terminate the server program by issuing server.close() after a while. It would then finish serving any pending connections an eventually exit. Since at that point it would have no active event listeners present.
Semantic Versioning Cheatsheet
Learn the difference between caret (^) and tilde (~) in package.json.