제목 : Yarn 과 pnpm 패키지 매니저는 무엇인가?
이 글을 작성하는 이유
방대한 JavaScript 기반의 패키지 레지스터를 보유하고 있는 장소가 바로 NPM 이다.
JavaScript 는 언어 자체로 IO(Input Output) 빌트인 메서드가 간단하며,
또한 표현식이 간단하여 프로그래머들의 진입 언어로 매우 유용하게 사용되고 있다.
그런 만큼, 그 커뮤니티의 크기는 감히 말할 수 없을 정도로 커졌으며,
언어 자체가 가지고 있던 성능의 한계를 다양한 내장 메서드 최적화,
재사용 코드 캐싱 등의 기능으로 돌파하고 있다. (그래도 저레벨 언어에 비해서는 한계가 있지만.)
npm 은 JavaScript 기반의 템플릿 프로젝트를 만들기 위해서 필수적인 요소이다.
주로 프로젝트 루트에 package.json
을 생성하여 내부에 모듈을 설치하기 위한 설정파일을 만들거나,
로컬 컴퓨터에 node, npm 패키지가 설치되어 있으면, 간단하게 npm i ...
로 설치 할 수 있다.
package-lock.json
은 설치된 의존성의 상세한 레지스터 주소 뿐 만 아니라,
이 패키지를 설치하기 위한 또 다른 필요 의존성을 거론한다.
그런데, NPM 의 부족한 특성으로 인해 다른 Node 패키지 매니저인
- Yarn
- PNpm(정식 이름)
이러한 프로그램이 나오게 되었다.
Yarn 은 자주 사용하는 사람들이 있던데, PNpm 은 왜 사용하는 건지 의문이 들었다.
NPM 은 겹치는 의존성 관리, 혹은 느린 의존성 파악, 보안, 등등 여러 부족한 부분을 보완하여
나머지 패키지 매니저들과 비슷한 부분까지 도달했다고 들었다.
그렇다면 나머지 패키징 매니저들은 현재 어떤 포지션으로 여전히 개발자들을 돕고 있을지 매우 궁금해졌다.
특히, 아직 Yarn 을 사용하는 프론트엔드 개발자들이 존재하여 이를 알아둘 필요가 있다고 판단되었다.
그리고 각자 나머지 패키지들보다 우세한 점을 공식 홈페이지에서 거론하고 있기 때문에,
공식 문서를 2 순위로 정하고, 위키백과에 나온 상대적으로 객관적인 내용을 1순위로 보기로 했다.
2025-07 기준, NPM > Yarn > pnpm 순으로 사용되고 있다.
Yarn 이란 무엇인가?
역시 React 의 시초인 회사라고 해야 할까.
Yarn 이란, 페이스북이 2016년 Node.js 기반의 자바스크립트 런타임 환경을 위해
개발한 소프트웨어 패키지 시스템이라고 한다.
대형 코드의 일관성, 보안, 성능 문제를 해결하기 위해 개발되었다.
위키백과에 NPM 과의 비교 가 적혀있기에, 적절한 것 같아 내용을 넣어보자면,
- Yarn 은 로컬 캐시로부터 패키지를 설치한다.
- Yarn 은 패키지 버전을 강력하게 바인딩한다.
- Yarn 은 데이터 무결성 보장을 위해 Checksum 을 사용하며, npm 은 sha-512 를 사용한다.
- Yarn 은 병렬로 패키지를 설치하며, npm 은 하나의 패키지씩 설치한다.
위에까지가 위키백과의 설명이지만, 여태까지 공식문서를 읽어온 내 입장에서,
오랜 역사를 가진 프로그램이 아니라면, 최신 프로그램에 대한 정보 변질이 발생하는 경우가 많았다.
따라서, 공식 문서를 읽으며 다른 추가 정보와 기능들을 더 살펴보기로 결정했다.
소개 항목을 요약하자면, 오픈소스이며, 자바스크립트 프로젝트 의존성을 관리하는데 사용된다.
Yarn 은 속도, 정확성, 보안, 그리고 개발자 경험에 초점을 맞추고 있으며,
작업 공간, 오프라인 캐싱, 병렬 설치, 강화 모드, 대화형 명령 등 혁신적인? 기능을 활용하여
모든 방향을 향상시키고 있다고 한다.
흠... 일단 현재로서 알 수 있는 것은, 작업 공간, 병렬 설치, 대화형 명령이다.
오프라인 캐싱과 강화 모드에 대해선 모르겠다.
- 작업 공간 : 만약에 다른 로컬 개발 환경에서 의존성을 설치한다면,
해당 의존성 모듈이 이미 전역 공간에 저장되어 있는지 확인하고, 없다면 다운로드 한다.
즉, 컴퓨터 자체에 모듈을 저장해 두고, 동일한 모듈을 다른 프로젝트에서 사용한다면,
공간 아깝게 또 모듈을 개별적으로 설치하지 않고, "참조" 하겠다는 의미
- 병렬 설치 : 하나씩 모듈을 설치하는 npm 과는 다르게,
네트워크 요청을 병렬로 수행하여 이를 동시에 다운로드 받겠다는 의미.
- 대화형 명령 : 기존 npm 보다 더 "유연한" 명령어 체계를 갖췄다는 의미이다.
따라서, 미리 공식 문서를 읽어 봤는데,
Hardened Mode (강화 모드) 라는 "Mode" 에 대한 설명이 없다.
즉, 이건 공식 문서 상에서 특정 기능을 추상화 한 설명이라는 추측이 들었다.
Yarn 오프라인 캐싱(offline caching 이란?)
기본적으로 영문서를 번역하기 때문에, 문서를 읽기 복잡한 분은 제가 작성하는 요약본을 보셔도 좋습니다!
요약 :
오프라인 캐싱이라는 개념을 알기 위해서, Yarn 이 주장하는 캐싱 전략 문서를 살펴봐야 한다.
이 개념에 강력하게 연관된 것은, 바로 "작업 공간" 즉, "Workspace" 이다.
Yarn 은 확실히 npm 패키지 매니저를 뒤이어 강력한 툴체인으로 거듭날 만한 것이, 바로,
모듈을 전역으로 저장하여 재사용한다는 것이다.
캐싱의 2 가지 전략. Offline Mirror and Zero Installs
[Offline-Mirror]
자바스크립트 프로젝트를 생성하고, 현재까지 설치된 모듈의 목록을 같은 팀원들에게 전달하는 것은
어렵지 않다. 그러나, 여태까지 알려진 경험으로서 NPM 에서 모듈을 다운로드 할 때, 종종
설치에 실패하는 이슈가 발생 해 왔다.
이러한 모듈 설치 실패 자체는 개발에 영향을 끼쳐 현재 개발중인 프로젝트의 Git 버전을
롤백하거나, 브랜치를 스위칭해야하는 등, CI/CD 면에서 여러 제약이 걸린다.
그러나, Yarn 에서는 이러한 상황을 막고 "확실한" 설치를 보장하기 위해 밑의 기능을 제공한다.
enableGlobalCache
라는 항목을 false
로 설정하면, 패키지 설치 모듈 캐시를
직접 프로젝트 루트 폴더 내의 .yarn/cache
에 저장한다.
그리고, Git 에 저장한다.
이러한 방식으로 구성하면, 모든 커밋이 설치에 실패하지 않는 커밋이라고 보장할 수 있다.
심지어, 해당 npm 레지스트리가 망가진다 할 지언정.
이러한 패턴을 "Offline Mirror" 이라는 패턴으로 부른다.
[Zero-Installs]
이게 위의 Offline-Mirror 과 다른 상반되는 전략이라고 생각했는데,
다른 카테고리의 캐싱 전략을 의미한다는 것을 알고 봐야 한다.
Yarn PnP(Plug and Play 약자) 와 Offline-Mirror 기능을 조합한 캐싱 전략으로,
브랜치를 이동할 때 마다, 굳이 yarn install
할 필요 없이, 그대로 프로젝트를 가동하는 것이다.
이게 어떻게 가능한가? 보니, PnP 는 로컬 머신에 설치되었던 모듈을 캐싱하며,
Offline Mirror 은 npm 레지스트리에 의존하지 않고 내부 .yarn/cache
에 의존한다.
이 둘을 조합하여 따로 Yarn Install 하지 않고도, 둘의 의존성을 Yarn 로더가 알아서 파악하여
yarn install
을 한 것과 같은 효과를 낸다는 것이다.
확실히, 팀 프로젝트를 진행하면 수많은 브랜치들이 갈라져 나오게 되는데,
변경사항이 생길 때 마다 추가 모듈을 적용하기 위해 npm i
하는 것은 불편한 일이기도 하다.
그런데, Yarn 은 내부적으로 Yarn PnP 그리고, Offline Mirror 를 이용하여
Zero-Install 즉, "모듈 설치 안함" 패턴을 이러한 방식으로 구현한다는 의미이다.
Hardened Mode 란?
NPM 의 package-lock.json
이나, Yarn 에서의 lock-file 은 정확한 레지스트리의 주소를 가르킨다.
그렇다는 것은, 레지스트리의 주소를 바꿔서 스크립트에 직접적인 공격 코드를 주입할 수 있다는 이야기이다.
Yarn 은 이러한 상황을 막기 위해, Hardened Mode 를 만들었다.
enablehardenedMode
를 true 하거나,
셸 자체에 YARN_ENABLE_HARDENED_MODE=1
로 환경 변수를 정의한다면,
lockfile poisoning
이라는 공격 기법을 차단할 수 있다.
PNpm 이란 무엇인가?
굉장히 독특한 게, 개인 유튜버가 자신이 찾은 npm 모듈 시스템의 고질적인 문제를 파악하여,
이에 대응하는 프로그램을 만들어 냈다는 것이다.
1년전 개발자 레딧이 관련 사이트로 나오길래 댓글을 살펴보았는데,
Yarn S**ks.. 라는 굉장한 단어까지 볼 수 있었다..
pnpm 은 npm, yarn 에 비해 굉장히 최신 프로그램이며, 아직도 발전 해 나가고 있는 프로그램이다.
즉, 기업이나 단체에 의해 만들어 진 개념보다는, 개인 + 개발 유튜버 가 만들어 낸 오픈소스라는 데
중점이 있다.
PNpm 이 왜 요즘 트렌드인지 살펴보자.
PNpm 이 나오게 된 계기.
NPM 모듈의 설치는 굉장히 공간을 낭비한다.
아무리 JavaScript 프로젝트의 모듈들이 최소한으로 공간을 저장하도록 노력한다 하더라도,
토이 프로젝트의 모듈 크기 수준이 50~100MB 수준이라면,(프레임워크 수준)
10 ~ 20 개의 프로젝트만 생성해도 1 GB 수준의 저장공간을 사용하는 것이다.
이건 내가 생각해도 정말로 엄청난 공간 낭비인데, pnpm 은 이러한 문제를 극단적으로 해소했다.
즉, 생성하는 프로젝트에 필요한 "모든 의존성" 을, content-addressable
이라는 저장소에
전부 저장하는 것이다.
그리고 해당 프로젝트는, 필요 의존성을 전부 content-addressable
저장소에 "Hard Link" 된다.
만약에, 새로운 버전의 모듈 의존성을 다운받았다고 해도, 해당 의존성에서 필요로 하는 다른 의존성이
1 개인 경우, 저장소에서 "1개" 만 업데이트하고, 나머지 의존성은 동일하므로 다시 하드 링크하는 방식이다.
위의 방식은 평균적인 개인 컴퓨터 저장소인 256 GB 에서 매우 유용하게 사용할 수 있다고 생각된다.
PNpm 만의 독특한 의존성 폴더 구조
위에서는 PNpm 의 하드 링크 방식으로 디스크 공간을 획기적으로 줄이는 방법을 소개했다.
그렇다면, JavaScript 프로젝트에는 의존성을 사용하기 위해 node_modules
를 필요로 하는데,
이를 어떻게 해소했을까?
공식문서에서 가져온 구조를 함께 보자 :
node_modules
└── .pnpm
├── bar@1.0.0
│ └── node_modules
│ └── bar
│ ├── index.js -> <store>/001
│ └── package.json -> <store>/002
└── foo@1.0.0
└── node_modules
└── foo
├── index.js -> <store>/003
└── package.json -> <store>/004
보통 node_modules
디렉토리 아래에는 .pnpm
이 있지 않으며,
bar...
그리고 foo...
가 있을 것이다.
그러나, 폴더 자체를 .pnpm
으로 나누어 확실히 분리했다.
결국, 각각의 모듈들은 내부적으로 필요한 내부 의존성이 있으며,
또한 모듈의 메서드를 한번에 내보내기 위한 index.js
파일이 컨벤션적으로나 일반적으로나 존재한다.
이 때, index.js
와 package.json
을
PNpm 의 content-addressable
저장소에서 참조하여 Symlink 하는 것이다.
NPM 과 나머지 2 개의 패키지 매니저의 비교 (간단)
간단한 설치 시스템을 가진 NPM 과 나머지 패키지 매니저와의 성능 차이는 명백하다.
나머지 매너지들은 "병렬 설치" 뿐만 아니라, 모듈 설치 공간을 따로 마련하여 작업 공간을 아껴주기도 한다.
그럼에도 불구하고, Yarn 과 PNpm 의 차이점은 나의 시각에서 이렇게 보인다.
- Yarn 은 미리 대안 패키지 매니저로서 정착하여 다양한 기업에서 사용한다.
그러나, PNpm 은 아직 성장 중이다.
- Yarn 은 NPM 레지스트리 참조와 전역 모듈 공간 참조를 섞은데 포커싱이 되어 있다면,
PNpm 은 개인 개발자의 로컬 컴퓨팅 경험에 초점을 맞췄다.
- Yarn 은 npm 의 기본 패키지 매니저와 비슷한 구조를 띄지만,
PNpm 은 그 구조부터가 극단적인 효율성을 띈다. (EX - Synlink)
NPM 은 어떻게 대응하고 있는가? (개인적 생각)
NPM 은 기존 레지스트리의 보호와 일관성 측면에서 매우 노력했으며,
나머지 부가적인 기능들을 외부에 외주 맡기듯 기다렸다는 생각이 든다.
결국, Yarn 이나, PNpm 이나, NPM 자체가 보유한 레지스트리가 존재하지 않으면,
필요 가치가 거의 없어지는 프로그램에 가깝기 때문이다.
NPM 에서는 이러한 부가 기능을 가진 외부 프로그램의 기능을 먹어치우는 느낌 보다는,
본연이 가진 레지스트리 저장, 보호, 그리고 새로운 레지스트리 등록에 집중하는 모습을 보인다.
심지어 NPM 공식 유튜브에서조차 외부 프로그램을 사용하여 의존성을 파악하는 영상을 띄울 정도니,
외부 오픈소스에 얼마나 열려있는지 알 수 있는 항목이다.
마무리
각 언어마다 고유한 의존성 레지스트리 장소가 다르며, 그 사용 형태도 명백히 다르다.
JavaScript 는 NPM 이 public 오픈소스 레지스트리 장소로 꼽히며,
그 위세는 전혀 꺾일 것이라고 보이진 않는다.
애초에 모듈을 참조하거나, 내용을 보기 위해 NPM 사이트에서 검색하는데,
해당 모듈을 다시 다른 패키지 매니저에 맞추기 위해 배우는 것은 해당 커뮤니티의 성격에 맞지 않을 수 있기 때문이다.
그러나, 나는 나머지 Package Manager 들의 탄생 목적과 그 기능을 훌륭하다고 말하고 싶다.
로컬 머신에서 개발하는데, 동일한 패키지와 버전을 다운받는데 어떠한 캐싱도 없이,
그대로 다운받아 각 프로젝트에 저장한다는 것은, 큰 용량을 가진 컴퓨터가 아니라면
분명히 한계를 가지는 방법이다.
따라서, NPM 의 방식과 스스로의 방식을 섞은 Yarn,
그리고 극단적인 디스크 용량 절약을 보이는 PNpm 의 방식 둘 다 존중한다.
그리고 사이트를 돌다가 개발자 레딧을 들어가게 되었는데,
PNpm 이 요즈음 트렌드로 올라가고 있는 것 같다.
그러나, 비교적 최신 프로그램이며, 아주 복잡한 기업 프로그램에서 사용될 수 있을지는 미지수라고 생각한다.
기업은 오래되고 불편하더라도 "정확성" 을 매우 중시하기 때문이다.
Yarn 이 가진 고유의 사용자 파이를 먹기 위해서,
PNpm 은 npm 의 불편함을 감수할 수 있는 편리한 방식을 고안해야 할 것이라는 생각도 든다.
참조 사이트
Yarn 공식 홈페이지
PNpm 공식 홈페이지
Yarn 깃허브 페이지
https://github.com/yarnpkg/berry
pnpm 깃허브 페이지
NPM 공식 홈페이지 문서 - (About npm)
https://docs.npmjs.com/about-npm
위키백과 - Yarn
https://ko.wikipedia.org/wiki/Yarn_(%ED%8C%A8%ED%82%A4%EC%A7%80_%EA%B4%80%EB%A6%AC%EC%9E%90)
'Node.js > 잡다 지식' 카테고리의 다른 글
JavaScript 개발자를 위한 스프링, NestJS 에 대해서 (0) | 2025.09.28 |
---|---|
Webpack 이라는 번들러는 무엇일까? (1) | 2025.05.18 |
.http 파일과 httpyac (1) | 2025.05.07 |
Jest 와 유닛 테스트 (4) | 2025.05.05 |
비밀번호는 왜 해싱할까? - With Node.js (0) | 2025.04.15 |