On macOS, first identify whether npm is reporting a Git merge conflict, a mismatch between package.json and package-lock.json, or a peer dependency resolution error. Check the project files, Git state, and npm versions in Terminal before changing anything. If the lockfile alone needs reconciling, npm’s --package-lock-only option can update it without reinstalling packages into node_modules.
Start in the project folder and preserve the current state
Open Terminal, change to the project directory, and confirm you are at the intended project root. In Finder, you can locate the folder, then use Terminal’s cd command; if the path contains spaces, quote the path, for example cd "$HOME/Projects/My App". Run:
pwd
git status --short
node --version
npm --version
git status --short shows whether either manifest has uncommitted edits. If there are changes you need to keep, save or commit them before proceeding; do not overwrite files while you are still deciding which dependency changes belong. Record the Node.js and npm versions so you can compare them with the project’s documented setup or continuous integration configuration. npm lockfile formats have changed across major npm versions, so a format difference can explain unexpected churn without proving the dependencies themselves are broken. npm’s package-lock documentation
Determine which kind of conflict you have
If package-lock.json contains Git markers such as <<<<<<<, =======, or >>>>>>>, this is a source control merge conflict. Inspect the full affected sections and compare both branch changes. Resolve dependency declarations in package.json first: npm’s older lockfile conflict guidance explicitly says to manually resolve manifest conflicts before regenerating the lockfile. Do not simply keep one side of the lockfile by habit; each branch may have added or changed dependencies. npm’s package-lock conflict guidance
If there are no Git markers, compare the dependency names and ranges in package.json with the lockfile. package.json specifies acceptable ranges, while the lockfile records a resolved dependency tree. Current npm documentation says a normal npm install uses locked versions when they satisfy the manifest ranges and updates the lock when they do not. How npm install uses a lockfile
If the command fails with a peer dependency message, focus on the packages named in that error and their peer requirements. It may be a valid incompatibility between declared package ranges, not a corrupt installation. Do not use --force or --legacy-peer-deps as a diagnostic shortcut: changing dependency resolution behavior can produce a tree that differs from the project’s intended setup.
Inspect the change before asking npm to reconcile
Review the project’s history and current diff:
git diff -- package.json package-lock.json
git log -5 --oneline -- package.json package-lock.json
Look for the commit or branch that changed the dependency declaration, lockfile version, or npm configuration. Also check whether the project has an .npmrc; npm documents that tree-shaping options such as legacy-peer-deps or install-links can affect whether a lockfile and a later clean install agree. Use the same project-specific settings already adopted by the repository rather than adding new flags at random. npm ci documentation
A lockfileVersion value helps identify the file format, but avoid treating it as a diagnosis by itself. npm documents format versions 1, 2, and 3 and notes that newer npm versions can update older lockfiles. A changed version may reflect npm compatibility behavior; inspect the actual dependency diff before accepting a large rewrite. Lockfile format and older files
Reconcile the lockfile without reinstalling dependencies
After resolving any conflict markers and making package.json correct, ask npm to update only the lockfile:
npm install --package-lock-only
npm documents this option as updating package-lock.json without checking node_modules or downloading dependencies. It is a focused reconciliation step; it does not guarantee that the resulting dependency set is the one you intended, so examine the diff afterward. npm install options
git diff --check
git diff -- package.json package-lock.json
git status --short
git diff --check helps catch whitespace errors, while the diff itself shows what npm changed. Confirm the manifest has not picked up unintended edits, inspect unexpected version changes or a broad lockfile rewrite, and verify the conflict markers are gone. If the proposed changes do not make sense, restore the files from your saved state or source control and revisit the cause instead of deleting node_modules or regenerating everything.
Know when a clean install is appropriate
Use npm ci only after the manifest and lockfile are intentionally aligned and you want to reproduce the locked dependency tree. It requires a lockfile, fails rather than updating a mismatch, and removes an existing node_modules directory before installing. That makes it useful for confirming a resolved state, but it is not a harmless inspection command. npm ci behavior
If npm install --package-lock-only cannot resolve the conflict, capture its exact error, review the named package ranges and project npm settings, and compare with the branch or CI environment that produced the lockfile. The decisive question is which dependency declarations the project should keep; installation cleanup cannot answer that for you. Once that decision is reflected in package.json, regenerate only the lockfile, inspect the proposed change, and then choose whether a clean install is necessary.
Sources
npm install — npm
npm ci — npm
package-lock.json — npm
package-locks — npm