Skip to main content

Command Palette

Search for a command to run...

npm SemVer 실무 가이드

Published
3 min read

이 글은 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 형식이어야 한다.

허용되지 않는 예:

  • 1

  • 1.2

  • 1_2_3

  • v1.2.3

  • 01.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.00.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의 도움을 받아 내용을 정리하였습니다.

More from this blog

LLM은 어떻게 글을 읽고 쓰는가 — 입력부터 출력까지

대화형 AI에게 질문을 던지면, 마치 사람처럼 문장을 이해하고 답을 써 내려가는 것처럼 보인다.하지만 그 안에서 벌어지는 일은 생각보다 단순하고, 또 생각보다 기계적이다.이 글에서는 두 가지 질문에 답해 본다.LLM은 어떻게 글을 만들어내는가,그리고 우리가 입력한 프롬프트는 모델에 어떤 모습으로 들어가는가. 1부. LLM은 어떻게 글을 만들어내는가 핵심은

Jun 10, 20264 min read

useEffect 지옥이란 무엇이며, 어떻게 안전하게 사용하는가

React를 어느 정도 사용하다 보면 한 번쯤은“useEffect 지옥에 빠졌다”는 말을 듣거나 직접 느껴본 적이 있을 것이다. useEffect가 계속 늘어나고 의존성 배열은 점점 길어지고 왜 실행되는지 이해하기 어려워지며 eslint-disable-next-line 이 늘어나는 상태 하지만 많은 사람들이 오해한다.useEffect 지옥은 useEffect가 많아서 생기는 문제가 아니다. 이 글에서는 ‘useEffect 지옥’의 ...

Jan 12, 20263 min read

Zod란 무엇인가: TypeScript에서 런타임 검증과 타입 안정성을 동시에 해결하는 방법

TypeScript 프로젝트를 하다 보면 반드시 마주치는 문제가 있다.바로 “타입은 있는데, 데이터는 믿을 수 없다”는 것이다. TypeScript는 컴파일 타임에는 강력하지만,런타임에 들어오는 데이터에 대해서는 아무런 보장을 해주지 않는다. API 요청 데이터 사용자 입력(Form) 환경 변수 (process.env) 외부 JSON / 설정 파일 이 모든 것은 타입 시스템 바깥에서 들어온다. 이 문제를 해결하기 위해 등장한 라이브러...

Jan 10, 20263 min read

Flatpak을 이해하기 위한 배경 지식

배포판, 라이브러리 충돌, 그리고 OSTree까지 리눅스 데스크톱에서 Flatpak이 표준처럼 자리 잡은 데에는 분명한 이유가 있다.그 이유를 이해하려면 단순히 “Flatpak은 패키징 시스템이다”를 넘어서,리눅스 배포판 구조, 라이브러리 버전 충돌, OSTree라는 기술까지 함께 이해해야 한다. 이 글에서는 다음 질문에 답해본다. 리눅스에서 말하는 배포판이란 무엇인가? 라이브러리 버전 충돌은 왜 발생하는가? Flatpak은 이 문제를 어...

Jan 8, 20265 min read

Dev note

31 posts