codingstairs
노트에듀라이프연락
⌕검색⌘K
koen

Navigation

  • Intro
  • Blog
  • Life

연락하기

로그인 없이도 보낼 수 있어요. 답변이 필요하면 이메일을 함께 적어 주세요.

  • 익명 폼으로 의견 남기기 →
  • ✉ warragon112@gmail.com
  • 카카오톡 오픈채팅 ↗

© 2026 codingstairs

  • 노트
  • 에듀
  • 검색
  • 라이프
  • 연락
  • 약관
  • RSS
  • GitHub
노트›tools

pnpm

2026-04-28 게시· 2026-05-18 갱신·0회 조회

pnpm

pnpm 은 Node.js 생태계의 패키지 매니저 가운데 하나. 이 글은 pnpm 의 출자 · 동작 방식 · 다른 매니저와의 차이를 사실 기준으로 정리합니다.

1. pnpm 에 대한 이야기

"performant npm" 의 약자로, 2017 년 Zoltan Kochan 이 시작한 오픈소스 프로젝트. 저작권 표기는 "2015–현재 contributors of pnpm" — 초기 실험은 2015 년부터 GitHub 저장소 (pnpm/pnpm) 에서 진행됐고 1.0 을 거쳐 현재 9.x · 10.x 메이저로 이어집니다. 라이선스는 MIT.

해결하려 한 문제는 둘:

  • 같은 패키지를 여러 프로젝트에 중복 설치해 디스크가 빠르게 차오르는 npm 의 동작.
  • 평탄화 (hoisting) 된 node_modules 가 선언하지 않은 의존성을 임포트해도 동작하게 만드는 "phantom dependency" 문제.

2. 어떻게 동작하는가

pnpm 의 핵심은 content-addressable store. 패키지 파일은 ~/.pnpm-store (또는 OS 기본 경로) 에 한 번만 저장되고, 각 프로젝트의 node_modules 에는 그 파일을 가리키는 하드링크. 같은 버전의 라이브러리를 여러 프로젝트가 의존해도 디스크에는 한 본만.

node_modules 구조는 두 단계:

  • node_modules/.pnpm/<pkg>@<ver>/node_modules/<pkg> — 실제 패키지 (스토어로의 하드링크).
  • node_modules/<직접의존성> — 위 경로로의 심볼릭 링크.

직접 선언한 의존성만 최상위에 노출되므로 package.json 에 적지 않은 모듈을 코드에서 require 할 수 없음. 공식 문서가 "non-flat node_modules" 라 부릅니다.

3. 워크스페이스

루트의 pnpm-workspace.yaml 에 패키지 경로 패턴:

packages:
  - "apps/*"
  - "packages/*"

내부 의존성은 "workspace:*" 같은 프로토콜로 적어 외부 npm 레지스트리 대신 워크스페이스 내부를 가리킴.

pnpm-lock.yaml 은 모든 의존성의 정확한 버전과 해시를 기록 — 커밋 대상.

4. 다른 길

도구 첫 릴리스 특징
npm 2010 Node.js 공식 동봉. 평탄화된 node_modules. 가장 큰 호환 폭.
Yarn Classic (1.x) 2016 Facebook 발. 락파일 · 워크스페이스를 npm 보다 먼저 도입. 현재 유지보수 모드.
Yarn Berry (2+) 2020 PnP (Plug'n'Play) 로 node_modules 자체를 없애는 모드. 도구 호환성 문제로 채택이 갈림.
pnpm 2017 스토어 + 하드링크 / 심링크. 디스크 절약 · 엄격한 의존성.
Bun 2023 (1.0) Zig 기반 런타임 + 패키지 매니저. bun install 의 속도가 강점.

각 도구가 어울리는 환경은 다름. CI 환경이 Node 표준 도구만 가정한다면 npm, 디스크와 모노레포 격리가 중요한 환경에서는 pnpm, 신규 그린필드에 한정해 속도를 우선한다면 Bun.

5. 자주 쓰는 모양

# 설치
# Windows: PowerShell
iwr https://get.pnpm.io/install.ps1 -useb | iex
# macOS · Linux: bash
curl -fsSL https://get.pnpm.io/install.sh | sh -

# 프로젝트에서
pnpm install            # 의존성 설치
pnpm add zod            # 런타임 의존성 추가
pnpm add -D vitest      # 개발 의존성
pnpm remove zod
pnpm update
pnpm run build          # 또는 그냥 pnpm build

워크스페이스 루트에서 특정 패키지 명령 실행:

pnpm --filter web dev
pnpm -r build           # 모든 워크스페이스 패키지에 build 실행

6. engines · packageManager

package.json 에 Node 와 pnpm 버전을 적어 놓는 관습:

{
  "engines": {
    "node": ">=20.10",
    "pnpm": ">=9"
  },
  "packageManager": "pnpm@9.12.3"
}

packageManager 필드는 Corepack (Node 16.10+ 동봉) 이 읽어 자동으로 해당 매니저 버전을 준비.

7. 자주 걸리는 자리

phantom dependency — 일부 도구가 평탄화된 node_modules 를 가정해 phantom dependency 를 쓰면 pnpm 환경에서 깨짐. 보통 누락된 의존성을 package.json 에 명시하면 해결. 임시 회피로 .npmrc 의 shamefully-hoist=true 가 있지만 의도가 흐려짐.

Windows 하드링크 — 사용자 프로필이 다른 드라이브에 있으면 하드링크가 같은 볼륨 안에서만 동작하는 제약 때문에 스토어 위치를 프로젝트와 같은 드라이브로 옮겨야 할 때. 환경변수 PNPM_HOME 또는 pnpm config set store-dir.

락파일 혼재 — npm 과 pnpm 의 락파일이 한 저장소에 섞이면 의존성 해석이 흔들림. CI 와 로컬에서 같은 매니저를 쓰도록 packageManager 필드와 Corepack 을 함께.

pnpm dlx vs npx — 캐시 경로가 달라 한쪽이 캐시한 도구를 다른 쪽이 다시 받는 경우.

하고픈 말

pnpm 의 content-addressable store + 비호이스팅 구조가 디스크 절약과 phantom dependency 차단 두 가치를 동시에 줍니다. 모노레포에서는 이 차이가 더 크게 드러나는 자리. packageManager 필드 + Corepack 으로 팀 · CI 가 같은 버전을 쓰도록 고정.

Next

  • monorepo-light
  • python-uv

pnpm 공식 문서 · pnpm motivation · pnpm GitHub · npm Documentation · Yarn Documentation · Node.js Corepack · pnpm 블로그 를 참고합니다.

tools 카테고리의 다른 글

카테고리 전체 보기 →
  • Git Submodule · Subtree · LFS — 저장소 안에 다른 저장소
  • 정규표현식 — 패턴으로 문자열을 찾기
  • Python 의존성 도구의 역사
  • 린팅과 포매팅
  • 에디터 설정
  • Gradle