The JavaScript engine and the JavaScript runtime are responsible for running JavaScript code, the JavaScript engine alone will freeze the page as long as the call stack is not empty. it means that the JavaScript engine is synchronous. but with the JavaScript runtime, we can run asynchronous code.
The JavaScript runtime is a set of features that exists in the browser and while the JavaScript engine runs our code synchronously, the browser works in the background.
The JavaScript runtime features are :
- Web API (DOM, fetch(), setTimeout() and more): this is the window object provided by the browser with a set of things that we can use asynchronously.
- Event Loop
- Callback queue
The way it works is this: when we have items in the call stack and it finds something that is not part of JavaScript and it belongs to the web API, for example, the setTimeout, it will send it to the web API. the web API will work on the setTimeout in the background and when it done, it will send the callback to the callback queue. the event loop will keep looping to check if the call stack is empty. when the call stack is empty the event loop will move the callback from the callback queue to the call stack which will then execute it.
There is a nice online tool that demonstrates the process and the interaction between the runtime features. try it out here.
So the JavaScript runtime is in the browser and it helps to run code asynchronously but what about running JavaScript on the server if we don’t have a browser with JavaScript runtime? to run JavaScript on the server we use node.js which is a JavaScript runtime too and instead of exposing a web API through the window object, it exposes the global API.