NPM

The world's largest software registry. Install anything in seconds.

What Is NPM

Three things: a registry, a CLI tool, and a website.

// NPM = Node Package Manager
// It's actually 3 things:

// 1. Registry — npmjs.com
//    2+ million packages of reusable code
//    Anyone can publish, anyone can install

// 2. CLI tool — the 'npm' command
//    Installed with Node.js automatically
//    Manages your project's dependencies

// 3. Website — npmjs.com
//    Browse packages, read docs, check downloads

// The ecosystem:
// npm    — the original (comes with Node.js)
// pnpm   — faster, saves disk space (uses symlinks)
// yarn   — Facebook's alternative (also fast)
// bun    — ultra-fast, built into Bun runtime

// All use the same registry (npmjs.com)
// All read the same package.json format
// Differences are speed and disk usage

// Check versions:
// $ npm --version
// $ pnpm --version

package.json

Your project's manifest — name, version, dependencies, and scripts.

// Create a new project:
// $ npm init -y    (generates package.json with defaults)
// $ pnpm init      (same thing with pnpm)

// package.json:
{
  "name": "my-app",
  "version": "1.0.0",
  "description": "A cool JavaScript app",
  "main": "index.js",
  "type": "module",
  "scripts": {
    "start": "node index.js",
    "dev": "node --watch index.js",
    "test": "vitest",
    "build": "vite build"
  },
  "dependencies": {
    "express": "^4.18.2",
    "zod": "^3.22.0"
  },
  "devDependencies": {
    "vitest": "^1.0.0",
    "typescript": "^5.3.0"
  }
}

// Key fields:
// "name"             — package name (lowercase, no spaces)
// "version"          — semver: major.minor.patch
// "type": "module"   — enables ES modules (import/export)
// "scripts"          — custom commands (npm run <name>)
// "dependencies"     — packages your code needs to run
// "devDependencies"  — packages needed only for development

Installing Packages

Add libraries to your project in one command.

// Install a dependency:
$ npm install lodash
$ pnpm add lodash

// What happens:
// 1. Downloads lodash from registry
// 2. Adds to node_modules/ folder
// 3. Adds to "dependencies" in package.json
// 4. Updates lock file (package-lock.json / pnpm-lock.yaml)

// Install a dev dependency (only for development):
$ npm install -D vitest
$ pnpm add -D vitest

// Install specific version:
$ npm install lodash@4.17.21

// Install all dependencies from package.json:
$ npm install       // reads package.json, installs everything
$ pnpm install      // same

// Uninstall:
$ npm uninstall lodash
$ pnpm remove lodash

npm install downloads packages and records them in package.json. The lock file ensures everyone gets exact same versions.

1 / 2

Scripts

Custom commands defined in package.json.

// package.json scripts:
"scripts": {
  "dev": "next dev",
  "build": "next build",
  "start": "next start",
  "lint": "eslint .",
  "test": "vitest",
  "test:watch": "vitest --watch",
  "format": "prettier --write .",
  "typecheck": "tsc --noEmit",
  "db:migrate": "prisma migrate dev",
  "prepare": "husky install"
}

// Run them:
// $ npm run dev        → runs "next dev"
// $ pnpm dev           → pnpm allows dropping "run"
// $ npm test           → special: doesn't need "run"
// $ npm start          → special: doesn't need "run"

// Chaining scripts:
"scripts": {
  "check": "npm run lint && npm run typecheck && npm run test",
  "prebuild": "npm run check",
  "build": "next build"
}
// "pre" scripts run automatically before the named script
// "post" scripts run after

// Pass arguments:
// $ npm run dev -- --port 4000
// The -- passes --port 4000 to the underlying command

// Environment variables in scripts:
"scripts": {
  "dev": "NODE_ENV=development node server.js",
  "prod": "NODE_ENV=production node server.js"
}

// npx — run a package without installing:
// $ npx create-next-app my-app
// $ npx vitest
// Downloads temporarily, runs, cleans up

Publishing

Share your code with the world on npm.

// Publishing your own package:

// 1. Create account: npmjs.com/signup
// 2. Login: npm login

// 3. Set up package.json:
{
  "name": "my-cool-utility",
  "version": "1.0.0",
  "description": "A useful utility function",
  "main": "dist/index.js",
  "module": "dist/index.mjs",
  "types": "dist/index.d.ts",
  "files": ["dist"],
  "keywords": ["utility", "helper"],
  "license": "MIT",
  "repository": {
    "type": "git",
    "url": "https://github.com/you/my-cool-utility"
  }
}

// 4. Build your package (if using TypeScript/bundler)
// 5. Publish:
// $ npm publish

// Scoped packages (@username/package):
// $ npm publish --access public

// Update version:
// $ npm version patch   → 1.0.0 → 1.0.1
// $ npm version minor   → 1.0.1 → 1.1.0
// $ npm version major   → 1.1.0 → 2.0.0
// Then: npm publish

// .npmignore (files to exclude from package):
// node_modules/
// src/          ← only publish dist/
// tests/
// .env

// Before publishing, test locally:
// $ npm pack   → creates .tgz archive
// $ npm install ./my-cool-utility-1.0.0.tgz

FAQ

Common questions about NPM.