package.json and Lock Files: Same Install Every Time
What package.json and package-lock.json record, what ^ means in a version, and when to use npm install or npm ci. After this, your project installs the same versions on every machine.
Course content
Sign in to save your progress.
-
Set Up Projects That Don't Break Each Other
-
Node.js and npm: Running JavaScript Outside the Browser
-
package.json and Lock Files: Same Install Every Time
-
-
-
Organize Code Other People Can Read
-
JavaScript Modules: import, export and Splitting One Big File
-
JavaScript Classes: When an Object Literal Is No Longer Enough
-
Destructuring and Spread Without the Confusion
-
-
-
Work With Real Data
-
Array Methods: map, filter, reduce and When a Loop Is Clearer
-
Working With JSON: parse, stringify and What Breaks
-
Dates in JavaScript Without Losing a Day
-
-
-
Waiting for Things
-
Callbacks to Promises: Why the Code Runs Out of Order
-
async/await and fetch: Calling a Real API
-
-
-
Prove It Works Before Someone Else Finds Out
-
try/catch and Custom Errors
-
Your First Tests With Vitest
-
-
- Final Check: JavaScript Intermediate
Skip ahead: If you already know what ^ means in a version and why you commit package-lock.json, skip to "npm install vs npm ci".
"It works on my machine." Most of the time, when a JavaScript project works for one person and not another, the two machines installed different versions of the same packages. package.json and package-lock.json exist to stop that. Commit both. Use the lock file. That's most of this lesson.
package.json: what you asked for
Run npm init -y and then npm install dayjs in an empty folder, and package.json looks like this:
{
"name": "order-report",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"type": "commonjs",
"dependencies": {
"dayjs": "^1.11.23"
}
}
The parts that matter:
- scripts: the commands for this project (
npm test,npm run build). - type: how Node reads your
.jsfiles.commonjsmeansrequire().modulemeansimport. Recent npm versions write"type": "commonjs"for you, which matters in the modules lesson. - dependencies: packages the code needs to run.
- devDependencies: packages only needed while developing, like a test runner. Install them with
npm install --save-dev vitest.
What the ^ means
"^1.11.23" doesn't mean "version 1.11.23". It means "1.11.23 or any newer 1.x version". So if the package publishes 1.12.0 next month, a fresh install takes 1.12.0.
^1.11.23: newer minor and patch versions allowed (1.12.0 yes, 2.0.0 no).~1.11.23: only newer patch versions (1.11.24 yes, 1.12.0 no).1.11.23: exactly that version.
The idea is reasonable: minor versions shouldn't break anything. In practice, sometimes they do. That's why the lock file exists.
package-lock.json: what you actually got
The lock file records the exact version of every package installed, including the packages your packages depend on, plus where it came from and a checksum:
"node_modules/dayjs": {
"version": "1.11.23",
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.23.tgz",
"integrity": "sha512-QDTC...",
"license": "MIT"
}
With the lock file, a teammate who installs next month gets 1.11.23, the same as you. Without it, they get whatever is newest that matches ^.
⚠ Warning: Commit package-lock.json. Don't delete it to "fix" an install error, and don't add it to .gitignore. Deleting it throws away the record of what worked and pulls the newest of everything at once. If something then breaks, you won't know which of the hundreds of updated packages did it.
npm install vs npm ci
npm installreadspackage.json, uses the lock file where it can, and updates the lock file if something changed. Use it when you add, remove or update a package.npm ciinstalls exactly what's in the lock file. It deletesnode_modulesfirst, never changes the lock file, and stops with an error ifpackage.jsonand the lock file disagree. Use it on a build server, in CI, and when you just cloned a project.
That error looks like this when someone added a package to package.json by hand and didn't update the lock file:
npm error `npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with `npm install` before continuing.
npm error
npm error Missing: ms@2.1.3 from lock file
That's a good error. It caught a mismatch before it shipped. The fix is to run npm install on your machine, check the changes to the lock file, and commit them.
A real example
Two developers start the same project a month apart. One gets a package at 3.4.0, the other at 3.5.0, which changed a default. Same code, different results, and the bug only shows up for one of them. If both had run npm ci from the same committed lock file, they would have the same 3.4.0, and the update to 3.5.0 would be a separate change someone made on purpose and could test.
💡 Tip: Before you update packages, run npm outdated. It lists each package with the version you have, the newest your ^ range allows, and the latest. Update a few at a time, run the tests, commit. Updating everything at once makes the next bug hard to trace.
Common mistakes
- Not committing the lock file, or committing
node_modulesinstead. - Deleting
package-lock.jsonandnode_modulesas the first fix for every error. - Running
npm installon the build server, so the lock file can change during the build. - Editing versions in
package.jsonby hand and forgetting to runnpm install. - Putting test tools in
dependenciesinstead ofdevDependencies.
What happens if you skip this
Without a committed lock file, every machine installs a slightly different project. Most days nothing happens. Then one day a dependency of a dependency publishes a bad release, your server installs it during a deploy, and the site breaks with code nobody on your team changed.
Look at a project you have. Is package-lock.json committed, and does its build use npm ci or npm install?
About
What package.json and package-lock.json record, what ^ means in a version, and when to use npm install or npm ci. After this, your project installs the same versions on every machine.
- Duration
- 5 min
- Last update
- 09/03/2026
Comments (0)
Sign in to commentNo comments yet.