package.json and package-lock.json

package.json describes a Node project's scripts and dependencies; package-lock.json pins the exact versions actually installed, for reproducibility.

                { "name", "scripts", "dependencies", "devDependencies" }
              

Purpose

package.json is a Node project’s manifest: its name and version, its scripts (named commands runnable with npm run <name>), and its dependencies. package-lock.json, generated automatically by npm install, records the exact resolved version of every dependency (and every dependency of those dependencies) actually installed — what makes an install reproducible.

Syntax

{
  "name": "my-app",
  "type": "module",
  "scripts": {
    "start": "node index.js",
    "test": "vitest run"
  },
  "dependencies": {
    "some-library": "^2.1.0"
  },
  "devDependencies": {
    "vitest": "^4.0.0"
  }
}

Behavior notes

  • dependencies are needed to run the finished program; devDependencies are needed only during development (test runners, linters, bundlers) and aren’t required by consumers of a published package.
  • A version range like ^2.1.0 matches any release considered compatible under semantic versioning (any 2.x.x at or above 2.1.0, but not 3.0.0) — flexible, but not exactly reproducible on its own.
  • npm install both installs dependencies and updates package-lock.json to match what was actually resolved; npm ci installs exactly what the lockfile specifies and fails rather than silently updating it — the command to prefer in CI and for onboarding a fresh clone.
  • "type": "module" tells Node to treat .js files in this package as ES modules by default (import/export) rather than CommonJS (require/module.exports).

Common mistakes

  • Not committing package-lock.json to version control, which allows dependency versions to drift silently between installs done at different times.
  • Adding a development-only tool (a test runner, a linter) to dependencies instead of devDependencies, unnecessarily bloating what ships with the published package.

Runtime notes

Node/npm-specific tooling convention; browsers have no equivalent concept, though other package managers (pnpm, yarn) follow the same package.json format with their own lockfile formats.

Taught in these lessons

Related reference

Updated 2026-09-03