1. Node.js

Node.js is an open-source and cross-platform JavaScript runtime environment, that runs the V8 JavaScript engine, the core of Google Chrome, outside of the browser. [1]

V8 is the name of the JavaScript engine that powers Google Chrome. It’s the thing that takes our JavaScript and executes it while browsing with Chrome. V8 provides the runtime environment in which JavaScript executes. The DOM and the other Web Platform APIs are provided by the browser.

  • A Node.js app runs in a single process, without creating a new thread for every request.

  • Node.js provides a set of asynchronous I/O primitives in its standard library that prevent JavaScript code from blocking and generally, libraries in Node.js are written using non-blocking paradigms, making blocking behavior the exception rather than the norm.

Both the browser and Node.js use JavaScript as their programming language.

  • In the browser, most of the time what you are doing is interacting with the DOM, or other Web Platform APIs like Cookies.

    Those do not exist in Node.js, of course. You don’t have the document, window and all the other objects that are provided by the browser.

  • And in the browser, we don’t have all the nice APIs that Node.js provides through its modules, like the filesystem access functionality.

  • Since JavaScript moves so fast, but browsers can be a bit slow to upgrade, sometimes on the web you are stuck with using older JavaScript / ECMAScript releases.

    You can use Babel to transform your code to be ES5-compatible before shipping it to the browser, but in Node.js, you won’t need that.

Node.js assumes it’s always running in a development environment. You can signal Node.js that you are running in production by setting the NODE_ENV=production environment variable.

This is usually done by executing the command

export NODE_ENV=production

in the shell, but it’s better to put it in your shell configuration file (e.g. .bash_profile with the Bash shell) because otherwise the setting does not persist in case of a system restart.

You can also apply the environment variable by prepending it to your application initialization command:

NODE_ENV=production node app.js

This environment variable is a convention that is widely used in external libraries as well.

Setting the environment to production generally ensures that

  • logging is kept to a minimum, essential level

  • more caching levels take place to optimize performance

You can use conditional statements to execute code in different environments:

if (process.env.NODE_ENV === 'development') {
  // ...
}

if (process.env.NODE_ENV === 'production') {
  // ...
}

if (['production', 'staging'].includes(process.env.NODE_ENV)) {
  // ...
}

2. NPM package manager

npm consists of three distinct components: [3]

  • Use the website to discover packages, set up profiles, and manage other aspects of your npm experience.

  • The CLI runs from a terminal, and is how most developers interact with npm.

  • The registry is a large public database of JavaScript software and the meta-information surrounding it.

2.1. About packages and modules

A package is a file or directory that is described by a package.json file. A package must contain a package.json file in order to be published to the npm registry. [2]

Packages can be unscoped or scoped to a user or organization, and scoped packages can be private or public.

A scope allows you to create a package with the same name as a package created by another user or organization without conflict.

When listed as a dependent in a package.json file, scoped packages are preceded by their scope name.

The scope name is everything between the @ and the /:

  • "npm" scope:

    @npm/package-name
  • "npmcorp" scope:

    @npmcorp/package-name

A module is any file or directory in the node_modules directory that can be loaded by the Node.js require() function.

To be loaded by the Node.js require() function, a module must be one of the following:

  • A folder with a package.json file containing a "main" field.

  • A JavaScript file.

Note: Since modules are not required to have a package.json file, not all modules are packages. Only modules that have a package.json file are also packages.

2.2. Introduction to npm CLI

npm is the standard package manager for Node.js. [4]

In September 2022 over 2.1 million packages were reported being listed in the npm registry, making it the biggest single language code repository on Earth, and you can be sure there is a package for (almost!) everything.

It started as a way to download and manage dependencies of Node.js packages, but it has since become a tool used also in frontend JavaScript.

Yarn and pnpm are alternatives to npm cli. You can check them out as well.

2.3. Packages

npm manages downloads of dependencies of your project.

2.3.1. Installing all dependencies

If a project has a package.json file, by running

npm install

it will install everything the project needs, in the node_modules folder, creating it if it’s not existing already.

2.3.2. Installing a single package

You can also install a specific package by running

npm install <package-name>

Furthermore, since npm 5, this command adds <package-name> to the package.json file dependencies. Before version 5, you needed to add the flag --save.

Often you’ll see more flags added to this command:

  • --save-dev installs and adds the entry to the package.json file devDependencies

  • --no-save installs but does not add the entry to the package.json file dependencies

  • --save-optional installs and adds the entry to the package.json file optionalDependencies

  • --no-optional will prevent optional dependencies from being installed

Shorthands of the flags can also be used:

  • -S: --save

  • -D: --save-dev

  • -O: --save-optional

The difference between devDependencies and dependencies is that the former contains development tools, like a testing library, while the latter is bundled with the app in production.

As for the optionalDependencies the difference is that build failure of the dependency will not cause installation to fail. But it is your program’s responsibility to handle the lack of the dependency.

2.3.3. Updating packages

Updating is also made easy, by running

npm update

npm will check all packages for a newer version that satisfies your versioning constraints.

You can specify a single package to update as well:

npm update <package-name>

2.3.4. Versioning

In addition to plain downloads, npm also manages versioning, so you can specify any specific version of a package, or require a version higher or lower than what you need.

Many times you’ll find that a library is only compatible with a major release of another library.

Or a bug in the latest release of a lib, still unfixed, is causing an issue.

Specifying an explicit version of a library also helps to keep everyone on the same exact version of a package, so that the whole team runs the same version until the package.json file is updated.

In all those cases, versioning helps a lot, and npm follows the semantic versioning (semver) standard.

You can install a specific version of a package, by running

npm install <package-name>@<version>

2.4. Running Tasks

The package.json file supports a format for specifying command line tasks that can be run by using

npm run <task-name>

For example:

{
  "scripts": {
    "start-dev": "node lib/server-development",
    "start": "node lib/server-production"
  }
}

It’s very common to use this feature to run Webpack:

{
  "scripts": {
    "watch": "webpack --watch --progress --colors --config webpack.conf.js",
    "dev": "webpack --progress --colors --config webpack.conf.js",
    "prod": "NODE_ENV=production webpack -p --config webpack.conf.js"
  }
}

So instead of typing those long commands, which are easy to forget or mistype, you can run

$ npm run watch
$ npm run dev
$ npm run prod

2.5. What is the difference between npm and NPX?

The Npm stands for Node Package Manager. Npm is a package installation tool. Npx is a tool for executing packages. NPX is a npm package runner whose job it is to execute a package from the registry without ever installing it. [5]

2.5.1. Which is better npx vs npm?

If the package in issue is only to be used once or twice, rather than every time the project runs, it is preferable to utilize NPX, which will execute the package without installing it. NPM is used to install packages, which we should do if our project requires dependencies or packages.

2.5.2. Is NPX installed with npm?

That depends on the version of the NPM. For NPM version 5.2.0, NPX will be installed automatically. For lower versions, you will need to install it separately.

2.5.3. Why we use NPX instead of npm?

NPX stand for Node Package Execute. With the aid of NPX, we may run packages in a clear and simple manner while avoiding versioning, dependency problems, and installing extra packages that we just need to test.

3. Node Version Manager

nvm is a version manager for node.js, designed to be installed per-user, and invoked per-shell. nvm works on any POSIX-compliant shell (sh, dash, ksh, zsh, bash), in particular on these platforms: unix, macOS, and windows WSL. [6]

$ nvm use 16
Now using node v16.9.1 (npm v7.21.1)
$ node -v
v16.9.1
$ nvm use 14
Now using node v14.18.0 (npm v6.14.15)
$ node -v
v14.18.0
$ nvm install 12
Now using node v12.22.6 (npm v6.14.5)
$ node -v
v12.22.6