React SME Cookbook
All FAQs

Search Documentation

Search across all documentation pages

linuxnodenpmenvironmentbuild

Node.js Developer Commands

Terminal commands every React, TypeScript, and Node.js developer needs — package management, environment setup, build tooling, and debugging.

Recipe

Quick-reference recipe card — copy-paste ready.

# Package management
npm install                    # install all dependencies
npm install zod                # add a dependency
npm install -D vitest          # add a dev dependency
npm run dev                    # start dev server
npm run build                  # production build
 
# Node version management
nvm install 22                 # install Node 22
nvm use 22                     # switch to Node 22
node -v                        # check Node version
 
# Environment
export PORT=3001               # set env var for this session
cat .env.local                 # view env file
echo $NODE_ENV                 # check current environment
 
# Quick checks
npx tsc --noEmit               # type-check without building
npx next lint                  # run linter
npx vitest run                 # run tests once

When to reach for this: Daily development workflow — installing packages, managing Node versions, running builds, checking types, and debugging issues.

Working Example

# Setting up a new Next.js project from scratch
npx create-next-app@latest my-app --typescript --tailwind --app --src-dir
cd my-app
npm install zustand zod react-hook-form @hookform/resolvers
npm install -D vitest @testing-library/react
npm run dev
# App running at http://localhost:3000

What this demonstrates:

  • npx runs a package without installing it globally
  • Separate install and install -D for runtime vs dev dependencies
  • Next.js flags for TypeScript, Tailwind, App Router, and src directory

Deep Dive

Package Management (npm)

# Install
npm install                        # install from package.json
npm install --legacy-peer-deps     # resolve peer dependency conflicts
npm ci                             # clean install (uses lockfile exactly, faster in CI)
 
# Add/remove packages
npm install lucide-react           # add dependency
npm install -D prettier            # add dev dependency
npm uninstall lodash               # remove a package
 
# Inspect
npm list --depth=0                 # top-level installed packages
npm outdated                       # check for updates
npm audit                          # security vulnerabilities
npm audit fix                      # auto-fix vulnerabilities
 
# Scripts
npm run dev
npm run build
npm run start
npm test
npm run lint
 
# View a package before installing
npm info zustand                   # package details
npm info zustand versions          # all published versions
 
# Link a local package for development
cd ../my-library && npm link
cd ../my-app && npm link my-library

Package Management (pnpm — faster alternative)

# Install pnpm
npm install -g pnpm
 
# Equivalent commands
pnpm install                       # install all
pnpm add zod                       # add dependency
pnpm add -D vitest                 # add dev dependency
pnpm remove lodash                 # remove
pnpm dev                           # run script (no "run" needed)
pnpm build
 
# Workspace commands (monorepo)
pnpm -r build                     # run build in all packages
pnpm --filter @app/web dev        # run dev in specific package

Node Version Management (nvm)

# Install nvm (macOS/Linux)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
 
# Install and use a Node version
nvm install 22
nvm install 20
nvm use 22
nvm alias default 22              # set default for new terminals
 
# Use version from .nvmrc file
echo "22" > .nvmrc
nvm use                           # reads .nvmrc
 
# List installed versions
nvm ls
 
# List available versions
nvm ls-remote | grep "Latest LTS"

Environment Variables

# Set for current command only
PORT=3001 npm run dev
NODE_ENV=production npm run build
 
# Set for current session
export DATABASE_URL="postgresql://localhost:5432/mydb"
 
# View current env vars
env | grep NODE
printenv PORT
 
# .env file structure (Next.js)
# .env                — all environments (committed)
# .env.local          — local overrides (gitignored)
# .env.development    — dev only
# .env.production     — prod only
# .env.test           — test only
 
# Access in Next.js
# Server: process.env.DATABASE_URL
# Client: process.env.NEXT_PUBLIC_API_URL (must have NEXT_PUBLIC_ prefix)
 
# Check what env vars your app sees
node -e "console.log(process.env.NODE_ENV)"

TypeScript Commands

# Type-check without building
npx tsc --noEmit
 
# Type-check in watch mode
npx tsc --noEmit --watch
 
# Generate declaration files
npx tsc --declaration --emitDeclarationOnly
 
# Check tsconfig
npx tsc --showConfig
 
# Find specific type errors
npx tsc --noEmit 2>&1 | grep "error TS"
 
# Count type errors
npx tsc --noEmit 2>&1 | grep "error TS" | wc -l
 
# Check a specific file
npx tsc --noEmit src/lib/utils.ts

Build & Bundle Analysis

# Next.js production build
npm run build
# Shows route sizes, static vs dynamic, bundle breakdown
 
# Analyze bundle size
npm install -D @next/bundle-analyzer
ANALYZE=true npm run build
 
# Check package size before installing
npx package-size zustand zod lodash
# or use https://bundlephobia.com
 
# Measure build time
time npm run build
 
# Check what's in node_modules
du -sh node_modules                    # total size
du -sh node_modules/* | sort -rh | head -20  # largest packages
npx depcheck                           # find unused dependencies

Debugging

# Node.js debugger
node --inspect server.js               # attach Chrome DevTools
node --inspect-brk server.js           # break on first line
 
# Debug a Next.js app
NODE_OPTIONS='--inspect' npm run dev
 
# Memory profiling
node --max-old-space-size=4096 server.js   # increase heap to 4GB
node --heap-prof server.js                  # generate heap profile
 
# Quick REPL for testing
node
> const { z } = require('zod')
> z.string().email().safeParse('test@example.com')
 
# Execute a one-liner
node -e "console.log(Date.now())"
node -e "console.log(require('./package.json').version)"
node -p "require('os').cpus().length"      # -p prints the result
 
# Check module resolution
node -e "console.log(require.resolve('react'))"

Network & API Testing

# Test an API endpoint
curl http://localhost:3000/api/health
curl -s http://localhost:3000/api/users | jq .
 
# POST with JSON body
curl -X POST http://localhost:3000/api/users \
  -H "Content-Type: application/json" \
  -d '{"name": "Alice", "email": "alice@example.com"}'
 
# POST with auth header
curl -H "Authorization: Bearer $TOKEN" \
  http://localhost:3000/api/protected
 
# Time a request
curl -o /dev/null -s -w "Total: %{time_total}s\nTTFB: %{time_starttransfer}s\n" \
  http://localhost:3000
 
# Watch a port
lsof -i :3000                  # what's using port 3000
kill -9 $(lsof -ti :3000)      # kill whatever's on port 3000

Gotchas

Things that will bite you. Each gotcha includes what goes wrong, why it happens, and the fix.

  • Port already in useEADDRINUSE: address already in use :::3000. Fix: lsof -ti :3000 | xargs kill -9 or use a different port: PORT=3001 npm run dev.

  • Node version mismatch — Build works locally but fails in CI or for teammates. Fix: Add a .nvmrc file and engines field in package.json: "engines": { "node": ">=22" }.

  • npm install vs npm cinpm install can update the lockfile, causing unexpected changes. Fix: Use npm ci in CI pipelines — it uses the lockfile exactly and is faster.

  • Missing NEXT_PUBLIC_ prefix — Client-side code gets undefined for env vars. Fix: Env vars accessed in the browser must start with NEXT_PUBLIC_. Server-only vars don't need the prefix.

  • Global package conflicts — Global installs of next, typescript, etc. conflict with project versions. Fix: Use npx instead of global installs. Remove globals: npm uninstall -g next.

  • Heap out of memory — Large builds crash with FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed. Fix: NODE_OPTIONS="--max-old-space-size=8192" npm run build.

Alternatives

Other ways to solve the same problem — and when each is the better choice.

AlternativeUse WhenDon't Use When
pnpmFaster installs, monorepos, strict dependency resolutionSimple projects where npm is sufficient
yarnExisting projects already using yarnNew projects (pnpm or npm are preferred)
bunMaximum speed, built-in test runnerProduction stability is critical (newer runtime)
fnmFaster Node version switching than nvmAlready using nvm and it works fine
voltaAutomatic Node version switching per projectSimple projects with one Node version

FAQs

What is the difference between npm install and npm ci?
  • npm install reads package.json and may update package-lock.json
  • npm ci uses the lockfile exactly, deletes node_modules first, and is faster
  • Use npm ci in CI pipelines for reproducible builds
When should I use npx instead of installing a package globally?
  • Use npx for one-off commands like npx create-next-app or npx tsc --noEmit
  • Global installs can conflict with project-local versions
  • npx always uses the project-local version if available
How do I switch Node versions for different projects?
echo "22" > .nvmrc
nvm use
  • nvm use reads .nvmrc and switches to that version
  • Set a default with nvm alias default 22
Why does my client-side code get undefined for an environment variable?
  • In Next.js, client-side env vars must be prefixed with NEXT_PUBLIC_
  • Server-only vars (e.g., DATABASE_URL) are not exposed to the browser
  • This is a security feature to prevent leaking secrets
How do I kill a process that is using port 3000?
lsof -ti :3000 | xargs kill -9
  • Or use a different port: PORT=3001 npm run dev
Gotcha: My build works locally but fails in CI with a different Node version. How do I fix this?
  • Add a .nvmrc file with the Node version (e.g., 22)
  • Add an engines field in package.json: "engines": { "node": ">=22" }
  • Ensure your CI config installs the matching version
How do I analyze my Next.js bundle size?
npm install -D @next/bundle-analyzer
ANALYZE=true npm run build
  • Opens an interactive treemap showing what is in each bundle
  • Use npx depcheck to find unused dependencies
How do I debug a Next.js app with Chrome DevTools?
NODE_OPTIONS='--inspect' npm run dev
  • Open chrome://inspect in Chrome and click "inspect" on your Node process
  • Use --inspect-brk to break on the first line
Gotcha: My build crashes with "heap out of memory." What should I do?
NODE_OPTIONS="--max-old-space-size=8192" npm run build
  • Increases the V8 heap limit to 8GB
  • If this keeps happening, investigate for memory leaks or large dependencies
How do I type-check a TypeScript project without producing build output?
npx tsc --noEmit
  • --noEmit runs the type checker without generating .js files
  • Add --watch for continuous checking during development
How do I find and count all TypeScript errors in the project?
npx tsc --noEmit 2>&1 | grep "error TS" | wc -l
  • Pipe through grep "error TS" to isolate type errors from other output
What is the difference between pnpm and npm?
  • pnpm uses a content-addressable store, so shared dependencies are not duplicated on disk
  • pnpm has stricter dependency resolution (prevents phantom dependencies)
  • pnpm is faster for installs, especially in monorepos
  • npm is pre-installed with Node and has broader ecosystem familiarity