1. Introduction
Before you can build anything with Node.js, you need a properly configured environment. This tutorial walks through installing Node.js, choosing the right package manager, and setting up a clean, production-ready project structure â including package.json, dependencies, linting, formatting, and TypeScript. đ ī¸
Information
2. Preparing Your Environment
System Requirements
- Operating System: Windows 10+, macOS 11+, or a modern Linux distribution.
- Disk space: At least 200MB free for Node.js itself; project dependencies add more.
- RAM: 4GB minimum recommended for comfortable development.
- Terminal access: Command Prompt, PowerShell, Terminal, or an integrated terminal in your editor.
Installing Node.js
There are several ways to install Node.js, and the right one depends on how much control you want over versions later on.
terminal
# Using Homebrew
brew install nodeDownload the official installer from nodejs.org, or use a package manager like winget:
terminal
winget install OpenJS.NodeJS.LTSterminal
# Debian / Ubuntu
sudo apt update
sudo apt install nodejs npmTip
Node.js Release Types
Node.js publishes two parallel release lines simultaneously, each serving a different purpose.
| Release Type | Purpose | Stability |
|---|---|---|
| Current | Latest features, released every 6 months | Newer, less battle-tested |
| LTS (Long-Term Support) | Stable releases recommended for production | Highly stable, supported for years |
LTS vs Current
Every even-numbered major Node.js version (e.g. 18, 20, 22) eventually becomes an LTS release, receiving bug fixes and security patches for 30 months. Odd-numbered versions are short-lived and never promoted to LTS.
Best Practice
Node Version Manager (nvm)
nvm lets you install and switch between multiple Node.js versions on the same machine â essential when different projects require different versions.
terminal
# Install nvm (macOS/Linux)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
# Install and use the latest LTS version
nvm install --lts
nvm use --lts
# Install a specific version
nvm install 20.11.0
# Switch between installed versions
nvm use 18Hint
Verifying Installation
Once installed, confirm that both Node.js and npm are available on your PATH:
terminal
node --version
# v20.11.0
npm --version
# 10.2.43. Package Managers
Understanding npm
npm (Node Package Manager) is installed automatically with Node.js. It manages your project's dependencies, exposes scripts for common tasks, and connects you to the public npm registry â home to over a million packages. đĻ
Understanding Package Managers
A package manager resolves, downloads, and organizes your project's dependencies (and their own sub-dependencies) so you don't have to manage them by hand. Several alternatives to npm have emerged, each with different trade-offs around speed, disk usage, and strictness.
- Ships by default with Node.js
- Largest install base, most documentation
- Lockfile: package-lock.json
- Created by Facebook to improve install speed and determinism
- Offers Plug'n'Play mode to skip node_modules entirely
- Lockfile: yarn.lock
- Uses a content-addressable store to save disk space across projects
- Strict by default â prevents accessing undeclared dependencies
- Lockfile: pnpm-lock.yaml
- All-in-one runtime, bundler, and package manager
- Extremely fast installs due to a native implementation
- Lockfile: bun.lockb
npm
terminal
npm install express
npm install --save-dev nodemon
npm run startYarn
terminal
yarn add express
yarn add --dev nodemon
yarn startpnpm
terminal
pnpm add express
pnpm add -D nodemon
pnpm run startBun
terminal
bun add express
bun add -d nodemon
bun run startReference
4. Creating Your First Node.js Project
Project Structure
A clean, conventional project structure makes a codebase easier to navigate as it grows. A typical setup looks like this:
Understanding package.json
package.json is the manifest file at the root of every Node.js project. It records the project's name, version, dependencies, scripts, and metadata.
package.json
{
"name": "my-app",
"version": "1.0.0",
"description": "A sample Node.js project",
"main": "src/index.js",
"type": "module",
"scripts": {
"start": "node src/index.js",
"dev": "nodemon src/index.js",
"test": "vitest"
},
"dependencies": {
"express": "^4.19.2"
},
"devDependencies": {
"nodemon": "^3.1.0"
}
}| Field | Purpose |
|---|---|
| name / version | Identifies the package, especially if published |
| main | The entry point when the package is required elsewhere |
| type | Determines whether files use ES Modules or CommonJS |
| scripts | Named shortcuts for common commands (e.g. npm run dev) |
| dependencies / devDependencies | Packages required at runtime vs. only during development |
Understanding package-lock.json
While package.json declares version ranges (like ^4.19.2), package-lock.json records the exact version of every installed package â including sub-dependencies â ensuring everyone on a team installs identical dependency trees.
Warning
Initializing a Project
terminal
mkdir my-app && cd my-app
npm init -yThe -y flag accepts all default values. Omit it if you'd like npm to prompt you interactively for each field.
Installing Dependencies
terminal
npm install express dotenvThis adds both packages under dependencies in package.json and downloads them into node_modules.
Installing Development Dependencies
Development dependencies are tools needed only while building the project â like test runners, linters, and formatters â not when it runs in production.
terminal
npm install --save-dev eslint prettier nodemonRunning Scripts
Scripts defined in package.json can be run with npm run <script-name>. A few conventional names â like start and test â can be run without the run keyword.
terminal
npm start
npm test
npm run dev5. Writing and Running Code
Creating Your First Program
src/index.js
console.log('Hello, Node.js! đ');Running Node.js Applications
terminal
node src/index.jsTip
The Node.js REPL
Typing node with no arguments opens the REPL (Read-Eval-Print Loop) â an interactive shell for experimenting with JavaScript directly in your terminal.
terminal
$ node
> 2 + 2
4
> const greet = (name) => `Hi, ${name}`;
undefined
> greet('Node')
'Hi, Node'
> .exitEnvironment Variables
Environment variables let you keep configuration and secrets (like API keys) outside your codebase. The dotenv package loads variables from a .env file into process.env.
.env
PORT=3000
DATABASE_URL=postgres://localhost:5432/mydbsrc/index.js
import 'dotenv/config';
console.log(process.env.PORT); // 3000Danger
6. Module Systems and Tooling
ES Modules Setup
ES Modules (import / export) are the modern, standardized module format shared with browser JavaScript. Enable them by setting "type": "module" in package.json.
package.json
{
"type": "module"
}src/math.js
export function add(a, b) {
return a + b;
}src/index.js
import { add } from './math.js';
console.log(add(2, 3)); // 5CommonJS Setup
CommonJS (require / module.exports) is Node.js's original module system and remains the default when "type" is omitted or set to "commonjs".
src/math.js
function add(a, b) {
return a + b;
}
module.exports = { add };src/index.js
const { add } = require('./math.js');
console.log(add(2, 3)); // 5Note
ESLint Setup
ESLint analyzes your code for potential errors and enforces consistent style rules.
terminal
npm install --save-dev eslint
npx eslint --initeslint.config.json (simplified)
{
"env": { "node": true, "es2022": true },
"extends": "eslint:recommended",
"rules": {
"no-unused-vars": "warn",
"no-console": "off"
}
}Prettier Setup
Prettier automatically formats your code for consistent style, complementing ESLint's focus on correctness.
terminal
npm install --save-dev prettier.prettierrc
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5"
}TypeScript Setup
TypeScript adds static typing to JavaScript, catching many errors before code ever runs.
terminal
npm install --save-dev typescript @types/node
npx tsc --inittsconfig.json (simplified)
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"outDir": "dist",
"strict": true,
"esModuleInterop": true
},
"include": ["src"]
}7. Ongoing Maintenance
Development Workflow
A typical daily workflow combines several of the tools covered above:
Updating Dependencies
terminal
# See which packages are outdated
npm outdated
# Update within the version ranges in package.json
npm update
# Check for known vulnerabilities
npm audit
npm audit fixBest Practice
Common Installation Issues
| Issue | Likely Cause |
|---|---|
| command not found: node | Node.js isn't installed, or isn't on your PATH |
| EACCES permission errors | Global npm packages installed without proper permissions |
| EADDRINUSE | Another process is already using the port your server needs |
| Version mismatch between machines | Different Node.js or lockfile versions across environments |
Troubleshooting
- Confirm your Node.js version with node --version and compare against your project's requirements.
- Delete node_modules and your lockfile, then reinstall dependencies from scratch.
- Check for conflicting global installs versus a version manager like nvm.
- Search the exact error message â most Node.js errors are well-documented online.
terminal
rm -rf node_modules package-lock.json
npm install8. Summary
Best Practices
- Use a version manager like nvm instead of a single global Node.js install.
- Prefer LTS releases for production applications.
- Always commit your lockfile to version control.
- Separate dependencies from devDependencies correctly.
- Set up ESLint and Prettier early, before a codebase grows large.
- Keep secrets in .env files, never in source code.
Summary
A solid Node.js setup starts with the right installation strategy, a well-chosen package manager, and a clean project structure governed by package.json. Layering in linting, formatting, and optionally TypeScript establishes a foundation that scales comfortably as your project grows. â