pnpm vs Yarn: Qual Gerenciador de Pacotes para CI?
Ambos são alternativas modernas ao npm, mas o pnpm e o Yarn fazem trade-offs diferentes em disco, rigor e workspaces.
O pnpm usa um store endereçado por conteúdo com node_modules por symlinks. O Yarn (Classic ou o mais novo Berry) oferece instalações rápidas, workspaces e o opcional Plug'n'Play. No CI a diferença aparece no uso de disco e no comportamento do cache.
pnpm vs Yarn at a glance
| pnpm | Yarn | |
|---|---|---|
| Layout do node_modules | Store endereçado por conteúdo via symlinks | Flat (Classic) ou PnP (Berry) |
| Uso de disco | Baixo (store compartilhado) | Maior (Classic), baixo (PnP) |
| Rigor | Estrito (sem deps fantasma) | Frouxo (Classic), estrito (PnP) |
| Install no CI | pnpm i --frozen-lockfile | yarn install --immutable |
| Workspaces de monorepo | Forte | Forte |
| Compatibilidade de ferramental | Alta | Alta (classic), menor (PnP) |
| Comportamento de lockfile no CI | Frozen automaticamente no CI | --immutable no Berry |
| Corepack | Suportado, padrão no Node 26 | Suportado, padrão no Node 26 |
No CI
O pnpm tende a vencer em disco e na velocidade de install com store quente, e sua resolução estrita pega bugs de dependência fantasma antes que cheguem à produção. O Yarn Berry com PnP também pode ser extremamente rápido e enxuto, mas o PnP muda a resolução de módulos de formas que alguns pacotes não esperam, então teste sua árvore de dependências. O Yarn Classic é o drop-in de menor atrito se você já o usa.
- A package that imports a transitive dependency it never declared works under Yarn classic and fails under pnpm.
- That failure is correct: the import was always a latent bug and Yarn hoisting was hiding it.
- It is also the single most common reason a Yarn-to-pnpm migration is more work than expected, so budget for it rather than being surprised.
- Yarn PnP is strict in the same way, so migrating Yarn classic to Yarn PnP surfaces exactly the same class of breakage.
Cacheie o store
Para o pnpm, cacheie o diretório do store (pnpm store path) com chave em pnpm-lock.yaml. Para o Yarn, cacheie a pasta de cache do Yarn com chave em yarn.lock. Cachear o store importa mais para o tempo de relógio do que a escolha da ferramenta em si.
- pnpm switches to frozen-lockfile mode automatically when it detects CI, so you do not need to pass the flag.
- Since pnpm 11 an install fails outright if the lockfile was written by a newer pnpm major version, rather than silently rewriting it. That is a correctness improvement and also a new way for CI to go red after a colleague upgrades locally.
- pnpm documents that caching the store makes installation faster in most scenarios but is not required and not guaranteed to help, so measure rather than assume.
- name: Install pnpm and Node.js
uses: pnpm/setup@v2.0.0
with:
runtime: node@${{ matrix.node-version }}
cache: true # caches the pnpm store between runs
- run: pnpm install # frozen-lockfile is automatic in CIYarn PnP: o que você ganha e o que abre mão
O Plug and Play é a ideia mais interessante desta comparação e a de trade-off mais afiado. Remover o node_modules remove a parte mais lenta de uma instalação, que é escrever dezenas de milhares de arquivos pequenos.
- Ganhos: instalações mais rápidas, muito menos disco e resolução estrita que bloqueia dependências fantasma.
- Custos: qualquer ferramenta que varre o
node_modulesem disco precisa entender PnP. Isso ainda pega de surpresa bundlers, editores e ferramentas de depuração na cauda longa. - A consequência prática é que o PnP encaixa bem em uma base cujo ferramental você controla por completo, e mal em uma com uma superfície ampla de plugins que você não controla.
Monorepos
Os dois têm implementações maduras de workspaces, e é aqui que acontece a maior parte da decisão real.
- O
--filterdo pnpm seleciona pacotes por nome, caminho ou mudança relativa a um git ref, o que mapeia diretamente para "buildar só o que este PR tocou". - Os catalogs do pnpm deixam você declarar uma versão de dependência uma vez e referenciá-la de todos os pacotes do workspace, o que elimina uma classe inteira de PRs de correção de versão.
- O rigor do pnpm vale mais em um monorepo do que em qualquer outro lugar, porque imports acidentais entre pacotes são exatamente o acoplamento que você tenta evitar.
- Os workspaces do Yarn são estabelecidos há tempo e bem compreendidos, e continuam uma escolha perfeitamente boa para um monorepo Yarn existente.
Vale migrar um repositório Yarn existente?
- Se é Yarn classic e funciona, a resposta honesta costuma ser não. O custo de migração é real e o retorno é principalmente minutos de CI e disco.
- Se você está enfrentando bugs de dependência fantasma ou desvio de versões em um monorepo, o rigor e os catalogs do pnpm atacam a causa real e a migração vale a pena.
- Se você está começando um monorepo novo, workspaces do pnpm mais catalogs é o caminho de menor atrito hoje.
- Se você está no Yarn Berry com PnP e funciona, fique. Você já tem resolução estrita e eficiência de disco; o pnpm seria um movimento lateral.
- Escolha o que escolher, fixe com Corepack para que o runner e todas as máquinas de desenvolvimento concordem.
Decide with your own numbers, not a feature table
Feature comparisons age badly and rarely decide anything, because both tools in a mature category can do the job. What differs is how each behaves on your repository, and that takes one afternoon to measure.
# time a cold install with each candidate, cache cleared
hyperfine --prepare "rm -rf node_modules" --warmup 1 \
"<tool-a> install" "<tool-b> install"
# and the thing CI actually pays for: a cold run with no local cache
docker run --rm -v "$(pwd):/w" -w /w node:22 sh -c "<tool> install"What actually changes when you switch
- Lockfile format. A switch is a one-way door for anyone still on the old tool until everyone migrates, so plan it as a single coordinated change.
- Resolution strictness. Tools differ on whether an undeclared transitive import works, and the stricter one will surface latent bugs as new failures.
- CI cache configuration. The cache path and key differ per tool; carrying over the old ones silently disables caching.
- Everyone on the team and every runner must move together. Pin the version so they cannot drift.
The verdict
Quer pouco disco e resolução estrita: pnpm. Quer um drop-in rápido ou o modelo zero-install do PnP e já está no Yarn: Yarn. Faça commit do lockfile e cacheie o store em qualquer um.
Perguntas frequentes
O pnpm é mais rápido que o Yarn?
Por que o pnpm economiza espaço em disco?
Por que meu código quebra ao trocar de Yarn para pnpm?
node_modules, então um pacote pode importar algo que nunca declarou. O pnpm cria um layout estrito e não achatado onde esse import falha. A falha está correta; a correção é declarar a dependência faltante e não afrouxar a resolução.Preciso de --frozen-lockfile com pnpm no CI?
Devo fazer cache do store do pnpm no GitHub Actions?
pnpm/setup faz isso com cache: true. O pnpm documenta que isso torna a instalação mais rápida na maioria dos cenários, mas não é obrigatório nem garantido, então meça os seus próprios tempos de instalação nos dois modos.Vale usar o Yarn PnP?
node_modules dá instalações mais rápidas, muito menos disco e resolução estrita. O custo é que qualquer coisa que espera node_modules em disco precisa entender PnP, o que ainda derruba partes da cauda longa. O nodeLinker: node-modules do Yarn é o caminho do meio.pnpm ou Yarn para um monorepo?
--filter seleciona pacotes por mudança relativa a um git ref, os catalogs centralizam versões de dependências entre pacotes, e a resolução estrita evita imports acidentais entre pacotes. Uma configuração de workspace Yarn existente que funciona não é um problema a ser resolvido.Como garanto que o CI use a mesma versão de gerenciador de pacotes que a minha máquina?
packageManager do package.json. A divergência de versão entre a máquina de desenvolvimento e o runner é a causa da maioria das falhas de CI ligadas a lockfile, e fixar remove a categoria inteira.