NVM 설치: Mac Silicon에서 Node.js 버전 관리하는 방법

요약

Mac에서 Node.js를 처음 설치할 때는 brew install node로도 충분해 보입니다. 그런데 프로젝트가 두세 개만 쌓여도 금방 문제가 생깁니다. 어떤 프로젝트는 Node 18을 요구하고, 어떤 프로젝트는 Node 22 이상에서만 정상 동작합니다.

이럴 때 매번 Node.js를 지웠다 다시 설치할 수는 없습니다. 보통은 NVM으로 Node 버전을 나눠 관리합니다. 특히 Mac Silicon 환경에서는 zsh 설정, arm64 지원, 오래된 Node 버전의 Rosetta 이슈만 알고 있으면 어렵지 않게 사용할 수 있습니다.

목차

배경

Node.js 버전 문제는 생각보다 자주 나옵니다.

예를 들어 기존 프로젝트는 Node 18에서 돌아가는데, 새 프로젝트는 Node 22나 24를 요구할 수 있습니다. 이 상태에서 시스템 Node 하나만 쓰면 npm install은 됐는데 빌드가 깨지거나, 반대로 빌드는 되는데 특정 패키지가 동작하지 않는 일이 생깁니다.

NVM(Node Version Manager)은 이런 상황에서 Node.js 버전을 프로젝트별로 바꿔 쓸 수 있게 해주는 도구입니다.

# 프로젝트 A
nvm use 18

# 프로젝트 B
nvm use 24

이런 식으로 버전을 바꿔가며 사용할 수 있습니다.

이 글에서 확인한 기준

설치 방법은 오래된 블로그 글과 현재 공식 문서가 조금씩 다를 수 있습니다. 그래서 이번 글은 아래 자료를 기준으로 다시 확인했습니다.

확인한 자료 확인한 내용
nvm 공식 README 설치 스크립트, zsh 설정, .nvmrc, LTS 명령
nvm GitHub Releases 최신 nvm 릴리스 v0.40.5
Node.js 공식 다운로드 페이지 현재 LTS와 Current 버전 흐름
Node.js 릴리스 정책 Active LTS, Maintenance LTS, EOL 개념
Apple Support macOS Catalina 이후 zsh 기본 셸
Homebrew 공식 문서 Apple Silicon의 Homebrew 경로 /opt/homebrew
Volta/fnm 공식 문서 nvm 대안 도구 비교

세부 내용

1단계. 현재 셸과 CPU 아키텍처 확인

Mac Silicon이라면 보통 기본 셸은 zsh입니다. 먼저 현재 셸을 확인합니다.

echo $SHELL

정상적인 Mac 기본 환경이라면 대개 이렇게 나옵니다.

/bin/zsh

CPU 아키텍처도 확인합니다.

uname -m

Mac Silicon이면 보통 아래처럼 나옵니다.

arm64

여기까지 확인했다면, 이후 설정 파일은 대부분 ~/.zshrc 기준으로 보면 됩니다.

2단계. NVM 설치

nvm 공식 README 기준으로 설치합니다. 글 작성 시점 기준 최신 릴리스는 v0.40.5입니다.

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash

wget을 쓰는 환경이라면 아래 명령도 가능합니다.

wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash

설치 스크립트는 보통 ~/.nvm 디렉터리를 만들고, 셸 설정 파일에 nvm 로딩 코드를 추가합니다.

3단계. 터미널 다시 열기 또는 zsh 설정 로드

설치 직후 바로 nvm 명령을 쳤는데 안 나오는 경우가 있습니다. 이건 설치가 실패했다기보다, 아직 ~/.zshrc가 다시 로드되지 않은 경우가 많습니다.

source ~/.zshrc

또는 터미널을 완전히 닫고 다시 열어도 됩니다.

설치 확인은 아래 명령으로 합니다.

command -v nvm

정상이라면 이렇게 나옵니다.

nvm

4단계. zsh 설정 확인

~/.zshrc에 아래 내용이 들어갔는지 확인합니다.

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

nvm 공식 README에서는 $XDG_CONFIG_HOME을 고려한 설정도 안내합니다.

export NVM_DIR="$([ -z "${XDG_CONFIG_HOME-}" ] && printf %s "${HOME}/.nvm" || printf %s "${XDG_CONFIG_HOME}/nvm")"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

개인 Mac 개발 환경이라면 첫 번째 방식으로 충분한 경우가 많습니다. 회사에서 dotfiles나 공통 셸 설정을 관리한다면 두 번째 방식까지 확인하면 됩니다.

5단계. Node.js LTS 설치

새 프로젝트라면 보통 LTS 버전부터 설치하는 게 안전합니다.

nvm install --lts

설치 후 버전을 확인합니다.

node -v
npm -v

현재 설치한 버전을 기본값으로 쓰고 싶다면 아래처럼 지정합니다.

nvm alias default node

특정 버전을 기본으로 고정하고 싶다면 버전 숫자를 적어도 됩니다.

nvm alias default 24

6단계. 프로젝트별 .nvmrc 만들기

실무에서는 이 부분이 제일 중요합니다. 프로젝트 루트에 .nvmrc를 만들어두면, 팀원들이 같은 Node 버전을 쓰기 쉬워집니다.

예를 들어 Node 24를 쓰는 프로젝트라면 .nvmrc 파일에 이렇게 적습니다.

24

LTS 최신 버전을 따라가고 싶다면 이렇게 쓸 수도 있습니다.

lts/*

프로젝트 폴더에서 아래 명령을 실행합니다.

nvm install
nvm use

이렇게 해두면 README에도 간단히 안내할 수 있습니다.

nvm install
nvm use
npm install

Node 버전이 안 맞아서 생기는 빌드 오류는 생각보다 많습니다. .nvmrc 하나만 커밋해도 팀원 간 환경 차이를 꽤 줄일 수 있습니다.

7단계. 폴더 이동 시 자동으로 nvm use 실행하기

매번 nvm use를 치는 게 귀찮다면 zsh hook을 사용할 수 있습니다.

autoload -U add-zsh-hook

load-nvmrc() {
  local node_version="$(nvm version)"
  local nvmrc_path="$(nvm_find_nvmrc)"

  if [ -n "$nvmrc_path" ]; then
    local nvmrc_node_version="$(nvm version "$(cat "$nvmrc_path")")"

    if [ "$nvmrc_node_version" = "N/A" ]; then
      nvm install
    elif [ "$nvmrc_node_version" != "$node_version" ]; then
      nvm use
    fi
  elif [ "$node_version" != "$(nvm version default)" ]; then
    nvm use default
  fi
}

add-zsh-hook chpwd load-nvmrc
load-nvmrc

다만 이 설정은 호불호가 있습니다. 폴더를 이동할 때마다 출력이 나오거나, 터미널 시작이 살짝 느려질 수 있습니다. 개인 개발 환경에서 써보고 불편하면 빼는 정도로 생각하면 됩니다.

Mac Silicon에서 Rosetta가 필요한 경우

최신 Node.js LTS를 쓴다면 보통 Rosetta를 신경 쓸 일이 없습니다. nvm 공식 문서에 따르면 Node.js는 v16.0.0부터 Apple Silicon용 arm64 Darwin 바이너리를 제공합니다.

문제가 되는 건 오래된 Node 버전입니다.

Node.js 버전 Mac Silicon에서의 의미
Node.js 16 이상 arm64 Darwin 바이너리 사용 가능
Node.js 14.17 이상 소스 컴파일 기준 experimental arm64 지원 언급
오래된 Node.js 14 이하 Rosetta 2 또는 x86_64 환경이 필요할 수 있음

현재 Node가 어떤 아키텍처로 실행 중인지 확인하려면 아래 명령을 사용합니다.

node -p "process.arch"

Mac Silicon에서 arm64 Node가 실행 중이면 이렇게 나옵니다.

arm64

Homebrew로 nvm을 설치해도 될까?

결론부터 말하면 권장하지 않습니다. nvm 공식 README에서는 Homebrew 설치를 지원하지 않는다고 안내합니다.

Homebrew에 nvm 패키지가 보일 수는 있습니다. 하지만 문제가 생겼을 때 공식 nvm 프로젝트는 Homebrew 설치본이 아니라 공식 설치 스크립트 방식으로 재설치한 뒤 확인하라고 안내합니다.

그래서 nvm은 아래 방식으로 설치하는 편이 낫습니다.

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.5/install.sh | bash

Homebrew는 다른 개발 도구 설치에는 편합니다. 다만 nvm만큼은 공식 설치 방식을 따르는 편이 덜 헷갈립니다.

Volta, fnm과 비교

Node 버전 관리 도구는 nvm만 있는 건 아닙니다. 새로 팀 표준을 정하는 상황이라면 Volta나 fnm도 같이 볼 만합니다.

도구 특징 이런 경우에 적합
nvm 가장 널리 쓰이는 셸 기반 Node 버전 관리자 기존 자료가 많고 .nvmrc 호환이 중요할 때
Volta Node, npm, yarn, pnpm 같은 도구 버전 고정에 강함 팀 단위로 JS 도구 버전을 강하게 맞추고 싶을 때
fnm Rust 기반이라 빠르고 .nvmrc도 지원 nvm과 비슷하게 쓰되 속도를 중시할 때

개인 개발 환경이라면 nvm으로 시작해도 충분합니다. 팀 단위라면 어떤 도구를 쓰든 README와 CI 설정까지 같이 맞춰야 합니다.

모범 사례

프로젝트에는 .nvmrc를 커밋한다

.nvmrc는 작지만 효과가 큽니다. 특히 프론트엔드 프로젝트나 Node 기반 백엔드 프로젝트에서는 Node 버전 하나 때문에 설치 오류가 나는 경우가 많습니다.

24

이 파일을 프로젝트 루트에 두고 Git에 커밋합니다.

README에 실행 순서를 적어둔다

처음 프로젝트를 받은 사람이 바로 따라 할 수 있게 README에 아래 정도는 적어두는 것이 좋습니다.

nvm install
nvm use
npm install
npm run dev

이 정도만 있어도 온보딩할 때 덜 헤맵니다.

CI와 로컬 Node 버전을 맞춘다

로컬은 Node 24인데 CI가 Node 20이면 결과가 다를 수 있습니다. GitHub Actions나 Jenkins에서 사용하는 Node 버전도 .nvmrc와 맞추는 편이 안전합니다.

오래된 Node 버전은 이유를 남긴다

Node 14나 16처럼 오래된 버전을 계속 써야 한다면 이유를 남겨두는 것이 좋습니다. 단순히 “예전부터 이렇게 써서”가 아니라, 특정 패키지 호환성이나 운영 환경 제약이 있는지 정리해두면 나중에 업그레이드할 때 도움이 됩니다.

흔한 실수

nvm 설치 후 command not found가 나온다

가장 흔한 케이스입니다. 설치가 안 된 게 아니라 셸 설정이 아직 적용되지 않았을 가능성이 큽니다.

source ~/.zshrc
command -v nvm

그래도 안 되면 ~/.zshrcNVM_DIR 설정이 들어갔는지 확인합니다.

.zshrc가 아니라 다른 파일에 설정이 들어갔다

nvm 설치 스크립트는 ~/.bashrc, ~/.bash_profile, ~/.zshrc, ~/.profile 중 하나를 자동으로 고르려고 합니다. 가끔 원하는 파일이 아닌 곳에 설정이 들어가기도 합니다.

Mac에서 zsh를 쓰고 있다면 우선 ~/.zshrc를 확인하세요.

cat ~/.zshrc

Homebrew Node와 nvm Node가 섞인다

예전에 brew install node로 설치한 Node가 남아 있으면 which node 결과가 예상과 다를 수 있습니다.

which node
node -v

nvm Node를 사용 중이라면 대체로 경로에 .nvm이 포함됩니다.

/Users/사용자명/.nvm/versions/node/v24.x.x/bin/node

.nvmrc만 만들고 nvm use를 안 한다

.nvmrc 파일을 만들었다고 자동으로 버전이 바뀌는 것은 아닙니다. 자동 전환 설정을 하지 않았다면 직접 실행해야 합니다.

nvm use

VS Code 터미널과 일반 터미널의 Node 버전이 다르다

일반 터미널에서는 nvm이 되는데 VS Code 터미널에서는 안 되는 경우가 있습니다. 이때는 VS Code의 기본 셸이 zsh인지, 그리고 ~/.zshrc가 제대로 로드되는지 확인해야 합니다.

echo $SHELL
command -v nvm
node -v

실패 사례와 해결

사례 1. 설치했는데 nvm: command not found가 나온다

가장 많이 나오는 케이스입니다. 공식 README와 Stack Overflow 사례를 보면, 대개 설치 실패가 아니라 셸 설정이 아직 로드되지 않은 문제입니다.

먼저 새 터미널을 열거나 아래 명령을 실행합니다.

source ~/.zshrc
command -v nvm

그래도 아무것도 나오지 않으면 ~/.zshrc에 nvm 로딩 코드가 들어갔는지 확인합니다.

grep NVM_DIR ~/.zshrc

설정이 없다면 아래 내용을 추가합니다.

export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"

저장 후 다시 로드합니다.

source ~/.zshrc

여기서 중요한 점은 which nvm보다 command -v nvm을 쓰는 편이 낫다는 것입니다. nvm은 일반 실행 파일이 아니라 셸 함수로 로드되기 때문입니다.

사례 2. VS Code 터미널에서만 nvm이 안 된다

일반 터미널에서는 nvm이 되는데 VS Code 터미널에서만 안 되는 경우가 있습니다. 이 경우는 VS Code가 열고 있는 셸이나 프로필 설정이 일반 터미널과 다를 가능성이 큽니다.

VS Code 터미널에서 먼저 확인합니다.

echo $SHELL
command -v nvm
node -v

일반 터미널에서도 같은 명령을 실행해 결과를 비교합니다.

echo $SHELL
command -v nvm
node -v

둘의 결과가 다르면 VS Code에서 Terminal: Select Default Profile을 실행해 기본 터미널을 zsh로 맞추는 쪽부터 확인합니다. 그래도 안 되면 VS Code 터미널이 ~/.zshrc를 제대로 읽고 있는지 확인해야 합니다.

사례 3. Homebrew Node와 nvm Node가 섞인다

예전에 brew install node로 Node.js를 설치해둔 상태에서 nvm을 설치하면 경로가 헷갈릴 수 있습니다. 이때는 node -v만 보면 부족하고, 실제 어떤 Node가 실행되는지 봐야 합니다.

which node
node -v
npm -v

nvm Node를 쓰고 있다면 보통 경로에 .nvm이 들어갑니다.

/Users/사용자명/.nvm/versions/node/v24.x.x/bin/node

반대로 Homebrew Node가 잡히면 Apple Silicon 기준으로 대개 /opt/homebrew 경로가 보입니다.

/opt/homebrew/bin/node

이 경우에는 어떤 방식을 쓸지 정해야 합니다. 프로젝트별 버전 관리를 nvm으로 할 거라면, 터미널 초기화 후 nvm use가 제대로 적용되는지부터 확인하세요.

nvm use
which node

무조건 Homebrew Node를 지울 필요는 없지만, 두 방식이 섞인 상태를 모른 채 두면 나중에 npm install이나 빌드 오류를 추적하기가 어려워집니다.

사례 4. .nvmrc가 있는데 Node 버전이 자동으로 안 바뀐다

.nvmrc는 자동 전환 기능이 아니라 “이 프로젝트는 이 Node 버전을 쓴다”는 표시입니다. 자동 전환 설정을 하지 않았다면 직접 실행해야 합니다.

nvm install
nvm use

자동 전환까지 원하면 zsh hook을 추가해야 합니다. 다만 이 설정은 모든 사람에게 필요한 건 아닙니다. 터미널 이동 때마다 출력이 생기는 걸 싫어하는 사람도 있어서, 팀 공통 규칙으로 강제하기보다는 개인 선택으로 두는 편이 무난합니다.

사례 5. 오래된 Node 버전 설치에서 Mac Silicon 문제가 난다

최신 LTS 버전은 대체로 arm64로 잘 설치됩니다. 문제는 오래된 Node.js 버전입니다. nvm 공식 문서에 따르면 Node.js는 v16.0.0부터 Apple Silicon용 arm64 Darwin 바이너리를 제공합니다.

오래된 프로젝트 때문에 Node 14 이하를 써야 한다면 Rosetta나 x86_64 환경이 필요할 수 있습니다. 먼저 현재 아키텍처부터 확인합니다.

uname -m
node -p "process.arch"

가능하다면 프로젝트를 LTS 버전으로 올리는 쪽이 좋습니다. 정말 오래된 Node 버전이 필요하다면 그 이유를 README에 남겨두세요. 나중에 누군가 같은 문제를 다시 만나게 됩니다.

결론

Mac Silicon에서 nvm을 쓰는 것 자체는 이제 크게 어렵지 않습니다. 최신 Node.js LTS를 설치한다면 Rosetta를 먼저 떠올릴 필요도 거의 없습니다.

실제로 자주 막히는 부분은 설치보다 셸 설정입니다. nvm 명령이 안 잡힌다면 Node 문제가 아니라 ~/.zshrc가 로드되지 않았거나, 설정이 다른 프로필 파일에 들어간 경우가 많습니다.

개인 개발 환경이라면 nvm으로 시작해도 충분합니다. 팀 프로젝트라면 .nvmrc를 커밋하고, README와 CI의 Node 버전까지 같이 맞춰두세요. 이 작은 정리가 나중에 빌드 오류를 꽤 많이 줄여줍니다.

참고 자료

  • nvm GitHub README — https://github.com/nvm-sh/nvm
  • nvm latest release — https://github.com/nvm-sh/nvm/releases/latest
  • Node.js Downloads — https://nodejs.org/en/download
  • Node.js Releases — https://nodejs.org/en/about/previous-releases
  • Apple Support: Use zsh as the default shell on your Mac — https://support.apple.com/en-us/102360
  • Homebrew Official Site — https://brew.sh/
  • Volta Official Site — https://volta.sh/
  • fnm GitHub README — https://github.com/Schniz/fnm