pnpm은 npm을 써본 개발자가 부담 없이 넘어갈 수 있는 빠르고 효율적인 패키지 매니저다. 이 글에서는 pnpm의 기본 개념, 설치 방법, 자주 쓰는 명령어, 기존 프로젝트에 적용할 때 확인해야 할 점을 실무 흐름에 맞춰 정리한다.pnpm이란 무엇인가

pnpm은 Node.js 프로젝트에서 패키지를 설치하고 관리하는 패키지 매니저다. 이미 npm install, npm run dev 같은 명령어를 써본 적이 있다면 역할 자체는 낯설지 않다. 프로젝트의 package.json을 읽고 필요한 의존성을 설치하며, 등록된 스크립트를 실행하고, 설치된 패키지 버전을 고정하는 일을 한다.
pnpm이라는 이름은 보통 Performant NPM으로 설명된다. 말 그대로 npm과 비슷한 사용 경험을 제공하면서 성능과 저장 공간 효율을 개선하는 데 초점을 둔 도구다. 그래서 처음 배울 때는 완전히 새로운 생태계를 익힌다고 생각하기보다, npm 명령어를 더 효율적인 방식으로 실행하는 도구라고 이해하면 쉽다.
npm, yarn, pnpm은 모두 같은 문제를 해결한다. 프로젝트가 의존하는 라이브러리를 내려받고, 버전을 기록하고, 다른 개발자나 배포 환경에서도 같은 의존성을 재현할 수 있게 돕는다. 차이는 의존성을 저장하고 연결하는 방식, 설치 속도, 잠금 파일 형식, 그리고 node_modules를 구성하는 방식에서 나타난다.
pnpm을 쓰는 이유
pnpm을 쓰는 가장 흔한 이유는 설치 속도와 디스크 공간이다. 여러 프로젝트를 동시에 다루다 보면 각 프로젝트마다 비슷한 패키지가 반복해서 설치된다. pnpm은 패키지를 전역 저장소에 한 번 저장해 두고, 각 프로젝트의 node_modules에는 필요한 참조를 연결하는 방식으로 중복을 줄인다.
이 구조 덕분에 같은 패키지를 여러 프로젝트에서 사용할 때 매번 새로 복사하는 부담이 줄어든다. 예를 들어 개인 프로젝트, 회사 프론트엔드 앱, 테스트용 Vite 프로젝트가 모두 react를 사용한다면, pnpm은 이미 저장된 패키지를 재활용할 수 있다. 결과적으로 설치 시간이 짧아지고 저장 공간도 아낄 수 있다.
또 하나의 장점은 의존성 관리가 비교적 엄격하다는 점이다. npm 환경에서는 직접 설치하지 않은 패키지가 우연히 node_modules 상위 구조에 있어서 코드에서 접근되는 경우가 생길 수 있다. pnpm은 프로젝트가 명시적으로 선언한 의존성 중심으로 접근을 제한하기 때문에, 숨은 의존성에 기대는 문제를 더 빨리 발견할 수 있다.
pnpm은 반복 설치되는 패키지의 중복을 줄인다.node_modules를 더 엄격하게 구성해 잘못된 의존성 사용을 드러내기 쉽다.package.json기반 흐름은 유지되므로npm사용자도 적응하기 쉽다.
pnpm 설치하기
pnpm을 설치하는 방법은 크게 두 가지로 볼 수 있다. 최근 Node.js 환경에서는 Corepack을 통해 패키지 매니저를 활성화하는 방법을 많이 사용한다. Corepack은 프로젝트에서 지정한 패키지 매니저 버전을 더 일관되게 사용할 수 있게 돕는 도구다.
corepack enable
corepack prepare pnpm@latest --activate
pnpm --version
기존 방식처럼 npm으로 전역 설치할 수도 있다. 개인 학습용이거나 빠르게 테스트해 보고 싶다면 아래 방식도 충분히 간단하다.
npm install -g pnpm
pnpm --version
설치가 끝난 뒤에는 pnpm --version으로 버전이 출력되는지 확인한다. 버전 번호가 보이면 터미널에서 pnpm 명령어를 사용할 준비가 된 것이다. 팀 프로젝트라면 개인마다 임의 버전을 쓰기보다 packageManager 필드에 사용할 pnpm 버전을 기록해 두는 방식도 고려할 수 있다.
아래의 pnpm@9.0.0은 작성 방식 예시일 뿐, 최신 버전을 뜻하는 고정 안내가 아니다. 실제 프로젝트에서는 팀에서 검증한 버전이나 현재 사용하는 버전을 확인한 뒤 기록하는 편이 좋다.
{
"packageManager": "pnpm@9.0.0"
}
pnpm 기본 명령어

pnpm의 기본 명령어는 npm과 매우 비슷하다. 기존 프로젝트에서 의존성을 설치하려면 프로젝트 루트에서 pnpm install을 실행한다. 이 명령은 package.json과 pnpm-lock.yaml을 기준으로 필요한 패키지를 설치한다.
pnpm install
새 패키지를 추가할 때는 pnpm add를 사용한다. 예를 들어 런타임 의존성으로 axios를 추가하려면 아래처럼 실행한다. 이 경우 dependencies에 패키지가 기록된다.
pnpm add axios
개발할 때만 필요한 패키지는 -D 옵션을 붙인다. 예를 들어 typescript, eslint, vitest처럼 빌드나 검사, 테스트에 쓰는 도구는 보통 devDependencies에 둔다.
pnpm add -D typescript eslint vitest
패키지를 제거할 때는 pnpm remove를 사용한다. 이 명령은 node_modules에서 패키지를 제거하고 package.json의 의존성 목록도 함께 정리한다.
pnpm remove axios
package.json의 scripts에 등록된 명령을 실행할 때는 pnpm run을 사용한다. dev, build, test처럼 자주 쓰는 스크립트는 npm을 쓸 때와 거의 같은 감각으로 실행할 수 있다.
pnpm run dev
pnpm run build
pnpm run test
패키지를 업데이트할 때는 pnpm update를 사용한다. 전체 의존성을 업데이트할 수도 있고, 특정 패키지만 지정할 수도 있다. 다만 실무 프로젝트에서는 무작정 전체 업데이트를 하기보다 변경 범위를 확인하고 테스트를 함께 실행하는 편이 좋다.
pnpm update
pnpm update react
처음 익힐 때는 npm install은 pnpm install, npm install axios는 pnpm add axios, npm run dev는 pnpm run dev로 대응된다고 보면 된다. 명령 이름이 완전히 같지는 않지만, 의존성을 설치하고 스크립트를 실행한다는 작업 흐름은 거의 그대로 이어진다.
기존 npm 프로젝트에서 pnpm 사용하기
기존 npm 프로젝트에서도 대부분 package.json은 그대로 사용할 수 있다. pnpm은 dependencies, devDependencies, scripts 같은 기본 필드를 읽기 때문에, 패키지 목록과 스크립트 구조를 새로 작성할 필요는 없다. 보통은 프로젝트 루트에서 pnpm install을 실행하는 것부터 시작한다.
다만 잠금 파일은 달라진다. npm은 주로 package-lock.json을 사용하고, pnpm은 pnpm-lock.yaml을 사용한다. 팀에서 pnpm을 쓰기로 했다면 pnpm-lock.yaml을 저장소에 커밋하고 팀원 모두 같은 패키지 매니저를 사용해야 한다. 잠금 파일이 섞이면 설치 결과가 달라지거나 리뷰할 변경 사항이 불필요하게 늘어날 수 있다.
node_modules 구조 차이도 알아두면 좋다. pnpm은 패키지를 납작하게 모두 펼쳐 놓는 방식이 아니라, 전역 저장소와 심볼릭 링크를 활용해 필요한 패키지를 연결한다. 일반적인 앱 개발에서는 크게 의식하지 않아도 되지만, 일부 오래된 도구나 잘못 작성된 패키지는 직접 선언하지 않은 의존성을 암묵적으로 찾으려다가 문제가 생길 수 있다.
이런 문제가 발생하면 먼저 현재 코드나 설정이 실제로 사용하는 패키지를 package.json에 명시했는지 확인한다. 예를 들어 코드에서 lodash를 직접 가져오는데 lodash가 의존성에 없다면, 다른 패키지의 하위 의존성에 우연히 기대고 있던 것이다. 이때는 pnpm add lodash로 직접 의존성을 추가하는 편이 맞다.
- 기존
package.json은 대부분 그대로 사용할 수 있다. pnpm-lock.yaml은 팀과 공유해야 하는 중요한 파일이다.package-lock.json,yarn.lock,pnpm-lock.yaml을 동시에 운영하지 않는 것이 좋다.- 직접 사용하는 패키지는 반드시
dependencies나devDependencies에 명시한다.
처음 도입할 때 체크리스트
pnpm을 처음 도입할 때는 거창한 마이그레이션보다 작은 프로젝트에서 먼저 흐름을 익히는 편이 좋다. 새 Vite 프로젝트나 개인 Node.js 프로젝트에서 pnpm install, pnpm add, pnpm run dev를 반복해 보면 기존 npm과 어떤 부분이 같은지 금방 감이 온다.
pnpm create vite my-app
cd my-app
pnpm install
pnpm run dev
새 프로젝트 생성 흐름까지 확인하면 단순 설치 명령뿐 아니라 개발 서버 실행, 의존성 추가, 빌드까지 한 번에 점검할 수 있다.
팀 프로젝트에 적용한다면 패키지 매니저를 통일하는 것이 먼저다. 한 사람은 npm install을 실행하고 다른 사람은 pnpm install을 실행하면 잠금 파일과 설치 결과가 흔들릴 수 있다. 저장소에는 사용할 패키지 매니저와 버전을 문서화하고, 가능하면 packageManager 필드도 함께 둔다.
또한 CI 환경에서 설치 명령도 바꿔야 한다. 로컬에서는 pnpm을 쓰는데 배포 파이프라인에서는 여전히 npm ci를 실행하면 잠금 파일 기준이 맞지 않는다. CI에서는 보통 pnpm install --frozen-lockfile처럼 잠금 파일을 기준으로 재현 가능한 설치를 수행한다.
pnpm install --frozen-lockfile
pnpm run build
pnpm run test
- 새 프로젝트에서는 생성, 설치, 실행 명령을 한 번에 확인한다.
- 팀 프로젝트에서는 패키지 매니저와 잠금 파일을 하나로 통일한다.
CI에서는pnpm install --frozen-lockfile처럼 재현 가능한 설치 명령을 사용한다.- 오류가 나면 누락된 직접 의존성이 없는지 먼저 확인한다.
정리하면 pnpm은 npm을 대체하기 위해 모든 습관을 새로 배워야 하는 도구가 아니다. package.json 중심의 작업 방식은 유지하면서 설치 속도, 디스크 사용량, 의존성 명확성을 개선하고 싶을 때 시도하기 좋은 선택지다. 특히 여러 Node.js 프로젝트를 자주 만들거나 프론트엔드 앱의 설치 시간이 부담스럽다면, 다음 프로젝트부터 pnpm으로 시작해 보는 것이 가장 현실적인 입문 방법이다.