AI Briefing

그때는 맞고 지금은 틀리다: Yarn Berry에서 pnpm으로의 패키지 매니저 전환기

·2026.03.10 18:00

Yarn Berry의 PnP·Zero-installs가 새 병목이 되자 pnpm으로 전환해 메모리와 배포 효율을 개선했다.

카카오페이는 전사 프론트엔드 표준 패키지 매니저를 Yarn Berry에서 pnpm으로 바꿨다. 처음에는 레지스트리 서버가 불안정해 의존성 설치 시간이 길고 배포 실패도 잦았기 때문에, Zero-installs로 설치 단계를 줄이는 방식이 효과적이었다. 실제로 의존성 설치 시간은 최대 **95%**까지 줄었다.

하지만 서비스와 레포지토리 규모가 커지면서 Yarn Berry의 장점은 새로운 문제로 바뀌었다. Git 부담 때문에 fetchclone, 배포 파이프라인의 checkout 시간이 길어졌고, PR diff가 수천 줄까지 커지면서 리뷰가 어려워졌다. IDE 설정을 위한 추가 SDK 설치와 ZipFS 기반 디버깅 제약도 DX를 떨어뜨렸다.

가장 치명적이었던 문제는 배포 빌드 단계의 메모리 스파이크였다. 일부 SSR 서비스의 Docker 이미지 빌드에서 OOM이 발생했고, 원인은 Yarn PnP가 빌드 초기에 .pnp.cjs를 메모리에 올리는 과정과 여러 Worker의 동시 파싱이었다. 초기에는 메모리 한도를 늘려 버텼지만, 전사 공통 배포 파이프라인에서는 근본 해결이 되지 않았다.

대안 검토에서는 PnP를 벗어나되 phantom dependency를 막아야 했고, 그 조건을 만족하는 선택지로 npm, Yarn의 nodeLinker: pnpm, pnpm이 남았다. npm은 호이스팅 문제에서 자유롭지 않았고, Yarn의 pnpm 모드는 주류 생태계가 PnP 중심이라 장기 유지보수 리스크가 컸다. 결국 표준 node_modules를 쓰는 pnpm이 안정성과 생태계 측면에서 가장 낫다고 판단했다.

검증 결과는 예상보다 더 좋았다. 빌드 단계의 메모리 스파이크는 깔끔하게 사라졌고, 배포 시간도 의미 있게 늘지 않았다. 이유는 두 가지였다.

  • 사내 환경의 Yarn Berry는 OS 아키텍처에 종속적인 네이티브 의존성(swc, sharp 등) 때문에 완전한 zero install이 아니었고, 배포마다 다시 설치·빌드가 필요했다.
  • pnpm은 글로벌 스토어와 하드 링크를 써서 CI 환경에서도 의존성 설치가 빨랐다.

추가로 최종 Docker 이미지 크기도 크게 줄었다. Next.js의 dependency tracing은 표준 node_modules 구조와 잘 맞았지만, Yarn PnP는 .yarn/cache를 함께 실어야 해 이미지가 무거웠다. pnpm으로 바꾸자 경량화된 런타임 디렉터리를 그대로 활용할 수 있었고, 이미지 push/pull 시간까지 함께 줄었다.

전환을 본격화하면서는 개발자 설득을 위해 전후 지표를 보여주는 대시보드도 만들었다. 의존성 설치와 빌드 시간, CPU·메모리 사용량, 최종 Docker 이미지 크기를 수집했고, DinD 환경에서는 cgroup 경로를 동적으로 찾아 정확한 값을 측정했다. 결과적으로 Docker 이미지 크기는 약 83% 감소, 최대 메모리 사용량은 약 64% 감소했고, 배포 시간도 줄었다.

결국 과거의 문제를 해결했던 Yarn Berry가 새로운 환경에서는 병목이 되었고, pnpm은 그 시점의 문제를 더 잘 풀어주는 도구였다. 기술 선택의 기준은 절대적 우열이 아니라, 지금의 환경과 문제를 얼마나 효과적으로 해결하느냐에 달려 있었다.

이 요약은 원문 이해를 돕기 위한 큐레이션입니다. 저작권은 원저작자에게 있으며, 정확한 내용과 맥락은 원문을 확인하세요.

요약 오류, 출처 표기 문제, 삭제 요청은 문의 · 건의로 알려주세요.