The manifest
package.json
"next": "16.4.0"The package version that the project requests.
Builder Academy · Dependency Management · Beginner
Why does CI stop before lint? Learn the difference between a package manifest and a lockfile, then practice diagnosing a real-world Next.js version mismatch.
The manifest
"next": "16.4.0"The package version that the project requests.
The resolved receipt
"next": "16.3.5"The outdated version pinned for installations. It no longer satisfies the manifest.
Think of package.json as the ingredients you order, and package-lock.json as the detailed receipt listing exact versions, where they were resolved, and integrity information. The lockfile also records transitive dependencies: packages your direct dependencies rely on.
A package registry such as npm is the catalog from which packages and metadata are fetched. Integrity hashes help npm check that downloaded package contents match what the lockfile records; they are not a security endorsement.
Continuous Integration (CI) uses npm ci because it checks that the manifest and lockfile are consistent before installing. A mismatch stops dependency installation before ESLint, tests, or the build can run. This is a dependency-resolution failure, not evidence that your source code has lint errors.
Example: package.json requests Next.js 16.4.0, but the lockfile pins 16.3.5.
Result: npm ci exits with an EUSAGE error because the dependency resolution is out of sync.
Fix: regenerate the lockfile, validate it with a clean install, and commit the result.
git switch fix/dependency-security-remediationWork on the existing repair branch rather than changing production directly.
npm install --package-lock-only --ignore-scriptsResolve and rewrite the lockfile without running package lifecycle scripts or reinstalling node_modules. It still needs registry access.
npm ciReinstall from the committed dependency resolution; npm will reject manifest/lockfile drift.
npm run lintCheck code quality only after dependencies have installed successfully.
npm run buildVerify the application compiles. Type checks or stylesheet imports can fail independently of a valid lockfile.
git add package-lock.json && git commit -m "fix(deps): sync lockfile"Commit the exact resolved dependency tree for GitHub Actions and teammates.
Finish by pushing the branch and reviewing the fresh GitHub Actions results. If the clean install passes but the build fails, diagnose that new error separately. Never hand-edit integrity hashes, blindly run npm audit fix --force, or disable CI simply to get a green badge.
Scenario: A security PR updates Next.js and eslint-config-next to 16.4.0, but GitHub Actions fails at npm ci. What should you change first?
Not recommended. This hides drift instead of ensuring CI uses a reproducible dependency resolution.
Correct. Run npm install --package-lock-only, test with npm ci, then commit the new lockfile.
Not a default fix. Preserve the intended safe versions unless testing reveals a documented incompatibility.
Try changing a dependency version in a disposable practice branch without changing the lockfile, then observe npm ci fail. Restore the manifest or regenerate the lockfile, and verify the command passes. Use a synthetic practice project—not production credentials.
Related lesson: Build Rate Limits & CI/CD
References: npm ci, package-lock.json, npm install.