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
dependenciesare needed to run the finished program;devDependenciesare needed only during development (test runners, linters, bundlers) and aren’t required by consumers of a published package.- A version range like
^2.1.0matches any release considered compatible under semantic versioning (any2.x.xat or above2.1.0, but not3.0.0) — flexible, but not exactly reproducible on its own. npm installboth installs dependencies and updatespackage-lock.jsonto match what was actually resolved;npm ciinstalls 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.jsfiles in this package as ES modules by default (import/export) rather than CommonJS (require/module.exports).
Common mistakes
- Not committing
package-lock.jsonto 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
dependenciesinstead ofdevDependencies, 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.