What the Heck is Node?

Here’s what you need to know about Node.js (or simply Node) and how it relates to npm right off the bat:

  • Node is JavaScript, but as a server-side language.
  • This is possible because of V8, Chromium’s JavaScript engine, which can run on its own, outside the confines of the browser.
  • Node and browser-based JavaScript can be very different, and have different capabilities, though both are JavaScript at their core.
  • You don’t need to know Node to use npm.

As you may know by now, npm stands for Node Package Manager (even if the official npm website displays amusing alternative names in its header on each page load, like “Ninja Pumpkin Mutants”).

The key thing to understand right away is this: “Node” and “Package Manager” are the two big, distinct pieces that combine to make npm.

We’ll cover what a package manager is and why you might consider using one when we get to the next chapter in this npm guide. For now, though, let’s focus on understanding what Node is, as it’s is a key part to understanding modern web development.

Guide chapters

  1. Who the Heck is This Guide For?
  2. What the Heck Does “npm” Mean?
  3. What the Heck is the Command Line?
  4. What the Heck is Node? (You are here!)
  5. What the Heck is a Package Manager?
  6. How the Heck Do You Install npm?
  7. How the Heck Do You Install npm Packages?
  8. What the Heck Are npm Commands?
  9. How the Heck Do You Install an Existing npm Project?

Node is JavaScript, but without all the browser

You likely know JavaScript primarily as a language that runs in the browser, similar to HTML and CSS. Yes, each of these languages has abstractions and supersets (like HAML for HTML, Sass for CSS, and TypeScript for JavaScript, as examples), as well as compilers and transpilers and all kinds of things that transform them into this shape or that. But ultimately, what these tools generate is vanilla (i.e., pure) code in the correct syntax, as if the abstractions were never used, to run in the browser and in the browser alone.

That’s the thing that took me the longest time to understand, and which, honestly, might be an even bigger missed memo than the whole npm thing. JavaScript doesn’t need a browser anymore in order to run. So, you’ll sometimes see me refer to Node JavaScript when distinguishing between it and “browser-based” JavaScript.

Server-side vs. client-side languages

At this point, I feel it’s worth taking a moment to explore the distinction between client-side languages (HTML, CSS, JavaScript), and server-side languages (basically all the rest of them). I won’t assume you have any experience with server-side languages, like PHP, Ruby, or Python, but if the concept of server-side languages is entirely new to you, it may be worth reading up on what they are. (To summarize: they’re code languages that run purely on a server instead of the browser, and generally have much broader and more powerful capabilities.)

This is relevant because several years ago, circa 2009, there were some very smart people who really liked JavaScript. In particular, they liked how fast JavaScript is (especially compared to the dominant server-side languages at the time, most notably, PHP and Ruby), and they wanted to have JavaScript everywhere, not just in a browser.

Ryan Dahl is the most prominent figure among them, and is credited with the invention of Node (and more recently, Deno, which is an anagram of Node). That’s a fun thing to know, but otherwise not strictly relevant to this topic.

How Node works

What is relevant, though, is that Node is essentially JavaScript as a server-side language that runs outside of the browser.

How is that possible? Under the hood, each browser has its own individual JavaScript engine. This is the part of the browser that actually runs JavaScript. Yes, that’s apparently a separate piece of the browser and not part of the same bits that do the HTML and CSS—which I guess makes sense when you think about the fact that we have literal APIs between the document and JavaScript. Heck, even the concept of a DOM makes more sense when you think of the department that handles JavaScript as a makeshift office down the hall from the HTML department.

The JavaScript engine in Chromium-based browsers is called V8, presumably after a specific kind of car engine (not the “vegetable drink” made mostly of tomato juice). V8 is by far the most popular JavaScript engine. Thanks to ECMAScript standardization efforts over approximately the last 15 years, there aren’t really any major differences between JavaScript engines anymore as far as browsers go. The engine used in Chrome is a lot like the engine that runs in Firefox, which is a lot like Safari, and so on. V8’s popularity these days has less to do with its distinctions, and more to do with Chrome’s self-sustaining ubiquity.

(Side note: Firefox’s JavaScript engine is named SpiderMonkey. That’s not particularly relevant, but it is further proof that Firefox is the coolest.)

Why does this matter? Well, it turns out, you can take the JavaScript engine out of a browser, and with some modification, run it on its own—kind of like if you decided to pull the stereo out of a car, tinker a bit, and make it into a stereo system for your home instead. V8 (and, presumably, a car’s stereo) can function perfectly fine as a standalone unit in any environment.

In other words: V8 makes it possible to run JavaScript anywhere. That’s why we have “Node” JavaScript and “browser-based” JavaScript.

Node is almost (but not exactly) JavaScript

To recap: JavaScript is a server-side language now! It’s called Node, and it could mean you don’t even need to learn anything about other server-side languages. We are front-end developers, and we have super-powers now.

Having said all this, however, Node and the JavaScript you’re used to running in the browser are both similar and very different from each other.

At the risk of veering too far into the weeds here: while both are JavaScript at their core, and while the language and syntax is the same, many staples of JavaScript in the browser (like the window or document, and even the oft-taken-for-granted alert) are not present in a purely server-side Node environment. There is no window, of course, when the language is just running on its own, and not in a browser. New Node JavaScript developers are often surprised to learn that even fetch is actually a browser API, not “pure” JavaScript.

Fear not, however. console.log is still your best friend, and there are many new, environment-specific features of Node JavaScript that differ from the browser’s implementation of JavaScript, such as the process object, which contains all the details about any processes that are currently running.

Node and its ecosystem have often, out of necessity, grown in a very different direction than browser-based JavaScript over the years. (As an obvious example: the syntax for imports between the two has been different for years, and only now is beginning to merge together again. We’ll talk about that a little more in the final chapter.)

Node long held the privilege of being able to move much faster than browsers when it comes to gaining new features, and has had its own set of concerns to deal with as well. It began to power server-side apps the same way Ruby and PHP had been doing for years, even while browsers were still trying to coalesce on standards. This has resulted in Node JavaScript and browser-based JavaScript becoming more like cousins than clones.

Here’s what I think is a fair analogy to explain the differences between the two JavaScript cousins: consider two similar musical instruments, say an upright bass and a modern electric bass guitar. Both instruments are tuned the same, and play the same notes; if you know one, in many ways, you kind of know the other. But while you’ll find it much easier to learn one after you’ve learned the other, playing the new one will be very different from what you’re used to.

The same, but different (Photos: Wikimedia Commons, Unplash)

Similarly, while one developer might write one type of JavaScript and a second developer writes in another type of JavaScript, their jobs are unlikely to look the same.

Node is JavaScript, with the capabilities of other server-side languages mentioned before—things like reading from and writing to the file system, access to system-level APIs, email, the ability to listen for and respond to requests, scheduled tasks… the list goes on.

I won’t say more on that here, but just know that while both are JavaScript at the end of the day, they run in different environments and are each capable of doing some things the other can’t. Even if you’ve written browser-based JavaScript before, Node will still likely feel a bit foreign to you beyond the foundational syntax, and will often be used in very different ways.

Running Node locally

As is generally the case with server-side languages, you do need to install Node before you can use it.

Node is commonly installed alongside npm, together as one, since the package manager part needs Node, and the Node part is more useful with a package manager. (You could say they’re a package deal. No, I will not apologize for that joke. I am a dad, after all.)

I’d like to stress at this point that you don’t need to know anything about Node to use npm. So, even though I’m about to cover some Node examples here, please consider this entire section something that’s nice to know, but inessential to that end. I feel it’s still useful to get a slightly better idea of how Node works, just for the sake of painting a more complete picture.

We will cover how to install Node and npm in an upcoming chapter of this guide. So, if you don’t have it installed already, you can either just glance over this part, or come back here when you do have it ready. Either way, this won’t be crucial for following along with this npm guide.

If you would like to try it out, you can create a new test.js file and put some generic JavaScript in it. Something contrived like the following code that logs some content to the console should do the trick:

console.log('Look, ma, Node hands!')

const oneThroughFive = [1, 2, 3, 4, 5]

oneThroughFive.forEach(number => {
  console.log(number)
})

Let’s say you save that code, then open the command line in a terminal window, navigate to where the file is (using cd, or “change directory”), and run node test.js to get the following output:

Look, ma, Node hands!
1
2
3
4
5

You can also enter node by itself (no filename afterwards) to open an interactive terminal where you can run arbitrary Node JavaScript. If you’ve ever popped open the console in your browser’s DevTools to type out some code, that’s exactly what this is, just on the command line with Node instead.

Try it out if you’d like to, assuming you do have Node installed. But again, this is all just for illustration and not required for using npm.

A screenshot of an open terminal window showing Node version 17.0.1 running and the output from the previous example under it.

What’s next

Everything we covered in this chapter is nifty and hopefully helps to show you (however simply) the way Node works. Remember, while we didn’t cover any specific example of it, Node is capable of doing anything a server-side language can do. It’s hopefully not too hard to picture how running some JavaScript to do virtually anything you can think of on the system level or even on a remote server is very appealing and advantageous.

The concept of Node started as a way to run JavaScript outside of the browser. As such, we have Node-based packages of scripts that are used to help us with front-end development. So how do we install those packages and make sure they’re not only updated but that they can be uninstalled? That’s contained in the last two letters in the npm abbreviation: package manager.

In other words, npm is a tool that manages packages written in Node JavaScript. What exactly is a package manager and how does npm qualify as one? That’s up next in our npm guide.