테크큐브 · IT테크

npm 패키지 버전 충돌 해결하는 법

✍ 테크큐브 편집팀 · 2026. 8. 14. · IT 트렌드·이슈
얽힌 의존성 트리와 서로 충돌하는 패키지 버전 태그를 표현한 일러스트
목차
  1. npm 버전 충돌, 왜 발생할까요?
  2. 에러 메시지로 원인부터 진단하기
  3. 단계별 해결 방법
  4. 상황별 어떤 방법을 써야 할까
  5. 자주 하는 실수와 주의사항
  6. yarn·pnpm에서는 어떻게 다를까
  7. 자주 묻는 질문
  8. 참고자료

npm에서 패키지 버전 충돌이 발생하면 대부분 npm install 실행 중 ERESOLVE(npm이 패키지 간 의존성 관계를 해석하지 못할 때 뜨는 에러 코드) 메시지와 함께 설치가 멈춥니다. 가장 빠른 해결 순서는 ①npm ls로 충돌 패키지 특정 → ②package-lock.json·node_modules 재설치 → ③overrides로 버전 강제 지정 순이며, --legacy-peer-deps--force는 원인을 없애는 게 아니라 경고를 숨기는 임시 조치라는 점을 먼저 알아두어야 합니다. 아래에서 원인 진단부터 실전 해결 단계까지 순서대로 정리합니다.

npm 버전 충돌, 왜 발생할까요?

npm 버전 충돌 해결 과정을 보여주는 화면으로 터미널 오류를 확인하고 패키지 삭제와 재설치, 버전 고정, 중복 정리를 진행하는 단계를 표현한 기술 이미지

의존성 트리와 semver 규칙

npm(Node Package Manager, 자바스크립트 패키지 관리 도구)은 패키지를 설치할 때 semver(Semantic Versioning, 유의적 버전 표기 규칙 — 예: ^1.2.0, ~2.0.0)를 기준으로 서로 다른 패키지가 요구하는 버전 범위를 계산해 하나의 트리로 맞춥니다. 그런데 A 패키지는 B 패키지의 1.x 버전을, C 패키지는 B 패키지의 2.x 버전을 요구하는 식으로 범위가 겹치지 않으면 npm이 하나의 버전으로 통일하지 못해 충돌이 발생합니다. 프로젝트 규모가 커지고 의존 패키지가 많아질수록 이런 겹침이 늘어나는 것이 근본 원인입니다.

peer dependency 충돌

peer dependency(동료 의존성 — 한 패키지가 '나를 쓰려면 이 패키지의 특정 버전도 같이 설치돼 있어야 한다'고 명시하는 관계)는 특히 React, ESLint 플러그인처럼 호스트 패키지에 종속되는 라이브러리에서 자주 문제를 일으킵니다. 예를 들어 어떤 라이브러리가 react@^17을 peer dependency로 요구하는데 프로젝트에는 이미 React 18이 설치돼 있다면, 이 지점에서 충돌이 발생합니다.

npm 6 이하에서는 peer dependency 불일치가 있어도 경고만 띄우고 설치를 계속 진행했지만, npm 7 버전부터는 기본값이 strict 모드로 바뀌어 충돌이 확인되면 설치 자체가 ERESOLVE 에러로 중단됩니다. Node.js 18 이상을 쓰고 있다면 대부분 npm 9 이상이 함께 설치돼 있어 이 strict 모드의 영향을 받습니다.

에러 메시지로 원인부터 진단하기

npm ls로 의존성 트리 확인하기

충돌 해결의 첫 단계는 무작정 옵션을 붙여 재설치하는 것이 아니라, 어떤 패키지가 어떤 버전을 요구해서 충돌이 났는지를 정확히 파악하는 것입니다. 아래 명령으로 특정 패키지가 프로젝트 안에서 몇 개의 버전으로 중복 설치돼 있는지 확인할 수 있습니다.

npm ls react
# 또는 전체 의존성 트리에서 문제 패키지 검색
npm ls react --all

ERESOLVE 로그 읽는 법

ERESOLVE 에러 로그는 보통 Found: react@18.2.0Could not resolve dependency: peer react@"^17.0.0" from some-package@1.0.0 형태로 '실제 설치된 버전'과 '요구하는 버전 범위'를 나란히 보여줍니다. 이 두 줄만 읽어도 어느 패키지가 어떤 버전을 요구하는지 바로 특정할 수 있으므로, 에러 로그를 끝까지 읽지 않고 검색 결과의 --force 옵션부터 복사해 붙여넣는 것은 원인 파악 기회를 놓치는 흔한 실수입니다.

단계별 해결 방법

npm 버전 충돌 해결 과정에서 발생하는 실수를 경고하는 화면으로 --force와 --legacy-peer-deps 사용, package-lock 관리, overrides 설정 주의사항을 보여주는 기술 이미지
  1. npm ls로 충돌 패키지와 요구 버전 범위 확인
  2. package-lock.json과 node_modules 삭제 후 재설치
  3. 불가피할 때만 --legacy-peer-deps 또는 --force 사용
  4. package.json overrides로 특정 버전 강제 지정
  5. npm dedupe로 중복 설치된 버전 정리

1단계: package-lock.json 삭제 후 재설치

가장 먼저 시도할 방법은 기존 잠금 파일을 지우고 새로 설치해보는 것입니다. package-lock.json(설치된 패키지들의 정확한 버전 조합을 기록해 재현성을 보장하는 잠금 파일)이 과거 버전 조합을 그대로 고정하고 있어서 충돌이 나는 경우가 의외로 많습니다.

rm -rf node_modules package-lock.json
npm install

2단계: --legacy-peer-deps 또는 --force

재설치로도 해결되지 않으면 npm 6 이하와 동일하게 peer dependency 검증을 완화하는 --legacy-peer-deps를 시도합니다. 이 옵션은 충돌을 없애는 게 아니라 검증 자체를 건너뛰는 것이므로, 런타임에서 실제로 문제가 생기지 않는지 반드시 기능 테스트로 확인해야 합니다.

npm install --legacy-peer-deps
# 최후 수단, 위험도가 더 높음
npm install --force
--legacy-peer-deps와 --force는 에러 메시지만 사라지게 할 뿐 버전 비호환 문제 자체를 없애지 않습니다. 특히 --force는 semver 범위를 아예 무시하고 강제로 설치를 진행하므로, 배포 전 반드시 주요 기능이 정상 동작하는지 점검한 뒤 사용하세요.

3단계: overrides로 버전 강제 지정

npm 8.3 이상에서 지원하는 overrides 필드를 쓰면 하위 의존성이 요구하는 버전과 무관하게 특정 패키지의 버전을 프로젝트 전체에서 하나로 고정할 수 있습니다. 근본적인 해결에 가장 가까운 방법입니다.

{
  "overrides": {
    "react": "18.2.0",
    "some-old-package": {
      "react": "18.2.0"
    }
  }
}

4단계: npm dedupe로 중복 정리

여러 패키지가 같은 라이브러리의 서로 다른 마이너 버전을 요구해 node_modules 안에 중복 설치된 경우, npm dedupe를 실행하면 semver 범위상 호환되는 선에서 하나의 버전으로 정리해 트리를 단순화할 수 있습니다.

npm dedupe

상황별 어떤 방법을 써야 할까

세 가지 방법은 위험도와 지속가능성이 다르므로 상황에 맞게 골라야 합니다.

상황추천 방법주의사항
단순 잠금 파일 꼬임package-lock.json 삭제 후 재설치팀 전체가 같은 시점에 재설치해야 버전 드리프트가 없음
당장 개발을 이어가야 할 때--legacy-peer-deps배포 전 기능 테스트 필수, 임시 조치로만 사용
여러 패키지가 공통 라이브러리를 다른 버전으로 요구package.json overrides강제 지정 버전이 실제로 호환되는지 검증 필요
node_modules 용량·중복이 문제일 때npm dedupesemver 범위 밖 버전은 병합되지 않음

자주 하는 실수와 주의사항

npm 버전 충돌 해결 시 자주 하는 실수와 주의사항을 표현한 화면으로 오류 로그 확인과 배포 전 검증의 중요성을 강조하는 개발 환경 이미지

버전 충돌 해결 과정에서 아래와 같은 실수가 반복되면 오히려 문제를 키울 수 있습니다.

  • 에러 로그를 읽지 않고 검색 결과의 --force 명령부터 그대로 실행하는 경우
  • --legacy-peer-deps로 설치는 성공했지만 실제 기능 테스트 없이 그대로 배포하는 경우
  • package-lock.json을 .gitignore에 넣어 팀원마다 다른 버전 조합으로 설치되는 경우
  • overrides로 버전을 고정한 뒤 해당 패키지의 마이너 업데이트를 계속 놓치는 경우

yarn·pnpm에서는 어떻게 다를까

다른 패키지 매니저를 쓴다면 대응 방식과 명령어가 다릅니다.

  • yarn: peer dependency 충돌 시에도 npm 7처럼 강하게 설치를 막지 않는 경우가 많고, resolutions 필드로 overrides와 동일한 역할을 합니다.
  • pnpm: node_modules 구조 자체가 npm과 달라(심볼릭 링크 기반) 중복 설치 문제는 덜하지만, peer dependency 경고는 별도로 확인해야 합니다.

같은 프로젝트에서 패키지 매니저를 섞어 쓰면(예: npm과 yarn 잠금 파일이 함께 존재) 버전 충돌 진단이 더 어려워지므로, 한 프로젝트에는 하나의 패키지 매니저와 잠금 파일만 유지하는 것이 좋습니다.

자주 묻는 질문

Q. npm install --force를 쓰면 안전한가요?

기능적으로 설치는 완료되지만 semver 범위를 무시하고 강제로 버전을 맞추는 것이라 런타임 오류 가능성이 남습니다. 급한 상황의 임시 조치로만 쓰고, 이후 overrides나 패키지 업데이트로 정식 해결하는 것이 안전합니다.

Q. package-lock.json을 삭제해도 되나요?

단독 개발 환경에서는 삭제 후 재설치로 대부분 해결되지만, 팀 프로젝트라면 삭제 전 원인을 먼저 진단하고 삭제 후에는 반드시 새로 생성된 잠금 파일을 커밋해 팀원 전체가 같은 버전 조합을 쓰도록 해야 합니다.

Q. ERESOLVE 에러가 npm 버전에 따라 다르게 나타나나요?

네, npm 7 이상에서는 peer dependency 불일치 시 기본적으로 설치가 중단되지만 npm 6 이하에서는 경고만 표시하고 설치가 진행됩니다. Node.js 버전을 업그레이드하면 함께 올라오는 npm 버전 때문에 이전에 없던 에러가 갑자기 나타날 수 있습니다.

Q. overrides와 resolutions는 같은 기능인가요?

역할은 비슷하지만 문법과 지원 패키지 매니저가 다릅니다. overrides는 npm 8.3 이상에서, resolutions는 yarn에서 사용하는 필드이며 두 필드를 동시에 넣어도 서로 인식하지 못하므로 사용하는 패키지 매니저에 맞는 필드만 작성해야 합니다.

Q. 충돌 해결 후에도 빌드가 실패하면 어떻게 하나요?

버전을 강제로 맞췄더라도 실제 API가 호환되지 않으면 빌드나 런타임에서 별도 오류가 날 수 있습니다. 이 경우 해당 패키지의 공식 릴리스 노트에서 호환 버전 표를 확인하고, 필요하면 두 패키지 모두 최신 메이저 버전으로 함께 올리는 것이 근본적인 해결책입니다.

참고자료

함께 보면 좋은 글