
What better to demystify a technology than to build a similar one from scratch. This is what we will attempt in this article 🙊
Interpreted vs. Compiled languages
Javascript is an interpreted language. That means that you need another program to execute the code. On the other hand, compiled languages need a compiler, which creates a binary file that the computer can understand.
NodeJS
One of the most popular interpreters for Javascript is NodeJS. But NodeJS does much more than execute Javascript; it also adds extra functionality such as a standard library, interaction with the OS, etc.
NodeJS is more than an interpreter; it’s a runtime environment.
To demystify and understand how NodeJS works, we will build a fierce competitor at the end of this article. Wait for it; it will change your life. Because, in the end, NodeJS is nothing more than another piece of software.
Most of it is developed in C++. Therefore, node
is a binary file compiled from a C++ project.
NodeJS, the Program
To check that NodeJS is just a program (a big and complex one, though), I encourage you to fork and clone it locally. Then, once you have it on your computer, build it:
For example, in Mac OS, the commands are:
$ ./configure
$ make -j4
Building the project takes quite a while, it took hours on my computer. When it finishes, you will see a new file in the root folder: node
. This file is the compiled version of the project.
You can use this binary to run Javascript.
$ ./node -e "console.log('Hello from Node.js ' + process.version)"
Or create a JS file in the same directory and run it.
$ ./node test.js
This node
file is actually the same (depends on the version, but it was built in the same way) that you have on your computer after installing NodeJS. If you run, which node
you get the path to that file. You can then use the path also to execute Javascript.
$ which node
/Users/llorencmuntaner/.nvm/versions/node/v12.7.0/bin/node
$ /Users/llorencmuntaner/.nvm/versions/node/v12.7.0/bin/node -e "console.log('Hello from Node.js ' + process.version)"
Hello from Node.js v12.7.0
The previous path is specific to my version and how I installed NodeJS, but the idea is the same for everybody.
You can even go to the folder ("/Users/llorencmuntaner/.nvm/versions/node/v12.7.0/bin/" in the previous example) and open the binary file node
. You won't find anything useful or even readable inside, but it’s a file, and files can be opened.
Building a NodeJS competitor: RunJS 🚀
Let’s build a NodeJS competitor—another runtime environment for Javascript, even better than Deno.
NodeJS is built in C++ and uses v8 as the Javascript engine. Whereas RunJS 🚀 is built in Python and uses a light engine called Dukpy.
This is how we want RunJS 🚀 to work at the end:
$ ./run_js test.js
The following is the code to read the filename from the arguments, open the file and execute the JS code with Dukpy:
With this file, I can execute a file like ./run_js test.js
. Yet, if we use setTimeout
in the code it fails: ReferenceError: identifier 'setTimeout' undefined
.
This “ReferenceError” is because setTimeout
is not part of the Javascript language but the standard API. Therefore, the runtime environment needs to provide this functionality. The same happens with “console.log” and many others.
One naive way to add this functionality is to create JS code for setTimeout
and add it to be evaluated along with the JS code.
If we execute the code now, there are no errors because now `setTimeout` exists. It doesn’t do anything, but it exists.
And this is how you build a competitor for NodeJS.
If you like this post, consider sharing it with your friends on Twitter or forwarding this email to them 🙈
Don't hesitate to reach out to me if you have any questions or see an error. I highly appreciate it.
And thanks to Michal for reviewing this article 🙏