2026. 6. 18.
npm ERESOLVE 오류가 뜰 때, Found와 peer 버전부터 읽는 순서
새 패키지를 설치하다 npm ERESOLVE가 뜨면 우회 플래그부터 붙이지 말고 Found의 현재 버전과 peer의 요구 범위를 비교해 충돌 소유자를 가려야 한다.

AI 코딩 도구가 “이 패키지를 설치하면 된다”라고 해서 npm install을 실행했는데, 터미널에 ERESOLVE unable to resolve dependency tree가 뜨는 순간이 있다. 초보자는 이때 두 방향으로 흔들린다. 하나는 오류를 전부 이해해야 할 것 같은 부담이고, 다른 하나는 검색에서 본 --legacy-peer-deps를 바로 붙이고 싶은 마음이다.
핵심은 긴 로그를 모두 해석하는 일이 아니다. Found의 현재 버전과 peer의 요구 범위를 먼저 비교하는 것이다. 둘이 맞지 않으면 충돌한 패키지 이름을 적고, package 파일 변화와 의존성 경로를 확인한 뒤 업데이트·대체·보류 중 하나를 고른다.
npm package.json의 peerDependencies 공식 문서는 패키지와 호스트 도구·라이브러리의 호환 범위를 표현한다고 설명한다. npm v7 이후에는 peer dependency가 기본으로 설치되며, 서로 충돌하는 요구로 트리를 해결하지 못하면 오류가 날 수 있다.
ERESOLVE 블록에서는 Found와 peer 두 줄부터 읽는다
터미널 로그가 길어도 처음 볼 곳은 하나다. npm ERR! code ERESOLVE가 나온 다음 블록에서 Found:와 Could not resolve dependency: 또는 peer로 시작하는 줄을 찾는다.
Found: [email protected]
Could not resolve dependency:
peer react@"^18.x" from example-package
이 구조라면 문제는 npm 전체가 아니라 example-package가 기대하는 React 범위와 현재 프로젝트의 React 버전이 맞지 않는 것이다. 이 단계에서는 해결 명령을 고르지 않는다.
이 단계에서는 해결책을 고르지 않는다. 아래 세 줄만 채운다.
설치하려던 패키지:
현재 프로젝트의 패키지와 버전:
충돌을 요구한 패키지와 버전 범위:
이 세 줄을 채운 뒤에만 AI에게 다시 묻는다. 그러면 “설치 옵션을 바꿔보라”는 추측보다 “이 패키지가 현재 버전을 지원하는지 보자”는 질문으로 좁힐 수 있다. 오류 질문을 더 구조화하려면 AI에게 오류를 다시 물을 때 채울 네 칸도 같은 방식으로 쓸 수 있다.
설치를 다시 시도하기 전에 package 파일 diff를 본다
npm install은 package.json 범위와 lockfile을 비교하고, 범위가 맞지 않으면 새 버전을 계산해 package-lock.json을 갱신할 수 있다. 그래서 충돌이 난 뒤에는 파일이 바뀌었는지 먼저 확인한다. lockfile을 지울지 고민된다면 npm 오류 뒤 package-lock 삭제 여부를 가르는 기준을 함께 확인한다.
git diff -- package.json package-lock.json
초보자가 흔히 놓치는 지점은 “설치가 실패했으니 아무것도 안 바뀌었겠지”라고 생각하는 것이다. 실제로는 설치 시도, 재시도, 다른 플래그 사용 때문에 lockfile이나 package.json이 바뀌어 있을 수 있다. 충돌 원인을 모르는 상태에서 이 파일들이 계속 바뀌면 다음 오류가 원래 충돌인지, 방금 바꾼 설치 상태 때문인지 분리하기 어려워진다.
아직 판단이 안 섰다면 파일을 저장하기 전에 이렇게 묻는다.
package 파일 diff를 봐 주세요.
이번 npm install 충돌 해결에 필요한 변경인지,
되돌려야 할 설치 흔적인지 분류해 주세요.
새 설치 명령은 아직 제안하지 마세요.
이 요청은 AI에게 코드를 더 쓰게 하는 질문이 아니다. 설치 상태를 분류하게 하는 질문이다.
설치된 패키지는 npm explain으로 누가 끌고 왔는지 본다
충돌 패키지 이름을 알았고 그 패키지가 현재 프로젝트에 설치돼 있다면 npm explain을 쓴다. npm explain 공식 문서는 이 명령이 특정 패키지를 설치하게 만든 의존성 체인을 출력한다고 설명한다. 설치가 완전히 실패해 패키지가 없다면 이 명령보다 ERESOLVE 로그와 package.json 비교가 먼저다.
npm explain react
npm explain example-package
여기서 중요한 것은 “어떤 패키지가 직접 설치한 것인지”와 “어떤 패키지가 다른 패키지를 통해 들어온 것인지”를 나누는 일이다. 직접 설치한 패키지라면 버전을 바꾸거나 제거하는 판단이 비교적 쉽다. 반대로 다른 라이브러리가 끌고 온 하위 의존성이라면 그 상위 패키지를 업데이트하거나 대체해야 할 수 있다.
AI에게는 이렇게 묶어 준다.
npm install에서 ERESOLVE가 났다.
설치하려던 패키지:
ERESOLVE의 Found 줄:
ERESOLVE의 peer 요구 줄:
npm explain 결과:
요청:
원인 패키지를 셋 중 하나로 분류해 주세요.
- 직접 의존성
- 하위 의존성
- peer 요구
그 다음 안전한 선택을 골라 주세요.
- 업데이트
- 대체 패키지
- 설치 보류
이 프롬프트의 핵심은 legacy-peer-deps를 먼저 묻지 않는 것이다. 충돌의 소유자를 찾은 뒤에야 우회가 필요한지 판단할 수 있다.
legacy-peer-deps는 마지막에만 검토한다
--legacy-peer-deps는 자주 보이는 해결책처럼 보인다. 하지만 npm config 문서는 이 설정이 패키지 트리를 만들 때 peerDependencies를 완전히 무시하며, peer dependency 계약을 강제하지 않으므로 권장하지 않는다고 설명한다. 설치 성공은 호환성 확인과 같은 말이 아니다.
그렇다고 이 플래그가 절대 쓰면 안 되는 금지어라는 뜻은 아니다. 오래된 프로젝트를 임시로 살리거나, 팀이 이미 같은 설정을 합의해 .npmrc에 기록한 경우도 있다. 문제는 초보자가 이 플래그를 “정답”처럼 외워서 쓰는 순간이다.
우회 전에 네 가지를 확인한다.
- 충돌 패키지의 최신 버전이 현재 프로젝트 버전을 지원하는지 본다.
- 같은 기능을 하는 다른 패키지가 현재 React나 Next.js 버전을 지원하는지 본다.
- 팀 프로젝트라면 기존
.npmrc나 CI 설치 명령이 같은 플래그를 쓰는지 본다. - 우회 후에는
npm run build또는 프로젝트의 테스트 명령을 반드시 실행한다.
CI 환경이라면 npm ci도 구분해야 한다. npm ci 공식 문서는 lockfile과 package.json의 의존성이 맞지 않으면 오류로 종료하고 package 파일을 쓰지 않는다고 설명한다. 또한 --legacy-peer-deps처럼 트리 모양을 바꾸는 플래그로 lockfile을 만들었다면 CI에서도 같은 플래그를 제공해야 오류를 피할 수 있다고 안내한다. 팀 설정과 CI 명령이 다르면 우회를 보류한다.
오늘 남길 결과물은 충돌 요약 네 줄이다
지금 설치가 막혔다면 터미널을 닫지 말고 아래 네 줄만 채운다.
설치하려던 명령:
Found 줄:
peer 요구 줄:
npm explain으로 확인한 패키지:
이 네 줄이 있으면 AI에게 다시 물을 때 프로젝트 전체를 던질 필요가 없다. npm install 충돌은 무조건 빨리 넘기는 문제가 아니라 어떤 패키지가 어떤 버전을 요구하는지 먼저 가르는 문제다. 오늘은 우회 플래그를 붙이기 전에 충돌 이름과 버전 범위를 분리하는 데서 멈춘다.
참고 출처
- package.json의 peerDependencies (npm Docs)
- npm install (npm Docs)
- npm explain (npm Docs)
- npm ci (npm Docs)
- legacy-peer-deps 설정 (npm Docs)
이 글은 AI 코딩과 개발 학습의 일반 정보 제공 목적입니다. 도구, 모델, 커리큘럼, 요금은 버전과 시점에 따라 달라질 수 있으므로 실습이나 도입 전 공식 문서와 최신 릴리스 노트를 확인하세요.
다음으로 읽을 기사
같은 흐름으로 이어 읽기 좋은 기사만 추려 보여줍니다.
첫 번째 댓글을 남겨보세요
여러분의 생각이 다른 독자에게 도움이 됩니다.
댓글 0
이 글을 읽은 독자들의 생각을 나눠보세요.