In Node.js there are two fundamental aspects to keep in mind.
We are programming a web server
You surely have noticed that when you create a new directory and insert files inside it, they are immediately accessible via the web with the LAMP or LEMP stack. This happens because Apache and nginx automatically manage them for you.
This does not happen in Node.js. We need to instruct Node on how to manage that directory and those files (for example with express.static() in ExpressJS). If we do not, that directory and those files will never be accessible.
We must understand that with Node.js we are actually programming a web server from scratch. Node provides only the basic modules for networking management and other activities. It is our job to use those modules (either directly or through a specific NPM package) to manage our site or our app.
Take for example file uploading: Apache and nginx simply pass the temporarily uploaded file via HTTP to PHP that manages it with the supeglobal array $_FILES starting from the copy stored in the /tmp directory.
In this case the server level (Apache and nginx) is kept separates from the application layer (PHP) and consists of two distinct steps. In Node, this separation does not exist and it is for this reason that we usually use packages as formidable or multer to handle both steps in a single solution.
Application level and server level
You certainly have implemented an e-commerce shopping cart with PHP sessions and noticed that when switching browser your cart will always restart with zero products on your first connection.
This is because PHP sessions work at the application level: session_start() initializes the session by sending a specific cookie (for example, PHPSESSID ) to the browser. So if you add a product to your cart with, say, browser A and then try with browser B, you will notice that the shopping cart in browser B is empty.
In Node.js, on the contrary, you might get an unexpected result: a shopping cart with the same product in both browsers. The point is that with Node there is no separation between the application layer and the server level: if you use request.session with the express-session package for ExpressJS, each time you add a variable, that variable will persist for the entire life cycle of the application (ie until the execution of node app.js will not be terminated).
So if the cart is not created (and later destroyed with the delete operator) as a result of a specific action (for example in a route) but at the very beginning of your app, you will have the same cart shared among all clients that will connect to your site.
In other words, in Node one should always understand first if the code he/she writes will affect the application layer or the server level and act accordingly.