JavaScript used to live only inside the browser. Node.js changed that. It lets you run JavaScript on your computer, your server, and anywhere else โ which is why it powers most of the modern web tooling you'll encounter as a developer.
What is Node.js?
Node.js is a JavaScript runtime. A runtime is a program that reads your code and executes it. Your browser has a JavaScript runtime built in. Node.js is a separate runtime that runs outside the browser โ on your computer or on a server.
That one change unlocks a huge amount:
- You can read and write files on your disk
- You can make network requests directly
- You can build web servers
- You can write command-line tools
- You can run build tools like bundlers and compilers
Every major JavaScript framework you'll encounter โ Next.js, Express, Remix, Astro โ requires Node.js to run. Every AI SDK for JavaScript runs on Node.js. Git operations through JavaScript, CLI tools like create-react-app, package installers โ all Node.js underneath.
If you're learning web development, you will need Node.js. There's no path around it.
Install Node.js: the right way (nvm)
You could download Node.js directly from nodejs.org. That works, but it creates a problem: if you later need a different version for a different project, you have to uninstall and reinstall.
The better approach is nvm (Node Version Manager). It lets you install multiple Node.js versions and switch between them with one command.
Mac / Linux โ install nvm
Open your terminal (see the terminal beginner guide if you need help with this) and run:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash
This downloads and runs the nvm installer. After it finishes, close and reopen your terminal (important โ nvm won't work in the same window). Then verify it installed:
nvm --version
You should see a version number like 0.40.3. If you see command not found, close and reopen the terminal again.
Now install Node.js LTS:
nvm install --lts
nvm use --lts
Windows โ install nvm-windows
nvm-windows is a separate project (not the same as nvm on Mac/Linux) but works the same way.
- Go to github.com/coreybutler/nvm-windows/releases
- Download
nvm-setup.exefrom the latest release - Run the installer
- Open Windows Terminal (or PowerShell) as Administrator
- Run:
nvm install lts
nvm use lts
Alternative: direct download from nodejs.org
If you just want Node.js installed and don't need version switching:
- Go to nodejs.org
- Download the LTS version (left button โ do not pick "Current")
- Run the installer
- Accept defaults throughout
Verify the installation
Run both of these:
node --version
v22.16.0
npm --version
10.9.2
Your exact numbers will differ โ that's fine. What matters is that both commands return a version number instead of an error. If either says command not found, the installation didn't complete โ restart your terminal and try again.
LTS vs Current โ which one to use
Node.js releases two types of versions:
| Type | Description | Use when |
|---|---|---|
| LTS (Long Term Support) | Stable, supported for 30 months, security patches | Always use this for projects |
| Current | Latest features, less stable, shorter support window | Only if you need a cutting-edge feature |
LTS version numbers are even (18, 20, 22). Current versions are odd (19, 21, 23). When in doubt, even = safe.
Your first Node.js script
Create a new file called hello.js:
mkdir node-practice
cd node-practice
touch hello.js
Open hello.js in any text editor and add:
console.log("Hello from Node.js!");
console.log("Node version:", process.version);
Run it:
node hello.js
Output:
Hello from Node.js!
Node version: v22.16.0
That's it. node runs the file, console.log prints to your terminal. Everything JavaScript you know from the browser works the same way here.
npm basics
npm is the package manager that ships with Node.js. A package is a reusable library someone else wrote that you can add to your project in seconds.
Start a new project โ npm init
Every Node.js project needs a package.json file that describes it. Create one:
npm init -y
The -y flag accepts all defaults. This creates package.json in your current folder. Open it and you'll see:
{
"name": "node-practice",
"version": "1.0.0",
"description": "",
"main": "hello.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
What package.json does
package.json is your project's manifest. It records:
- The project name and version
- Which packages your project depends on (and which version)
- Scripts you can run with
npm run
When someone else clones your project, they run npm install and npm reads package.json to install exactly the right packages.
Install a package โ npm install
npm install chalk
This does three things:
- Downloads the
chalkpackage into a folder callednode_modules/ - Adds
chalkto thedependenciessection of yourpackage.json - Updates
package-lock.json(an exact lock of every package version used)
Install from an existing package.json
If you clone a project that already has a package.json, run:
npm install
No package name needed. npm reads package.json and installs everything listed.
node_modules and .gitignore
node_modules can contain thousands of files and hundreds of megabytes. You never commit it to Git. Instead, add it to .gitignore:
touch .gitignore
Add this line to the file:
node_modules/
Anyone who clones your repo runs npm install to rebuild it. See the Git guide for more on .gitignore.
dependencies vs devDependencies
Not all packages are needed in production. A testing library, for example, is only needed while you're developing.
| Type | Where it lives | Example packages | Install command |
|---|---|---|---|
dependencies | Needed to run the app | express, chalk, next | npm install packagename |
devDependencies | Only needed during development | eslint, typescript, jest | npm install --save-dev packagename |
npm install express # adds to dependencies
npm install --save-dev eslint # adds to devDependencies
When deploying to production, some platforms skip installing devDependencies to save time and space.
npm scripts โ run, build, start
The scripts section of package.json is where you define shortcuts. When you clone a Next.js project you'll see:
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start"
}
Run them with npm run:
npm run dev # starts the development server
npm run build # compiles for production
npm start # starts the production server (shortcut, no "run" needed)
npm start and npm test are special โ they don't need the run keyword. Everything else does.
Real example: install chalk and write colourful output
chalk is a package that adds colour to terminal output. Let's install and use it.
Step 1: Make sure package.json exists
npm init -y
Step 2: Install chalk
npm install chalk
Step 3: Create colorful.js
chalk v5+ uses ES modules. Add "type": "module" to your package.json first:
# Open package.json and add this line inside the top-level object:
# "type": "module",
Your package.json should now include:
{
"name": "node-practice",
"version": "1.0.0",
"type": "module",
...
}
Now create colorful.js:
import chalk from 'chalk';
console.log(chalk.green('Success! Node.js is working.'));
console.log(chalk.red('This is an error message.'));
console.log(chalk.blue.bold('Bold blue text'));
console.log(chalk.yellow(`Your Node version: ${process.version}`));
Step 4: Run it
node colorful.js
You'll see coloured output in your terminal. This is exactly how CLI tools format their messages โ same technique, same package.
npx โ run without installing
npx is a tool that ships with npm. It runs a package without permanently installing it.
npx create-next-app@latest my-app
Instead of installing create-next-app globally first, npx downloads it, runs it once, and discards it. This is the standard way to run project scaffolding tools.
| Command | What it does |
|---|---|
npm install packagename | Installs permanently into node_modules |
npm install -g packagename | Installs globally (available everywhere on your machine) |
npx packagename | Downloads and runs once, doesn't keep it |
Use npx for one-off tools like project generators. Use npm install for packages your code imports.
Switching Node versions with nvm
If you work on multiple projects, you'll eventually hit a version conflict. nvm makes switching easy:
nvm install 20 # install Node 20
nvm install 22 # install Node 22
nvm use 20 # switch to Node 20
nvm use 22 # switch to Node 22
nvm list # see all installed versions
nvm alias default 22 # make Node 22 the default for new terminals
You can also create a .nvmrc file in your project folder:
echo "22" > .nvmrc
Then anyone working on the project (including you, in a new terminal) can run nvm use and it auto-selects the right version.
Hands-on exercise: build a small CLI tool
Put it all together. Build a script that reads your Node version, lists today's date, and prints a greeting.
# Inside your node-practice folder:
touch info.js
Add to info.js:
import chalk from 'chalk';
import { execSync } from 'child_process';
const nodeVersion = process.version;
const npmVersion = execSync('npm --version').toString().trim();
const today = new Date().toLocaleDateString('en-US', {
weekday: 'long',
year: 'numeric',
month: 'long',
day: 'numeric'
});
console.log(chalk.cyan.bold('=== Dev Environment Info ==='));
console.log(chalk.green(`Node.js: ${nodeVersion}`));
console.log(chalk.green(`npm: v${npmVersion}`));
console.log(chalk.yellow(`Date: ${today}`));
console.log(chalk.cyan.bold('============================'));
Run it:
node info.js
You just wrote a real CLI tool โ reads system info, uses an external package, formats the output. That's what Node.js development looks like.
Quick reference
# Installation
nvm install --lts # install LTS version of Node
nvm use --lts # switch to LTS
node --version # check Node version
npm --version # check npm version
# Project setup
npm init -y # create package.json
npm install packagename # install a package
npm install # install all packages from package.json
npm install --save-dev pkg # install as dev dependency
npm uninstall packagename # remove a package
# Running things
node script.js # run a JavaScript file
npm run dev # run the "dev" script
npm run build # run the "build" script
npm start # run the "start" script
npx create-next-app@latest # run a package without installing
What to learn next
Node.js is the engine under most of what you'll build. Now that it's installed:
- Build a web app โ Next.js beginner guide uses Node.js under the hood.
npm run devstarts it. - Version control your code โ Git beginner guide. Every Node project should be in a Git repo.
- Learn Python too โ Python beginner guide. Python and Node.js are the two runtimes most AI tools use.
- Build with AI editors โ Cursor beginner guide. Cursor runs on Node.js and uses npm under the hood.