npm SemVer 실무 가이드
이 글은 npm의 Semantic Versioning(SemVer) 을 처음 접하는 개발자부터, 실무에서 이미 사용하고 있지만 헷갈리는 포인트가 많은 개발자까지를 대상으로 한다.
단순한 규칙 나열이 아니라, 실제 업무에서 어떻게 쓰이고, 어디서 사고가 나며, 어떤 관습이 굳어졌는지를 중심으로 정리했다.
1. SemVer란 무엇인가?
SemVer(Semantic Versioning)는 버전 번호에 의미를 부여하는 규칙이다.
기본 형식은 다음과 같다.
MAJOR.MINOR.PATCH
예:
1.4.2
각 숫자의 의미는 다음과 같다.
MAJOR: 하위 호환되지 않는 변경 (Breaking Change)
MINOR: 하위 호환되는 기능 추가
PATCH: 버그 수정
버전만 보고도 “이 업데이트가 안전한지”를 판단할 수 있게 하는 것이 목적이다.
2. SemVer 공식 규격 vs npm의 현실
2.1 SemVer 2.0.0 공식 규격
공식 규격상 정식 버전은 반드시 MAJOR.MINOR.PATCH 형식이어야 한다.
허용되지 않는 예:
11.21_2_3v1.2.301.2.3
구분자는 반드시 . 이며, 세 숫자는 모두 정수여야 한다.
2.2 npm에서의 현실적인 동작
npm은 node-semver 라이브러리를 사용하며, 의존성 범위(range) 표현에서는 훨씬 관대하다.
"dependencies": {
"react": "1",
"lodash": "1.2"
}
이 경우 npm은 다음처럼 해석한다.
"1"→>=1.0.0 <2.0.0"1.2"→>=1.2.0 <1.3.0
⚠️ 하지만 이는 버전 범위 표현일 뿐, 실제 패키지 버전(package.json > version)으로는 사용할 수 없다.
3. npm에서 자주 쓰이는 버전 범위 문법
3.1 Caret (^) — 실무 기본값
"react": "^18.2.0"
의미:
>=18.2.0 <19.0.0
MAJOR 고정
MINOR, PATCH 자동 업데이트
가장 널리 쓰이는 패턴이다.
3.2 Tilde (~) — 패치만 허용
"express": "~4.18.2"
의미:
>=4.18.2 <4.19.0
MINOR 고정
PATCH만 허용
내부 라이브러리나 안정성이 매우 중요한 경우에 사용된다.
3.3 정확한 버전 고정
"react": "18.2.0"
재현성은 높음
보안 패치 자동 반영 불가
4. Pre-release 버전과 설치 우선순위
4.1 Pre-release란?
1.0.0-alpha
1.0.0-beta.1
1.0.0-rc.1
정식 릴리즈 이전의 테스트 버전이다.
4.2 설치 우선순위 규칙 (중요)
npm은 항상 정식 릴리즈를 Pre-release보다 우선한다.
예:
존재하는 버전
1.0.0
1.1.0
1.2.0-beta.1
"pkg": "^1.0.0"
👉 설치 결과: 1.1.0
Pre-release는 자동 선택되지 않음
정식 버전이 없다고 해서 Pre-release를 fallback으로 사용하지도 않음
4.3 Pre-release를 설치하려면
명시적으로 지정해야 한다.
"pkg": "1.2.0-beta.1"
또는
npm install pkg@beta
5. 0.x 버전의 현실적인 취급
SemVer 규칙상 0.x는 불안정 버전이다.
즉:
0.1.0 → 0.2.0
도 breaking change가 가능하다.
실무 관행
많은 라이브러리가 0.x에서도 사실상 안정적으로 운영되기 때문에,
"lib": "^0.14.2"
처럼 MINOR를 MAJOR처럼 취급하는 관습이 널리 쓰인다.
6. npm publish와 dist-tag
6.1 기본 동작
npm publish
👉 자동으로 latest 태그가 붙는다.
npm install your-pkg
은 곧
npm install your-pkg@lates
와 같다.
6.2 Pre-release 배포 시 주의점
npm publish --tag beta
⚠️ 옵션을 주지 않으면 beta 버전도 latest가 된다.
이로 인해 실제 서비스 장애가 발생한 사례가 매우 많다.
7. npm tag 이름 규칙
7.1 tag 이름은 자유로운가?
대부분 자유롭다.
npm publish --tag beta
npm publish --tag next
npm publish --tag canary
npm publish --tag legacy
npm은 tag의 의미를 해석하지 않는다.
7.2 사실상 기본 태그
latest
이 태그만 npm의 기본 동작과 연결되어 있다.
7.3 사용할 수 없는 tag 이름
- semver 형식 문자열
npm publish --tag 1.2.3 # ❌
npm publish --tag v2.0.0 # ❌
버전과 혼동되기 때문에 명시적으로 금지된다.
8. 실무에서 통용되는 SemVer 활용 방식 요약
소비자(의존성 사용)
^MAJOR.MINOR.PATCH기본package-lock.json커밋 필수MAJOR 업그레이드는 수동
제공자(라이브러리 배포)
PATCH: 버그 수정
MINOR: 하위 호환 기능 추가
MAJOR: 진짜 breaking change만
Pre-release는 항상 별도 tag 사용 (beta, next 등)
9. 핵심 정리
SemVer는 규칙이지만, 실무에서는 관습과 자동화가 더 중요하다
npm은 안정성을 위해 정식 버전을 항상 우선한다
npm publish는 기본적으로 latest를 건드린다tag는 자유롭지만 의미는 팀이 책임져야 한다
한 줄 요약
SemVer는 버전 규칙이 아니라, 생태계 전체가 암묵적으로 합의한 계약이다.
🧾 작성 참고
이 글은 ChatGPT의 도움을 받아 내용을 정리하였습니다.