Run JavaScript on your computer with Node.js and manage packages, scripts and secrets with npm.
Why it matters
JavaScript started in the browser, but Node.js lets you run it anywhere: on your laptop, on a server, or as a serverless function. It is one of the most common back-end runtimes, so a front-end developer who knows JavaScript can write an API without learning a new language. npm (the Node package manager) comes with Node and gives you access to millions of open-source packages, including the Express framework you will use in the next lesson.
What Node is (and is not)
Node is a JavaScript runtime: the V8 engine from Chrome plus libraries for files, networking and processes. Compared with the browser:
- There is no
documentorwindow. There isprocess(arguments, environment variables, exit codes),fs(files),http(servers) and more. - Node runs on one main thread with an event loop. While it waits for a database or a file, it handles other requests. That is why most Node APIs are asynchronous (callbacks, promises,
async/await). Code that blocks the thread, such as a huge synchronous loop, blocks every request.
Installing Node
Install an LTS (long-term support) release, which is the version most companies run. Use the installer from nodejs.org, or a version manager such as nvm (macOS/Linux) or nvm-windows/fnm (Windows) so you can switch versions per project:
node --version # e.g. v22.x
npm --version
Running a script
Create hello.js:
const name = process.argv[2] ?? "world";
console.log(`Hello, ${name}! Node ${process.version} on ${process.platform}`);
Run it:
node hello.js Ada
# Hello, Ada! Node v22.11.0 on darwin
process.argv holds the command-line arguments: the Node binary, the script path, then yours.
A project with package.json
Every Node project has a package.json describing it. Create a folder and initialise it:
mkdir hello-api && cd hello-api
npm init -y
The generated file is plain JSON. Two fields are worth adding straight away:
{
"name": "hello-api",
"version": "1.0.0",
"type": "module",
"scripts": {
"start": "node index.js",
"dev": "node --watch index.js"
}
}
"type": "module"lets you useimport/export(ES modules) instead ofrequire.scriptsare shortcuts:npm startrunsnode index.js,npm run devrestarts on every save.
Installing a package
npm install express
This does three things:
- Downloads the package and everything it depends on into
node_modules/. - Adds
"express": "^5.x.x"underdependenciesinpackage.json. - Writes
package-lock.json, which records the exact version of every package installed.
Tools you only need while developing (test runners, linters) go in devDependencies: npm install --save-dev vitest.
The ^ in ^5.1.0 means "any 5.x version from 5.1.0 up". That follows semantic versioning: MAJOR.MINOR.PATCH, where a major bump may break your code. The lock file is what keeps every machine on the same versions, so commit package-lock.json and use npm ci in CI and deployments; it installs exactly what the lock file says.
Environment variables and secrets
Configuration that differs between machines, such as a port, a database URL or an API key, goes in environment variables, not in code:
const port = Number(process.env.PORT ?? 3000);
Locally, many projects keep these in a .env file. Newer Node versions can load one with node --env-file=.env index.js. The .env file holds secrets, so it must never be committed.
What to commit
Create a .gitignore before your first commit:
node_modules/
.env
node_modules/can be rebuilt from the lock file and can hold tens of thousands of files..envholds secrets. If a secret is ever pushed, deleting the file later is not enough; it is in the history. Rotate (replace) the secret immediately.
A common pattern is to commit a .env.example with the variable names and fake values, so teammates know what to set.
Choosing packages carefully
Every dependency is code you run with full access to your machine and your server. Before you install one, check that it is maintained, widely used, and spelled correctly (attackers publish "typosquat" packages with near-identical names). npm audit reports known vulnerabilities in what you have installed.
Common mistakes
- Committing
node_modules/or.env. - Not committing
package-lock.json, so teammates and servers get different versions. - Using
npm installin CI instead ofnpm ci. - Installing globally (
npm install -g) for project tools. Usenpx <tool>or a local devDependency. - Blocking the event loop with heavy synchronous work in a request handler.
Quick recap
- Node runs JavaScript outside the browser on a single-threaded event loop.
package.jsondescribes the project and its scripts;package-lock.jsonpins exact versions. Commit both.npm install <pkg>adds a dependency,npm cireproduces the lock file exactly.- Configuration and secrets live in environment variables;
.envandnode_modules/go in.gitignore.
Try it: the Do tab walks you through installing Node, creating a project, adding a package and running your first script.