Elegir e instalar: pnpm, corepack y packageManager
Convertir el análisis del nivel en una decisión y luego en un setup reproducible: por qué pnpm es el estándar de facto en monorepos en 2026, cómo corepack —incluido con Node— gestiona la versión del gestor sin instalaciones globales, y cómo el campo packageManager de package.json fija exactamente qué gestor y qué versión ejecuta todo el equipo. Fijar el toolchain es tan importante como fijar las dependencias.
Tres gestores analizados, una recomendación para 2026: pnpm, y doblemente en monorepos. Esta lección cierra el nivel convirtiendo el análisis en una decisión y la decisión en un setup reproducible, porque elegir pnpm es solo la mitad del trabajo. La otra mitad es fijar qué pnpm ejecuta todo tu equipo —qué versión exacta, en tu portátil, en el de tu compañera y en el runner de CI— para que “en mi máquina funciona” deje de ser una frase con sentido. De eso se ocupan corepack y el campo packageManager.
- Elegir con criterio entre npm, yarn y pnpm según el caso.
- Entender por qué pnpm domina los monorepos en 2026.
- Usar corepack para gestionar la versión del gestor sin instalaciones globales.
- Fijar el gestor y su versión con el campo
packageManagerdepackage.json.
El veredicto: pnpm por defecto
Recapitulando el nivel: pnpm elimina la duplicación en disco con su store direccionable por contenido, mata las fantasmas con su árbol de symlinks estricto, es rápido por aritmética y —a diferencia de yarn PnP— conserva un node_modules real que todas las herramientas entienden. npm sigue siendo omnipresente y perfectamente válido para algo pequeño y simple, pero arrastra las patologías del árbol plano. Yarn Berry es potente pero cobra un impuesto de compatibilidad. Para cualquier proyecto no trivial, y muy especialmente para monorepos, la elección por defecto es pnpm.
| Gestor | Layout | Fantasmas | Disco | Cuándo |
|---|---|---|---|---|
| npm | plano, hoisting | posibles | una isla por proyecto | algo pequeño y simple, scripts sueltos |
| yarn Berry | PnP o linkers | imposibles en PnP | caché en git o linker | equipos que ya lo usan a escala |
| pnpm | symlinks estricto | imposibles | store compartido | por defecto, y todo monorepo |
Cada gestor tiene su lockfile: package-lock.json, yarn.lock, pnpm-lock.yaml. Tener dos a la vez es una fuente de árboles divergentes y builds irreproducibles. Elige uno, borra los lockfiles de los demás y haz que el repo lo imponga —con el campo packageManager, con corepack, y si quieres con un preinstall que rechace el gestor equivocado (only-allow)—. Un repo, un gestor, un lockfile.
pnpm y los monorepos
Donde pnpm pasa de “buena opción” a “estándar de facto” es en los monorepos. Sus workspaces (nivel 7) son nativos: declaras los paquetes en pnpm-workspace.yaml y el store se comparte entre todos ellos, de modo que una dependencia usada por cincuenta paquetes del repo existe una sola vez en disco.
La estrictitud escala especialmente bien aquí. En un monorepo con árbol plano, las fantasmas se multiplican porque un paquete puede importar por accidente lo que otro instaló en la raíz compartida; pnpm lo impide por construcción, aislando lo que cada paquete declara. A eso suma los catalog: para unificar versiones en un único lugar, el filtrado con --filter para ejecutar tareas en subconjuntos del repo, y una integración limpia con Turborepo y Nx.
packages:
- apps/*
- packages/*
catalog:
react: ^19.1.0 # una version, referida como catalog: en cada paquete
typescript: ^5.9.0
Es la combinación de dedup, estrictitud y ergonomía de workspace lo que convirtió a pnpm en el cimiento de los monorepos serios en 2026.
Corepack: gestionar el gestor
Instalar pnpm globalmente con npm i -g pnpm funciona, pero deja sin resolver una pregunta: ¿qué versión usa cada persona del equipo? Corepack es la respuesta oficial. Es un shim que viene incluido con Node y que intercepta las llamadas a pnpm y yarn, descargando y ejecutando la versión exacta que el proyecto declara, sin instalación global que se desincronice entre máquinas.
corepack enable # activa los shims de pnpm y yarn
corepack use pnpm@11.5.0 # fija la version y escribe el campo packageManager
Conviene ser honesto sobre su estado en 2026: corepack se distribuye con Node pero viene desactivado por defecto, así que hay que hacer corepack enable una vez por máquina. Las alternativas —un script de instalación independiente, un gestor de versiones o Homebrew— instalan pnpm, pero no atan su versión al proyecto, que es justo lo que da la reproducibilidad por proyecto.
La inclusión de corepack en el binario de Node no es pacífica: se ha discutido separarlo de la distribución por defecto, y su futuro exacto puede variar entre versiones de Node. Por eso conviene no atar tu setup a que corepack esté, sino al campo packageManager, que es declarativo y sobrevive a cualquier decisión sobre el empaquetado de la herramienta. Si corepack está, lo honra; si un día no está, el campo sigue documentando sin ambigüedad qué gestor y qué versión usa el proyecto.
El contrato: el campo packageManager
La pieza durable, la que sobrevive a cualquier debate sobre corepack, es una sola línea en package.json:
{
"packageManager": "pnpm@11.5.0"
}
Ese campo fija el gestor y su versión exacta para todos: tus compañeros, tu CI y tu yo del futuro. Corepack lo lee y ejecuta precisamente esa versión, instalándola si hace falta; e incluso sin corepack, el campo documenta de forma inequívoca la intención. Puedes reforzarlo con un hash (pnpm@11.5.0+sha512...) para que la propia versión del gestor sea verificable. Con esta línea, la reproducibilidad se completa: el lockfile fija qué dependencias instalas, y packageManager fija quién las instala.
flowchart LR dev[ejecutas pnpm install] --> cp[shim de corepack] cp -->|lee packageManager| ver[pnpm 11.5.0 exacto] ver --> run[instala con la version fijada, igual para todos] style dev fill:#89b4fa,color:#11111b style ver fill:#f9e2af,color:#11111b style run fill:#a6e3a1,color:#11111b
Elige pnpm
Dedup por store, estrictitud sin fantasmas y node_modules compatible. La opción por defecto para todo lo no trivial.
Monorepos
Workspaces nativos, catalogs para unificar versiones y –filter para tareas dirigidas. El estándar de facto en 2026.
Corepack
Incluido con Node, activado con corepack enable. Ejecuta la versión declarada sin instalación global que se desincronice.
packageManager
Una línea que fija gestor y versión para todo el equipo. El contrato durable de la reproducibilidad del toolchain.
La idea que cierra este nivel es más profunda de lo que aparenta esa línea de package.json. Durante todo el track has perseguido la reproducibilidad: el lockfile congela el árbol exacto de dependencias para que dos instalaciones den el mismo resultado. Pero hay un supuesto tácito en esa promesa que casi nadie examina: que la herramienta que lee el lockfile y despliega el árbol es la misma en todas partes. No lo es por defecto. pnpm 10 y pnpm 11 pueden resolver peers, ordenar el store o interpretar el lockfile con diferencias sutiles; npm y pnpm producen árboles distintos del mismo package.json. Si el resolvedor varía, la reproducibilidad del lockfile es una ilusión construida sobre arena, porque estás fijando la entrada de una función mientras dejas la función misma flotando. El campo packageManager cierra ese último hueco: fija también la función. La lección general, que vale para cualquier pipeline y no solo para JavaScript, es que un build es reproducible únicamente cuando toda la cadena que lo produce está fijada —las dependencias con el lockfile, el gestor con packageManager, y en los casos más exigentes el runtime, el sistema operativo y hasta las variables de entorno con contenedores o con Nix—. La reproducibilidad no es una propiedad de un artefacto, es una propiedad de una cadena, y una cadena es tan reproducible como su eslabón más flojo. Pasar de “fijo mis dependencias” a “fijo todo lo que interviene en construirlas” es el salto mental que separa a quien logra que algo compile hoy de quien garantiza que compilará igual dentro de tres años en una máquina que aún no existe. Determinismo hasta el fondo: esa es la meta, y packageManager es el eslabón que la mayoría olvida.
- Ejecuta
corepack enabley luegocorepack use pnpm@11.5.0; comprueba que ha aparecido el campopackageManagerenpackage.json. - Borra cualquier lockfile ajeno a pnpm que haya en el repo y confirma que solo queda
pnpm-lock.yaml. - Explica en un comentario por qué el lockfile por sí solo no garantiza reproducibilidad total y qué añade exactamente
packageManager. - Monta un workspace mínimo de dos paquetes con
pnpm-workspace.yamly ejecuta una tarea con--filtersobre uno solo. - Argumenta, para un monorepo hipotético de treinta paquetes, por qué elegirías pnpm frente a npm, citando dedup, estrictitud y catalogs.