Right Then, Wrong Now: A Package Manager Migration Story from Yarn Berry to pnpm
Key point
As Yarn Berry's PnP and Zero-installs became a new bottleneck, the team switched to pnpm and improved memory usage and deployment efficiency.
Details
KakaoPay changed its company-wide frontend standard package manager from Yarn Berry to pnpm. Initially, the registry server was unstable, causing long dependency install times and frequent deployment failures, so reducing the install step with Zero-installs was effective. In practice, dependency install time was reduced by up to 95%.
However, as the service and repository grew in scale, Yarn Berry's strengths turned into new problems. The Git burden lengthened fetch and clone times as well as checkout time in the deployment pipeline, and PR diffs grew to thousands of lines, making reviews difficult. The extra SDK installation needed for IDE setup and debugging constraints from ZipFS also degraded DX.
The most critical problem was a memory spike at the deployment build stage. OOM occurred during Docker image builds for some SSR services, caused by Yarn PnP loading .pnp.cjs into memory early in the build process combined with concurrent parsing by multiple Workers. Initially, they got by by increasing the memory limit, but this was not a fundamental fix within the company-wide common deployment pipeline.
In reviewing alternatives, they needed to move away from PnP while still preventing phantom dependencies, and the options that satisfied this condition were npm, Yarn's nodeLinker: pnpm, and pnpm. npm was not free from hoisting issues, and Yarn's pnpm mode carried significant long-term maintenance risk since the mainstream ecosystem is centered on PnP. In the end, they judged that pnpm, which uses the standard node_modules, was the best choice in terms of stability and ecosystem support.
The verification results were better than expected. The memory spike at the build stage disappeared cleanly, and deployment time did not increase meaningfully. There were two reasons for this.
- In the in-house environment, Yarn Berry was not truly zero-install due to OS-architecture-dependent native dependencies (such as
swc,sharp), requiring reinstallation and rebuilding on every deployment. - pnpm used a global store and hard links, making dependency installation fast even in CI environments.
Additionally, the final Docker image size was significantly reduced. Next.js's dependency tracing worked well with the standard node_modules structure, but Yarn PnP required also shipping .yarn/cache, making the image heavier. Switching to pnpm allowed them to fully leverage a lightweight runtime directory, which also reduced image push/pull times.
As the migration got underway in earnest, they also built a dashboard showing before-and-after metrics to persuade developers. They collected dependency install and build time, CPU/memory usage, and final Docker image size, and in the DinD environment, they dynamically located the cgroup path to measure accurate values. As a result, Docker image size decreased by about 83%, peak memory usage decreased by about 64%, and deployment time also decreased.
In the end, Yarn Berry, which had solved past problems, became a bottleneck in the new environment, and pnpm was the tool that better solved the problems of that moment. The criterion for technology choice was not absolute superiority, but how effectively it solves the current environment and problems.
This summary was generated automatically by AI. Check the original for the author's claims and context. Copyright belongs to the original author.
Our guide explains how the AI works. Report summary errors, attribution issues, or removal requests via Contact.