Node.js & npm
Debian Development Machine Setup
Chapter 6 ยท Node.js & npm
Node.js has the same shape of problem as Python in Chapter 5, with a different twist. Debian packages Node,
but the packaged version is fixed at release time, and Node moves quickly. So the question for
devserver is not just “how do I install Node?” but “which Node, and how do I
change my mind later?” This chapter answers both, and finishes with npm, Node's package manager.
What Debian Gives You
Start with the Chapter 3 checks, before installing anything:
On a fresh desktop install Node is probably not there. apt policy shows what Debian offers.
On Trixie the nodejs package is 20.19.2 (with Debian's security fixes applied),
and npm is a separate package, version 9.2.0, with a long list of dependencies. The
nodejs package does depend on corepack, a helper that can give you access to other
JavaScript package managers.
Which Node? The Release Lines
Node publishes a new major version each year, and gives each an LTS (Long Term Support) phase. As of the end of September 2026, the schedule looks like this:
| Version | Status now | Maintenance phase begins | End of life |
|---|---|---|---|
| Node 20 (Iron) | End of life | 22 October 2024 | 30 April 2026 |
| Node 22 (Jod) | Maintenance LTS | 21 October 2025 | 30 April 2027 |
| Node 24 (Krypton) | Active LTS | 20 October 2026 | 30 April 2028 |
| Node 26 | Current (becomes LTS on 28 October 2026) | 20 October 2027 | 30 April 2029 |
“Active LTS” is the sweet spot for real work: it is stable and still receiving improvements. Node 24
is the one to pick today, and it is only a few weeks from moving to the less active Maintenance phase, which
is still fully supported. The Node project's own advice is that production applications should use Active or
Maintenance LTS releases. Check nodejs.org before you decide, because these dates come from the
project's published schedule and can be adjusted.
Three Ways to Get Node
| Method | Version you get | Switching versions | Trade-off |
|---|---|---|---|
Debian package (apt install nodejs npm) | Fixed: Node 20 on Trixie | Not possible | Simple and integrated with apt, but old, and npm drags in a large set of packages. |
| A third-party apt repository (such as NodeSource) | The major version the repository provides | Only by changing the repository | Newer, still managed by apt, but you trust a third party's key and packages. Linux Package Managers 3 covers adding repositories safely. |
| nvm (a version manager) | Any version you choose | One command, or automatic per project | Lives in your home directory, outside apt. You manage it yourself. |
For a development machine, the version manager is the best fit, for the same reason pyenv was the answer in
Chapter 5: different projects want different Node versions, and you should be able to switch without touching
the system. This chapter uses nvm (Node Version Manager). If you install Node this way, do
not also install the Debian nodejs package. Two Nodes on one machine is exactly the
confusion Chapter 3 taught you to avoid.
Installing nvm
The nvm project's documentation gives a one-line installer that pipes a downloaded script into
bash. As with pyenv, the safer route is to clone the repository at a specific release and add
the shell lines yourself, so you know exactly what runs. The current release at the time of writing is
v0.40.8; check the project page for a newer one.
Then add these lines to ~/.bashrc:
Open a new terminal and check it worked. Note that nvm is a shell function, not a
program, so the usual which nvm will find nothing. Use command -v:
Installing and Switching Node Versions
type -a node now shows a path under ~/.nvm/versions/node/. That is Chapter 3's
“first copy wins” idea again: nvm puts the chosen version's directory at the front of your
PATH. Switching with nvm use changes which directory is first. Each Node version also
comes with its own npm.
Choosing a version per project
Put the version a project needs in a file called .nvmrc in the project's root, and commit it. It
contains a version such as 24, or lts/*. Then, from inside the project:
debserver will run should be the version .nvmrc names, so
what you test here is what you deploy there. Decide that before you start the project, not after the first
surprise.
npm: Projects and Global Tools
npm does two different jobs, and confusing them causes most npm problems. You already know the equivalent split from Python (Chapter 5): libraries for a project, and tools you run.
Project dependencies
| File / folder | What it is | Commit it? |
|---|---|---|
package.json | Your project's description and its list of dependencies. | Yes |
package-lock.json | The exact version of every package installed, including dependencies of dependencies. | Yes |
node_modules/ | The installed packages themselves. Large, and rebuildable. | No (add to .gitignore) |
This is the same idea as requirements.txt in Chapter 5. The lock file is the record, and
node_modules is disposable. To rebuild exactly what the lock file describes, use
npm ci (a clean install from the lock file), rather than npm install, which may
update versions:
Global tools
Use npm install -g for command-line tools you want available everywhere. With nvm this needs
no sudo, because the tools install into the current Node version's own folder
in your home directory:
nvm use, a tool you installed globally under the first version can seem to vanish. It has not
gone; it is simply installed under the other version. You can carry tools across with
nvm install --reinstall-packages-from=current NEW-VERSION. For anything a project depends on,
list it in that project's package.json instead of relying on a global copy.
npx runs a package's command without installing it globally: npx cowsay hi.
It is a good way to try something once without leaving anything behind.
Which Tool for Which Job
| You want to… | Use |
|---|---|
| Pick or switch the Node version | nvm, with a .nvmrc per project |
| Add a library to a project | npm install NAME (locked in package-lock.json) |
| Rebuild a project exactly | npm ci |
| Install a command-line tool for yourself | npm install -g NAME (or npx for a one-off) |
| Run something Debian itself depends on | The apt nodejs package (only if you need it) |
For the language itself, see the Node.js Fundamentals course. The next chapter does for PHP what these last two did for Python and Node.
Hands-On Exercises
Before installing anything, run the Chapter 3 checks for Node on devserver. Then, using the release-line table and the Debian package facts, decide which Node version you will install and write a short justification. Say what would change your mind.
Install nvm and the current LTS, and record what type -a node reports. Then install a second Node major version, create two project folders each with its own .nvmrc, and show that nvm use selects the right version in each.
Create an npm project, install lodash, write a small script that uses it, then delete node_modules and restore it with npm ci. Next, install cowsay globally under one Node version, switch versions, and explain what you see and how to fix it.
Chapter 6 Quick Reference
- Debian 13 packages Node 20.19.2;
npm(9.2.0) is a separate, dependency-heavy package. Upstream Node 20 reached end of life on 30 April 2026 - As of September 2026: Node 24 is Active LTS, Node 22 is Maintenance LTS, Node 26 becomes LTS on 28 October 2026 (check nodejs.org)
- For development, use a version manager (nvm) rather than the Debian package; do not install both
- Install nvm at a release tag:
git clone https://github.com/nvm-sh/nvm.git ~/.nvmthengit checkout v0.40.8, and add three lines to~/.bashrc command -v nvm(it is a function, sowhichdoes not work)nvm install --lts,nvm alias default 'lts/*',nvm ls,nvm use VERSION,nvm current- A
.nvmrcfile pins a project's Node version;nvm usereads it - Commit
package.jsonandpackage-lock.json; never commitnode_modules npm cirebuilds exactly from the lock file;npm installmay update versions- With nvm,
npm install -gneeds no sudo, but global tools belong to one Node version;npxruns a tool once