버전 매니저
버전 매니저
프로젝트마다 필요한 언어 런타임 버전이 다릅니다. 한 머신에서 여러 버전을 안전하게 오가는 도구가 버전 매니저. 이 글은 Node · Python · JVM 의 대표 도구와 다중 언어 매니저.
1. 버전 매니저가 필요한 자리
언어 런타임을 시스템 패키지 매니저 (apt install nodejs · Windows MSI 인스톨러) 로 설치하면 보통 한 버전만. 프로젝트 A 는 Node 18, B 는 Node 22, C 는 Node 16 을 요구할 때 매번 재설치는 비현실적. 또한 시스템 전역 설치는 글로벌 npm 패키지 설치 시 관리자 권한이 필요해지는 등 추가 문제.
버전 매니저가 제공하는 것:
- 여러 버전을 사용자 홈 디렉터리에 격리 설치.
- 셸 진입 시 또는 디렉터리 진입 시 자동으로 버전 전환 (
.nvmrc·.python-version·.tool-versions). - 시스템 PATH 를 건드리지 않는 shim 또는 함수.
2. 두 가지 동작 방식
대부분의 매니저는 두 방식 중 하나:
- Shim 방식 —
~/.pyenv/shims/python같은 얇은 래퍼를 PATH 앞에. 실제 호출 시 현재 디렉터리의.python-version등을 보고 알맞은 실제 바이너리로 라우팅. 어떤 셸에서도 똑같이 동작. - 셸 함수 / PATH 재배치 — nvm 처럼
nvm use 20시 셸 함수가 PATH 의 Node 위치를 바꿈. 가벼우나 셸 종속.
3. Node.js
| 도구 | 출시 | 특징 |
|---|---|---|
| nvm (creationix → nvm-sh) | 2010 | bash / zsh 함수. macOS / Linux 표준 격. |
| nvm-windows (coreybutler) | 2014 | Go 작성. nvm 의 Windows 포트 (별개 프로젝트). |
| fnm (Schniz) | 2018 | Rust. 빠른 셸 진입. 크로스플랫폼. |
| Volta (LinkedIn) | 2019 | Rust. package.json 의 "volta" 필드로 프로젝트별 핀. |
| Corepack | 2021 (Node 16.10+) | Node 동봉. 패키지 매니저 (pnpm / yarn) 자체 버전 관리. |
4. Python
| 도구 | 출시 | 특징 |
|---|---|---|
| pyenv (yyuu) | 2012 | rbenv 영감. shim 방식. macOS / Linux. |
| pyenv-win | 2018 | Windows 포트. |
| uv python | 2024 | uv 가 Python 인터프리터 자체도 받아 둠. |
5. JVM
| 도구 | 출시 | 특징 |
|---|---|---|
| SDKMAN! | 2012 | sdkman.io. Java / Kotlin / Gradle / Maven 등 JVM 도구 다수. macOS / Linux / WSL. |
| jenv | 2014 | macOS / Linux 에서 이미 설치된 JDK 들 사이를 전환. |
| jabba | 2017 | 크로스플랫폼. |
6. 다중 언어
| 도구 | 출시 | 특징 |
|---|---|---|
| asdf (asdf-vm) | 2014 | 플러그인 기반. Node · Python · Ruby · Java 등 통합. |
| mise (jdx) | 2023 | 원래 rtx. Rust. asdf 호환 + 환경변수 · 태스크 러너. |
7. Windows 특수
- Scoop (2013) · winget (Microsoft, 2020) — OS 수준 패키지 매니저. 버전 매니저 자체를 설치하기 좋은 진입점이지만, 한 시점에 한 버전을 설치하는 도구라 다중 버전 격리는 위 매니저들의 역할.
- Chocolatey (2011) — 비슷한 위치. winget 등장 이후 점유는 옮겨가는 추세.
8. 자주 쓰는 모양
# nvm (macOS · Linux)
nvm install 20
nvm use 20
echo "20" > .nvmrc
nvm use # .nvmrc 자동 적용
# nvm-windows (PowerShell)
nvm install 20.10.0
nvm use 20.10.0
nvm list
# pyenv
pyenv install 3.12.5
pyenv local 3.12.5 # .python-version 작성
python --version
# SDKMAN! (macOS · Linux · WSL)
sdk install java 21.0.4-tem
sdk use java 21.0.4-tem
sdk list java
# mise (크로스플랫폼)
mise use node@20 python@3.12 java@21
cat .tool-versions
.tool-versions 한 파일에 여러 도구 버전을 적는 형식은 asdf 가 정착시켰고 mise 가 호환.
9. 자주 걸리는 자리
시스템 PM + 버전 매니저 충돌 — 시스템 패키지 매니저로 설치한 런타임과 버전 매니저로 설치한 런타임이 PATH 에 섞여 있는 경우. which python · Get-Command python 로 어느 바이너리가 잡히는지 확인.
nvm 은 bash 함수 — bash 를 거치지 않는 환경 (일부 IDE 의 통합 터미널 · GUI 런처) 에서 nvm: command not found. shim 방식의 fnm 이나 Volta 가 이 점에서 마찰이 적음.
nvm-windows 자동 전환 — 디렉터리별 자동 전환을 기본으로 지원하지 않음 (외부 도우미 필요). fnm 은 이 부분을 처리.
pyenv 의 빌드 — 소스에서 컴파일이라 OS 헤더 (build-essential · Xcode CLT · openssl-dev) 필요. uv 의 Python 설치는 미리 빌드된 인터프리터를 받아 와 이 문제를 비킴.
SDKMAN! 의 셸 rc — 진입 스크립트를 추가. 비대화형 셸이나 CI 에서는 명시적 source $SDKMAN_INIT 가 필요할 때.
글로벌 npm 패키지 — Node 버전이 바뀌면 새 버전의 prefix 에는 비어 있음. 도구가 갑자기 사라진 것처럼 보일 수 있음.
하고픈 말
여러 프로젝트를 동시에 다루는 자리에서는 버전 매니저가 거의 필수. Node 는 fnm (또는 Volta), Python 은 uv 의 인터프리터 관리 (또는 pyenv), JVM 은 SDKMAN!, 모두 다루는 한 도구로는 mise 가 자주 거론됩니다. 셸 진입 시 자동 전환 + 프로젝트별 핀 (.nvmrc · .python-version · .tool-versions) 두 가치가 핵심.
Next
- git-workflow
- gradle
nvm GitHub · nvm-windows GitHub · fnm GitHub · pyenv GitHub · SDKMAN! · asdf 공식 문서 · mise 공식 문서 · Volta 공식 문서 · Corepack 문서 · Scoop · winget 을 참고합니다.