DEV Community

Cover image for How to fix package-lock.json merge conflicts (and yarn.lock, poetry.lock, go.sum) the right way
TANK JAY
TANK JAY

Posted on Originally published at jaytank.hashnode.dev

How to fix package-lock.json merge conflicts (and yarn.lock, poetry.lock, go.sum) the right way


You rebase on main and git stops:

CONFLICT (content): Merge conflict in package-lock.json
Enter fullscreen mode Exit fullscreen mode

The usual reflexes are all wrong:

  • Hand-editing the markers away gives you a dependency tree no resolver would produce.
  • "Accept Both Changes" leaves duplicate JSON keys or invalid TOML/YAML.
  • Accepting one side looks fine, but the other branch's new dependencies are silently missing from the lock.

The rule

A lockfile is a build output of the manifest. So:

  1. Resolve the manifest (package.json, pyproject.toml, Cargo.toml, go.mod...) by hand.
  2. Give the tool a lockfile it can read.
  3. Let the tool regenerate the lock.

npm, Yarn and pnpm can read a conflicted lockfile and merge both sides themselves. The others need one clean side first: git checkout --ours -- <lockfile>.

The command table

Lockfile Start from Regenerate with
package-lock.json conflicted file npm install --package-lock-only --ignore-scripts
yarn.lock (v1) conflicted file yarn install --ignore-scripts
yarn.lock (berry) conflicted file yarn install --mode=update-lockfile
pnpm-lock.yaml conflicted file pnpm install --lockfile-only --ignore-scripts
poetry.lock --ours poetry lock (Poetry 2) / poetry lock --no-update (Poetry 1)
uv.lock --ours uv lock
Cargo.lock --ours cargo update --workspace
go.sum --ours go mod tidy
composer.lock --ours composer update --lock --no-install --no-scripts
Gemfile.lock --ours bundle lock
Pipfile.lock --ours pipenv lock

Two gotchas: during a rebase, --ours is the branch you rebase onto, not yours. And for Cargo, skip cargo generate-lockfile: it upgrades everything, which turns a merge into an upgrade.

--ignore-scripts is a deliberate choice: you are regenerating a lockfile, not building, so there is no reason to run install scripts from packages you have not reviewed.

One click in VS Code

I built LockSettle, a free VS Code extension that runs this routine for you. It flags conflicted lockfiles (ten types, monorepos included), refuses and opens the manifest if that is still conflicted, shows you the exact command in a confirmation dialog, runs it as a visible task in the right folder, then checks for leftover markers and offers to stage the file. Every command is overridable. No network, no telemetry, nothing runs in an untrusted workspace.

It also gets its own activity bar icon with a badge, and a Conflicted lockfiles panel with Regenerate and Open manifest buttons.

code --install-extension jaytankdev.locksettle
Enter fullscreen mode Exit fullscreen mode

Source (MIT): github.com/jay-tank/locksettle

Full write-up (why each tool differs, Yarn berry and Poetry 2 details, safety design, FAQ): How to fix package-lock.json merge conflicts the right way

Top comments (0)