Blog

Blog · Complete Guides

The Complete Guide to npm in 2026

A complete guide to npm — package.json, installing packages, semver ranges, scripts, npx, lockfiles, npm ci vs install, workspaces, publishing and the npm v12 security changes — with commands throughout.

XCODX Team · 5 min read

npm is the default package manager for Node.js — how you install, manage and share JavaScript packages. This complete guide covers package.json, installing dependencies, semantic versioning, scripts, lockfiles, workspaces and publishing, plus the important npm v12 security changes and how npm compares to pnpm and Bun in 2026.

What npm is

npm is three things: a command-line tool (installed with Node.js), a registry of over two million public packages, and the package.json format that describes a project. You use it to add libraries, run scripts, and publish your own packages.

package.json

Every Node project has a package.json — its manifest. It lists metadata, dependencies and scripts. Create one with npm init (add -y to accept defaults).

{
  "name": "my-app",
  "version": "1.0.0",
  "type": "module",
  "scripts": { "dev": "vite", "build": "vite build", "test": "vitest" },
  "dependencies": { "react": "^19.0.0" },
  "devDependencies": { "vite": "^8.0.0" }
}

Installing packages

Add packages to your project with npm install. Runtime dependencies go in dependencies; build/test-only tools go in devDependencies with -D.

npm install                 # install everything in package.json
npm install react            # add a runtime dependency
npm install -D vitest        # add a dev dependency
npm install [email protected]     # a specific version
npm uninstall lodash         # remove a package

Semantic versioning (semver)

Versions are MAJOR.MINOR.PATCH. The range prefix in package.json controls which updates you accept: ^ allows minor and patch updates, ~ allows only patch, and no prefix pins an exact version.

"react": "^19.2.0"   // >=19.2.0 <20.0.0  (minor + patch)
"react": "~19.2.0"   // >=19.2.0 <19.3.0  (patch only)
"react": "19.2.0"    // exactly 19.2.0
  • MAJOR — breaking changes.
  • MINOR — new features, backward-compatible.
  • PATCH — bug fixes, backward-compatible.

Scripts

The scripts field defines commands you run with npm run <name>. start and test have shortcuts (npm start, npm test). Scripts can chain and reference locally-installed binaries directly.

npm run dev        # runs the "dev" script
npm start          # shortcut for "start"
npm test           # shortcut for "test"

npx

npx runs a package’s command-line binary without installing it globally — great for one-off tools and scaffolding. It downloads, runs, and cleans up.

npx create-vite@latest my-app   # scaffold a project
npx eslint .                    # run a tool without a global install

Lockfiles: npm ci vs npm install

package-lock.json records the exact resolved dependency tree so installs are reproducible — commit it. Use npm install in development (it resolves ranges and may update the lockfile) and npm ci in CI/production (a clean, lockfile-exact install that fails if package.json and the lockfile disagree).

npm install     # dev: resolves ranges, updates lockfile
npm ci          # CI: clean, exact, reproducible install

Updating and auditing

Keep dependencies current and check for known vulnerabilities. npm outdated shows what’s behind; npm audit reports security issues.

npm outdated        # what has newer versions
npm update          # update within your semver ranges
npm audit           # report known vulnerabilities
npm audit fix       # auto-fix where safe

Workspaces (monorepos)

npm workspaces let one repository hold multiple packages that reference each other — the built-in way to manage a monorepo. Declare the folders in the root package.json.

{
  "name": "monorepo",
  "workspaces": ["packages/*", "apps/*"]
}
npm install                              # installs all workspaces
npm run build --workspace=apps/web       # run a script in one workspace

Publishing a package

To share a package, set its name, version and exports/files, log in, and publish. Scoped packages need --access public to be public.

npm login
npm version patch          # bump the version (1.0.0 -> 1.0.1)
npm publish --access public

Security and supply chain

Packages are code you run, so treat them with care — especially in 2026:

  • npm v12 disables dependency install scripts by default; enable them only for packages you trust.
  • Beware hallucinated packages ("slopsquatting"): AI assistants sometimes suggest package names that don’t exist, and attackers pre-register them. Verify every new dependency exists and is the legitimate package before installing.
  • Commit your lockfile, run npm audit in CI, and enable 2FA for publishing.

npm vs pnpm vs Bun

  • npm — the default; ships with Node, universal compatibility, and (v12) hardened supply-chain defaults.
  • pnpm — a content-addressable store for the best disk efficiency and strict, correct dependency resolution; the strongest choice for large monorepos.
  • Bun — the fastest installs, part of an all-in-one runtime and toolkit; very fast but with near-complete (not total) Node compatibility.

Frequently asked questions

What is the difference between dependencies and devDependencies?
dependencies are packages your application needs at runtime — frameworks, libraries your code imports. devDependencies are tools needed only to build, test or develop the project — bundlers, test runners, linters, type definitions. Install dev tools with npm install -D. When you deploy with --omit=dev (or in production installs), devDependencies are skipped, keeping the runtime lean.
What does the ^ mean in package.json versions?
The caret (^) allows updates that don’t change the leftmost non-zero version number — for ^19.2.0 that means any 19.x.x at or above 19.2.0 but below 20.0.0 (minor and patch updates). The tilde (~) is stricter, allowing only patch updates (~19.2.0 means 19.2.x). No prefix pins the exact version. These ranges let you get compatible fixes automatically while your lockfile keeps installs reproducible.
What is the difference between npm install and npm ci?
npm install resolves your dependency ranges and can update package-lock.json — use it during development when adding or changing packages. npm ci does a clean, reproducible install straight from the lockfile: it deletes node_modules, installs the exact locked versions, and fails if package.json and the lockfile disagree. Use npm ci in CI and production for fast, deterministic builds.
Is npm still the best package manager in 2026?
npm remains the default and a solid choice — it ships with Node, has universal compatibility, and version 12 hardened its supply-chain security by disabling install scripts by default. That said, pnpm is often preferred for large monorepos (better disk usage and stricter resolution), and Bun offers the fastest installs as part of an all-in-one toolkit. All three are viable; npm is the safe default.

Install and run npm packages in the browser with XCODX Studio — no local Node setup. See also Node.js best practices, the complete guide to Git and the web development roadmap 2026.