Skip to main content

Node.js

Node.js runs JavaScript outside the browser. See also PM2 for running Node apps in production and Jest for testing.

Install

nvm

nvm lets you install and switch between node versions from the command line.

# Install
NVM_VER=v0.40.4
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/$NVM_VER/install.sh | bash

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/$NVM_VER/install.sh | bash

source ~/.bashrc
nvm --version

# If ~/.bash_profile exists, source ~/.bashrc from it:
# if [ -f ~/.bashrc ]; then
# . ~/.bashrc
# fi

# List remote LTS versions only
nvm ls-remote --lts

# Choose a version
NODE_VER=v24.16.0

# Install / use it
nvm install $NODE_VER
nvm use $NODE_VER

# nvm keeps "forgetting" node in a new terminal session — set a default
nvm alias default $NODE_VER

# List installed versions
nvm ls

# Run a script with a specific version
nvm run $NODE_VER app.js

# Remove a version
nvm uninstall $NODE_VER

# Remove the current node binary
rm `which node`

# Upgrade nvm itself
(
cd "$NVM_DIR"
git fetch --tags origin
git checkout `git describe --abbrev=0 --tags --match "v[0-9]*" $(git rev-list --tags --max-count=1)`
) && \. "$NVM_DIR/nvm.sh"

APT (Debian/Ubuntu)

Install from NodeSource when you need a system-wide package.

# Current setup script (replace the version as needed)
curl -sL https://deb.nodesource.com/setup_10.x | sudo bash -
sudo apt-get install nodejs

# Pin an old series
apt install nodejs=0.10*

# Install an old 12.x directly
sudo curl -sL https://deb.nodesource.com/setup_12.x -o nodesource_setup.sh
sudo bash nodesource_setup.sh
sudo apt-get -y install nodejs

npm

Use the npm bundled with the node LTS version.

# Reinstall / upgrade npm itself
npm install npm@latest -g

# Initialize a project
npm init

# Inspect config and the resolved node version
npm config list

# Funding info
npm audit fund
npm config set fund false # turn it off

# Update globally-installed packages (no output means everything is current)
npm update -g
npm outdated -g

# List installed packages
npm list

# Remove packages not listed in package.json
npm prune

Linking node/npm/pm2 into /usr/bin

When npm -v or pm2 -v work interactively but pm2 deploy reports command not found, expose the binaries system-wide:

sudo ln -s /root/.nvm/versions/node/v22.15.0/bin/npm /usr/bin/npm
sudo ln -s /root/.nvm/versions/node/v22.15.0/bin/node /usr/bin/node
sudo ln -s /root/.nvm/versions/node/v22.15.0/bin/pm2 /usr/bin/pm2

# Or point them at whatever is currently active
sudo rm -f /usr/bin/npm /usr/bin/node /usr/bin/pm2
sudo ln -s $(which npm) /usr/bin/
sudo ln -s $(which node) /usr/bin/
sudo ln -s $(which pm2) /usr/bin/

# A symlink can break after updating/compiling/installing software (it shows up
# as red text in ls). Inspect and repair it:
readlink -v /usr/bin/npm
sudo ln -sfn /root/.nvm/versions/node/v22.15.0/bin/npm /usr/bin/npm
sudo ln -sfn /root/.nvm/versions/node/v22.15.0/bin/node /usr/bin/node
sudo ln -sfn /root/.nvm/versions/node/v22.15.0/bin/pm2 /usr/bin/pm2

Updating packages

npm install # install everything from package.json
npm install package_name --save # add / upgrade a specific dependency
npm outdated # which modules are out of date
npm update # update to the wanted version
npm update --save # also bump the numbers in package.json
npm update -g # update global packages

# A short cheat sheet
npm list --depth 0 # top-level packages in this project
npm audit # which dependencies are vulnerable
npm update package_name # update one already-installed package
npm uninstall package_name && npm install package_name@version # pin a version
npm cache clean --force # clear npm's package cache

Express

npm install express --save

Generate a template project (the generator is deprecated but still handy):

npm install express-generator -g
express --view=pug project1
cd project1
npm install
vi bin/www # change the port in normalizePort(process.env.PORT || '3000')
DEBUG=project1:* npm start
# Visit http://localhost:3000/

forever

forever list
forever start dist/app.js
forever restart dist/app.js
forever stop 38282
forever stopall

Useful packages

npm-check-updates

Upgrade package.json version hints to the newest releases (including major versions) so npm can install them.

npm install -g npm-check-updates
ncu # show available updates
ncu --upgrade # ncu -u — write them to package.json
ncu --interactive # ncu -i
ncu --interactive --format group

# Without installing globally
npx npm-check-updates
npx npm-check-updates -u

npkill

Find and remove old, heavy node_modules folders.

npm install npkill -g
npx npkill
npx npkill -D -x
npx npkill --delete-all --directory C:\Temp

Mock Service Worker (MSW)

npm install msw --save-dev

Jest

jest --env=node # run in a specific environment
npx jest --showConfig
npx jest --coverage

local-ssl-proxy

npx local-ssl-proxy --key localhost+2-key.pem --cert localhost+2.pem --source 3001 --target 3000 --hostname localhost

Miscellaneous

# Windows build tools
npm i -g windows-build-tools

# V8 stack size (default: 984 kB)
node --v8-options | grep -B0 -A1 stack-size

-D / --save-dev: the package appears in devDependencies.

Jest: "Cannot find module" with path aliases

Jest does not support path aliases by default, so a test can fail with Cannot find module 'src/index' from 'index.js'. Add a mapping in jest.config.js:

const customJestConfig = {
moduleNameMapper: { '@src(.*)$': '<rootDir>/src/$1' },
};

Concepts

Relative URLs in Node.js

You don't use them. In Node.js there is nothing for a URL to be relative to. When describing network behavior for a Node.js application, use the absolute URLs you are requesting. If you are using MSW with a Node.js-based test runner such as Jest or Vitest, configure the runner to support relative URLs (for example, by polyfilling the window.location object).