
안녕하세요, JavaScript와 Node.js 생태계에서 개발하고 계신 모든 분들! 우리는 프로젝트를 시작할 때마다 거의 항상 패키지 매니저와 마주하게 됩니다. package.json 파일과 node_modules 디렉토리는 우리에게 너무나도 익숙하죠. 오랫동안 Node.js의 기본 패키지 매니저였던 npm이 시장을 지배했지만, 그 단점을 보완하기 위해 yarn이 등장했고, 최근에는 pnpm이 혁신적인 방식으로 주목받고 있습니다.
"그래서, 도대체 뭘 써야 하는 건데?" 라는 고민을 한 번쯤 해보셨을 겁니다. 오늘은 이 세 가지 패키지 매니저의 특징, 장단점을 심도 있게 비교 분석하여 여러분의 다음 프로젝트에 가장 적합한 도구를 선택할 수 있도록 도와드리겠습니다!
npm은 Node.js를 설치하면 자동으로 설치되는 사실상의 표준 패키지 매니저입니다. 가장 오래되었고, 가장 거대한 생태계를 자랑하죠.
장점:
압도적인 인지도와 자료: 문제가 발생했을 때 해결책을 찾기 가장 쉽습니다. 대부분의 문서와 튜토리얼이 npm을 기준으로 작성되어 있습니다.
기본 내장: 별도의 설치 과정이 필요 없어 접근성이 매우 뛰어납니다.
지속적인 개선: 과거의 느린 속도와 비효율적인 node_modules 구조 문제를 해결하기 위해 버전 5부터 package-lock.json을 도입하고, 버전 7부터는 workspaces를 정식 지원하는 등 꾸준히 발전하고 있습니다.
단점:
의존성 관리: 과거 버전(v3 이전)의 중첩된 node_modules 구조는 매우 비효율적이었고, 현재의 평탄화된 구조는 "유령 의존성(Phantom Dependencies)" 문제를 야기할 수 있습니다. (package.json에 명시되지 않은 패키지에 접근 가능한 문제)
속도와 효율성: yarn이나 pnpm에 비해 설치 속도나 디스크 공간 효율성 측면에서 여전히 아쉬운 부분이 있습니다.
# 패키지 설치
npm install <package_name>
# 개발 의존성 설치
npm install <package_name> --save-dev
# 전역 설치
npm install -g <package_name>
Yarn은 npm의 속도, 일관성, 보안 문제를 해결하기 위해 Facebook(현 Meta)에서 개발했습니다. 등장 초기, 병렬 설치와 yarn.lock 파일을 통한 일관성 있는 의존성 관리로 큰 인기를 끌었습니다.
장점:
빠른 속도: 여러 패키지를 동시에 다운로드하는 병렬 처리 덕분에 npm보다 월등히 빠른 설치 속도를 보여주었습니다.
안정적인 의존성: yarn.lock 파일을 통해 모든 개발 환경에서 동일한 버전의 패키지를 설치하도록 보장하여 "내 컴퓨터에선 됐는데..." 문제를 방지합니다.
Workspaces: 모노레포(Monorepo) 관리를 위한 workspaces 기능을 초창기부터 강력하게 지원했습니다.
Yarn Berry (v2+):
Yarn은 버전 2부터 Plug'n'Play(PnP)라는 혁신적인 전략을 도입했습니다. 이는 node_modules 디렉토리 자체를 생성하지 않고, .pnp.cjs 파일에 패키지 위치 정보를 저장하여 디스크 공간을 절약하고 설치 속도를 극대화하는 방식입니다. 하지만 일부 오래된 도구들과의 호환성 문제가 단점으로 지적되기도 합니다.
# 패키지 추가
yarn add <package_name>
# 개발 의존성 추가
yarn add <package_name> --dev
# 전역 추가
yarn global add <package_name>
pnpm (performant npm)은 이름에서부터 성능에 대한 자신감이 엿보입니다. pnpm의 핵심 철학은 디스크 공간 절약과 엄격한 의존성 관리입니다.
핵심 특징: 콘텐츠 주소 지정 저장소 (Content-addressable store)
pnpm은 패키지를 프로젝트의 node_modules에 직접 복사하지 않습니다. 대신, 시스템의 특정 위치(.pnpm-store에) 패키지를 한 번만 저장하고, 각 프로젝트에서는 이 저장소에 있는 파일로 연결되는 심볼릭 링크(Symbolic Link) 또는 하드 링크(Hard Link)를 사용합니다.
장점:
압도적인 디스크 공간 효율성: 여러 프로젝트에서 동일한 버전의 패키지를 사용하더라도 실제 파일은 디스크에 단 하나만 존재합니다.
매우 빠른 설치 속도: 이미 다운로드한 패키지는 다시 받을 필요 없이 링크만 생성하므로, 캐시를 활용한 설치 속도가 매우 빠릅니다.
유령 의존성 원천 차단: node_modules가 평탄하지 않고, package.json에 명시된 패키지만 직접 접근할 수 있는 구조를 만들어 의도치 않은 패키지 사용을 막습니다.
단점:
생소한 node_modules 구조: 심볼릭 링크 기반의 구조가 익숙하지 않은 개발자에게는 다소 혼란스러울 수 있습니다. (하지만 대부분의 경우 개발자가 직접 이 구조를 건드릴 일은 없습니다.)
일부 도구 호환성: 과거에는 심볼릭 링크를 제대로 처리하지 못하는 일부 도구와 문제가 있었으나, 현재는 대부분 해결되었습니다.
# 패키지 추가
pnpm add <package_name>
# 개발 의존성 추가
pnpm add <package_name> -D
# 전역 추가
pnpm add -g <package_name>
| 특징 | npm | Yarn (Classic) | pnpm | Yarn (Berry) |
|---|---|---|---|---|
| 설치 속도 | 보통 | 빠름 | 매우 빠름 | 매우 빠름 |
| 디스크 공간 | 높음 | 높음 | 매우 효율적 | 매우 효율적 |
| 의존성 관리 | 유령 의존성 가능 | 유령 의존성 가능 | 엄격함 | 매우 엄격함 (PnP) |
| 인지도/자료 | 매우 높음 | 높음 | 증가 추세 | 보통 |
| 모노레포 지원 | O (v7+) | O (강력) | O (강력) | O (강력) |
workspaces 기능이 중요한 프로젝트, PnP의 이점을 활용하고 싶은 모던 프로젝트 (단, 호환성 체크 필요)과거에는 npm의 대안으로 yarn이 각광받았다면, 현재는 pnpm이 가장 진보하고 효율적인 패키지 매니저로 평가받고 있습니다. Vite, Vue, Next.js 등 수많은 대형 오픈소스 프로젝트들이 기본 패키지 매니저로 pnpm을 채택하고 있는 것이 그 증거입니다.
물론 어떤 도구를 선택할지는 프로젝트의 특성과 팀의 선호도에 따라 달라질 수 있습니다. 하지만 아직 pnpm을 경험해보지 않으셨다면, 다음 프로젝트에서는 꼭 한번 사용해보시는 것을 강력히 추천합니다. node_modules의 공포에서 해방되고, 놀라운 속도와 효율성을 체감하게 될 것입니다!
로그인 후 댓글을 작성할 수 있습니다.