Chapter 3.7 โ€” package-lock.json Conflictsโ˜• 16 min read

package-lock.json Conflicts

Manual edit = corrupted dependencies. npm install = correct merge. Aur lock file KABHI gitignore mat karo!

01Lock File Conflicts: The #1 JavaScript Merge Problem

package-lock.json locks exact dependency versions so every install is identical across machines. It is the contract that guarantees reproducibility.

A lock file conflict occurs when Branch A adds Package X and Branch B adds Package Y โ€” both modify the lock file differently.

Git cannot auto-merge because the lock file has complex nested JSON with interdependent entries, integrity hashes, and dependency trees.

This is the MOST COMMON conflict in JavaScript teams. Every team that uses npm has seen this.

The same problem exists for yarn.lock, pnpm-lock.yaml, Gemfile.lock, Pipfile.lock โ€” any lock file managed by a package manager.

# The typical scenario:
# Branch A: npm install express
# Branch B: npm install lodash
# Both modify package-lock.json differently

git merge feature
# CONFLICT (content): Merge conflict in package-lock.json
# Auto-merge failed for package-lock.json

# DO NOT try to manually resolve this!
# The JSON structure is too complex and interdependent.
package-lock.json conflicts are the #1 merge conflict in JavaScript projects. Why? Because every npm install modifies the entire lock file tree โ€” adding a package changes hashes, updates resolved URLs, and shifts dependency positions. Two branches adding different packages = guaranteed lock file conflict. The good news: the fix is incredibly simple.
02Why Manual Editing Is Dangerous

NEVER manually edit package-lock.json to resolve conflicts. This is the most dangerous thing you can do.

The lock file has integrity hashes, dependency trees, and version constraints that are all interlinked. Change one entry and the whole tree can become inconsistent.

Manually deleting conflict markers will corrupt the file. Even if the JSON becomes valid, the dependency tree might be wrong.

A corrupted lock file means different developers get different node_modules. This causes "works on my machine" bugs that are extremely hard to diagnose.

You might not notice the corruption immediately โ€” it only shows up when a teammate installs and gets a subtly different set of packages.

# WRONG: Manually editing package-lock.json
# Opening the file and deleting conflict markers
# Trying to combine two versions of "requires" arrays
# Result: Corrupted lock file!
# Teammate runs npm install - gets different packages
# Production build behaves differently than development
# Bugs appear that nobody can reproduce

# NEVER DO THIS:
git add package-lock.json  # adding a manually edited lock file
git commit -m "fix conflict"
# You just committed a broken dependency tree!
๐Ÿ’ก Pro Tip: A corrupted lock file is worse than no lock file. With no lock file, everyone gets slightly different versions. With a corrupted lock file, everyone gets different versions BUT thinks they have the same ones โ€” because the lock file says so. This false confidence makes debugging nearly impossible.
03The Correct Fix: Let npm Handle It

The correct resolution is laughably simple: let npm handle it.

Step 1: Accept one version of the lock file: git checkout --theirs package-lock.json

Step 2: Run npm install โ€” npm automatically merges the dependency trees and creates a correct lock file.

npm 7+ can even resolve conflicts automatically if you just run npm install with the conflict markers still in the file. Yes, it is that easy.

Alternative: Delete the lock file entirely and run npm install to regenerate from scratch. Nuclear but clean.

Always commit BOTH package.json AND package-lock.json together after resolution.

# RIGHT: Let npm handle it
# Option 1: Accept one side, then reinstall
git checkout --theirs package-lock.json
npm install
# npm regenerates the lock file with BOTH packages included

# Option 2: npm 7+ auto-resolves (easiest!)
# Just run npm install with conflict markers still in the file
npm install
# npm automatically resolves the conflict and updates the lock file

# Option 3: Delete and regenerate (nuclear but clean)
rm package-lock.json
npm install
# Fresh lock file generated from package.json

# After any option, stage both files:
git add package.json package-lock.json
git commit -m "merge: resolve lock file conflict via npm install"
npm 7+ (released 2021) changed the game. Before npm 7, you had to manually accept one side then reinstall. Now, just running npm install with conflict markers in the lock file will auto-resolve the conflict. npm reads both package.json entries, merges the dependency trees correctly, and writes a clean lock file. One command. Done.
04Same Principle for All Lock Files

The same principle applies to every lock file in every language. Never manually edit โ€” let the package manager handle it.

yarn.lock conflicts: Same approach โ€” do not edit manually. Run yarn install to resolve.

pnpm-lock.yaml conflicts: Run pnpm install to resolve.

Gemfile.lock (Ruby): Run bundle install after accepting one version.

Pipfile.lock (Python): Run pipenv lock to regenerate.

The principle is universal: let the package manager handle lock files, not Git. Git does not understand dependency graphs โ€” package managers do.

# Yarn conflict resolution
git checkout --theirs yarn.lock
yarn install
git add yarn.lock
git commit -m "merge: resolve yarn.lock conflict"

# pnpm conflict resolution
git checkout --theirs pnpm-lock.yaml
pnpm install
git add pnpm-lock.yaml
git commit -m "merge: resolve pnpm lock conflict"

# Ruby Gemfile.lock
git checkout --theirs Gemfile.lock
bundle install
git add Gemfile.lock
git commit -m "merge: resolve Gemfile.lock conflict"
๐Ÿ’ก Pro Tip: The pattern is always the same: (1) accept one version of the lock file, (2) run the package manager install command, (3) commit the regenerated lock file. The package manager understands the dependency graph โ€” Git does not. This is true for npm, yarn, pnpm, bundler, pipenv, cargo, go modules โ€” every single one.
05Preventing Lock File Conflicts

The best conflict is the one that never happens. Here is how to prevent lock file conflicts before they start.

Prevention 1: Update dependencies on main regularly, before branching. A fresh lock file on main means less divergence.

Prevention 2: Before starting a feature branch: git pull origin main && npm install to get the latest deps.

Prevention 3: Use npm ci in CI/CD โ€” it installs exactly from the lock file, no updates. Fails if lock file and package.json are out of sync.

Prevention 4: Keep dependency updates in separate PRs โ€” not mixed with feature code. This isolates lock file changes.

Prevention 5: Use Renovate or Dependabot for automated, conflict-free dependency updates.

# Prevention 1: Update deps on main before branching
git checkout main
npm update
git add package.json package-lock.json
git commit -m "chore: update dependencies"
git push origin main

# Now branch off - your lock file is up to date
git checkout -b feature

# Prevention 2: Use npm ci in CI (strict install from lock file)
npm ci  # deletes node_modules, installs exactly from lock file
# Fails if package.json and lock file are out of sync!

# Prevention 3: Separate PR for dependency updates
# Do not mix "npm install new-package" with feature code
# PR 1: chore: add axios
# PR 2: feat: implement API calls with axios
Renovate and Dependabot are game-changers for lock file conflicts. They create separate PRs for each dependency update, which means: (1) lock file changes are isolated, (2) they merge into main one at a time, (3) feature branches stay up to date by rebasing on main. No more two developers adding packages simultaneously. Automation beats discipline every time.

Lo kar liya โ€” Key Points:

  • โœ… package-lock.json conflicts happen when two branches install different packages, both modifying the lock file
  • โœ… NEVER manually edit lock files to resolve conflicts โ€” this corrupts the dependency tree and causes "works on my machine" bugs
  • โœ… The correct fix: accept one version of the lock file, then run npm install to regenerate it with both sets of dependencies
  • โœ… npm 7+ can auto-resolve lock file conflicts if you just run npm install with conflict markers in the file
  • โœ… The same principle applies to yarn.lock (use yarn install), pnpm-lock.yaml (use pnpm install), and Gemfile.lock (use bundle install)
  • โœ… Prevent lock file conflicts by updating dependencies on main before branching, and use npm ci in CI
Course Search
Search across all chapters & stages
๐Ÿ“–

Search the course

Type any topic โ€” branching, stash, rebase, hooks โ€” and jump straight to that chapter.

merge branchesgit stashundo commitrebase