12k
All articles

Por dentro de la reescritura de pnpm en Rust

Explora la reescritura de pnpm 12 en Rust, sus benchmarks, la compatibilidad con pnpm 11 y los riesgos de actualización que pueden afectar a CI.

OpenReplay Team
OpenReplay Team
Por dentro de la reescritura de pnpm en Rust

pnpm 12 sustituye el código base en TypeScript de pnpm por una reescritura nativa en Rust. Mantiene los comandos, flags, ajustes y formato de lockfile de pnpm 11, por lo que la mayoría de los proyectos pueden actualizarse sin modificar ninguna configuración.

Si usas pnpm en un monorepo y en una flota de CI con mucha carga, seguramente habrás visto titulares que prometen un «90 % más rápido» y te habrás preguntado dónde está la trampa. Una nueva versión mayor de la herramienta que escribe tu lockfile merece más escrutinio que un gráfico de benchmarks.

Este artículo explica por qué un gestor de paquetes escrito en JavaScript es lento, qué cambió el motor en Rust y qué ha costado, quién midió cada cifra y qué cambios de comportamiento pueden afectar a tu pipeline.

Puntos clave

  • pnpm 12.0.0 se publicó como versión estable el 26 de agosto de 2026 y mantiene los comandos, flags, ajustes y formato de lockfile de pnpm 11, salvo una breve lista de diferencias documentadas.
  • En la página de benchmarks de pnpm (pnpm 11.27.1 frente a 12.7.0), una instalación repetida en caliente baja de 563 ms a 18 ms, mientras que una instalación limpia solo baja de 8,4 s a 4,4 s, porque en las instalaciones en frío predominan la transferencia por red y la descompresión.
  • Vercel midió que su workspace de 1670 paquetes se instalaba en entre un 64,4 % y un 90,5 % menos de tiempo con pnpm 12 que con pnpm 10.28, aunque el arranque de Corepack sin caché fue un 11,1 % más lento porque la descarga nativa es más pesada.
  • El cambio con más probabilidades de romper tu CI es la eliminación de pnpm install --resolution-only. Usa pnpm peers check en su lugar.

La restricción: el mismo pnpm, con otro motor

pnpm 12 se diseñó para que actualizar no se sintiera como una migración. El anuncio de la versión 12.0 de pnpm lo plantea como objetivo, y la guía de compatibilidad confirma que, salvo una breve lista de diferencias, pnpm 12 mantiene los comandos, flags, ajustes y formato de lockfile de pnpm 11. pnpm 12 también conserva el almacén direccionable por contenido (content-addressable store), que permite a los proyectos compartir los archivos de los paquetes en lugar de copiarlos. InfoQ indica que la estructura de node_modules tampoco cambia.

La mayoría de las reescrituras aprovechan el nuevo código base para corregir antiguas decisiones de diseño. pnpm, en cambio, convirtió la compatibilidad en el objetivo, hasta el punto de afirmar que su documentación es válida para ambas versiones. En la superficie no cambió casi nada. El trabajo consistió en sustituir todo lo que hay debajo.

¿Por qué es lento un gestor de paquetes en JavaScript?

Un gestor de paquetes escrito en JavaScript paga dos costes en cada instalación grande. Arranca el runtime de Node.js cada vez que lo invocas y hace pasar miles de operaciones de sistema de archivos por un único runtime de JavaScript.

Una instalación pasa, a grandes rasgos, por estas fases:

  1. Obtener los metadatos de los paquetes desde el registro.
  2. Resolver el grafo de dependencias.
  3. Descargar los tarballs.
  4. Descomprimirlos en el almacén.
  5. Enlazar los paquetes en node_modules.

El primer coste es fijo. Antes de que pnpm 11 hiciera cualquier trabajo real, Node.js tenía que arrancar. pnpm 12 se publica como binarios nativos, con un paquete @pnpm/exe.<platform>-<arch> por plataforma. La documentación de self-update confirma que no se lanza Node.js previamente, así que ese coste de arranque desaparece.

El segundo coste crece con la cantidad de trabajo. Las fases 4 y 5 implican descomprimir tarballs y crear hard links para miles de archivos, y cada una de esas operaciones pasa por el runtime de JavaScript.

Este principio se aplica a cualquier herramienta: eliminar una sobrecarga fija ayuda sobre todo cuando queda poco trabajo por hacer. Cuando una instalación casi no tiene nada que hacer, el arranque supone la mayor parte del tiempo total. Cuando tiene que descargar cientos de megabytes, el arranque apenas se nota.

¿Cuánto más rápido es pnpm 12?

Las mejoras de velocidad de pnpm 12 son reales, pero desiguales: una instalación repetida en caliente baja de 563 ms a 18 ms, mientras que una instalación limpia solo baja de 8,4 s a 4,4 s. Las cifras proceden de dos conjuntos de mediciones distintos con versiones de referencia diferentes. No las combines en un único número.

EscenarioAntespnpm 12Medido porReferencia
Instalación repetida en caliente563 ms18 msPágina de benchmarks de pnpm (pnpm 12.7.0)pnpm 11.27.1
Instalación limpia8,43 s4,42 sPágina de benchmarks de pnpm (pnpm 12.7.0)pnpm 11.27.1
Workspace de 1670 paquetes, seis escenarios (mediana)n/dEntre un 64,4 % y un 90,5 % menos de tiempoVercel (pnpm 12.0.0)pnpm 10.28.0
Arranque de Corepack sin cachén/d11,1 % más lentoVercel (pnpm 12.0.0)pnpm 10.28.0
Arranque de Corepack con cachén/d74,7 % más rápidoVercel (pnpm 12.0.0)pnpm 10.28.0

Las cifras de pnpm corresponden al proyecto alotta-files de la página de benchmarks de pnpm, que compara pnpm 11.27.1 con pnpm 12.7.0. La página se vuelve a ejecutar periódicamente y siempre muestra la versión más reciente de cada herramienta, así que es de esperar que esas cifras cambien. La diferencia entre las dos filas de pnpm ilustra lo explicado en la sección anterior. La instalación en caliente mejora unas 30 veces, muy probablemente porque los costes fijos, como el arranque, representaban una gran parte de su tiempo de ejecución. La instalación limpia mejora unas 1,9 veces porque la transferencia por red y la descompresión de tarballs ocupan la mayor parte del tiempo, sea cual sea el lenguaje en que esté escrito el motor.

Las propias mediciones de Vercel muestran el mismo patrón. Con node_modules ya presente, el almacén en caliente y los scripts desactivados, las instalaciones bajaron de 1,476 s a 142 ms. Una instalación totalmente en frío con los lifecycle scripts activados pasó de 9,850 s a 3,472 s. Cada mediana procede de 20 ejecuciones por versión en una única máquina Linux, sobre un workspace de Turborepo con 21 proyectos.

La compilación nativa de pnpm 12 tiene un coste. Vercel cifró la descarga de pnpm 12 mediante Corepack en 47,3 MB, frente a los 17,5 MB de pnpm 10.28.0, y atribuye a esa descarga más pesada el arranque más lento sin caché. Los runners de CI que no almacenan Corepack en caché probablemente pagarán ese coste en cada job.

El tratamiento determinista de los ciclos que se incluye junto con el nuevo motor es una mejora independiente. La guía de compatibilidad de pnpm atribuye a ese cambio, y no al motor en Rust en sí, una reducción de alrededor del 25 % en el uso de memoria y una resolución de peer dependencies entre 2 y 3 veces más rápida en workspaces con muchos ciclos.

La página pública de benchmarks de pnpm ahora solo compara pnpm 12 con npm y con pnpm 11. Según InfoQ, pnpm retiró Bun y Yarn de la comparativa después de que diversos problemas en la configuración del benchmark hicieran poco fiables esas clasificaciones.

¿Por qué el formato del lockfile de pnpm tenía que mantenerse idéntico?

El formato del lockfile de pnpm 12 tenía que mantenerse porque un cambio incompatible dividiría a un equipo a mitad de la actualización. Si pnpm 12 escribiera un formato nuevo, todos los portátiles y runners de CI tendrían que cambiar el mismo día. De lo contrario, dos variantes del lockfile competirían en un mismo repositorio y cada pull request arrastraría ruido de la última versión que se hubiera ejecutado.

Mantener el formato pretende que los equipos puedan actualizarse de forma gradual. Eso no significa que el contenido del archivo no vaya a cambiar nunca. Formato y contenido son cosas distintas:

  • Los lockfiles existentes siguen funcionando. La guía señala que pnpm no modifica las entradas existentes hasta que algo le obliga a volver a resolverlas.
  • La re-resolución puede cambiar las entradas. pnpm 12 registra las dependencias de GitHub, GitLab y Bitbucket con su URL HTTPS, nunca con una SSH. Además, corta los ciclos de dependencias siempre en el mismo punto, lo que reduce el tamaño de los lockfiles en workspaces con muchos ciclos.

Revisa el diff de tu primera instalación con re-resolución en pnpm 12 en un commit independiente.

¿Qué se rompe al actualizar a pnpm 12?

Si una actualización a pnpm 12 rompe un job de CI, la causa más probable es un script que todavía llama a pnpm install --resolution-only. La v12 rechaza ese flag. Su función de informar sobre peer dependencies corresponde ahora a pnpm peers check:

# pnpm 11
pnpm install --resolution-only

# pnpm 12
pnpm peers check

La v12 también rechaza pnpm install --frozen-lockfile false. Usa --no-frozen-lockfile para desactivar el modo frozen-lockfile y --frozen-lockfile sin más para activarlo.

Los demás cambios afectan sobre todo a los resultados, pero tres de ellos también pueden detener un comando:

CambioA quién afectaQué hacer
Las dependencias Git de GitHub/GitLab/Bitbucket se resuelven mediante HTTPSRepositorios privados a los que se accede por SSHConfigurar la reescritura de URL de Git en la máquina
Se informa de las claves desconocidas de pnpm-workspace.yaml, y el comando falla con ERR_PNPM_UNRECOGNIZED_WORKSPACE_SETTINGS cuando el proyecto fija una versión de pnpm que cumple la versión en ejecuciónConfiguraciones con erratasCorregir o eliminar la clave
Los comandos que modifican la instalación global fallan bajo sudo con ERR_PNPM_SUDO_NOT_SUPPORTEDsudo pnpm self-update y similaresEjecutarlos sin sudo
Con engineStrict activado, un engine incompatible en las dependencies normales hace fallar la instalación, incluso si figura también en optionalDependenciesProyectos que usan engineStrictContar con que las instalaciones que antes mostraban una advertencia ahora fallen
En Linux, packageImportMethod: auto prueba los hard links antes que los reflinksUsuarios de LinuxNormalmente, nada
node, deno o bun instalados globalmente siguen la versión fijada por el proyectoMáquinas con runtimes globalesContar con la versión fijada

Las notas de la versión v12.0.0 explican por qué es importante la comprobación del workspace. En pnpm 11, una errata en un ajuste como minimumReleaseAge hacía que pnpm ignorara la clave sin avisar, por lo que la regla que pretendía establecer nunca se aplicaba:

# pnpm-workspace.yaml
packages:
  - "apps/*"
minimumReleseAge:   # typo: pnpm 12 reports this key

En este ejemplo, minimumReleseAge contiene una errata, y pnpm 12 informa de esa clave.

La guía de compatibilidad enumera ocho diferencias en total. Seis modifican un resultado y dos rechazan sintaxis de línea de comandos que pnpm 11 aceptaba: --resolution-only y --frozen-lockfile false. La tabla anterior no las recoge todas. Omite cómo trata pnpm 12 los nombres de gestores de paquetes como yarn en pnpm add, y las filas sobre las claves del workspace y sobre sudo proceden de las notas de la versión, no de la guía. Lee la guía completa antes de actualizar.

¿Deberías actualizar a pnpm 12?

Por lo general, sí, y la actualización transcurre sin incidencias. Ese era el objetivo del diseño. Desde pnpm 11.10 o posterior, ejecuta:

pnpm self-update

En un proyecto que fija pnpm mediante packageManager, self-update simplemente actualiza la versión de ese campo en lugar de instalar pnpm globalmente. pnpm descarga la nueva versión la próxima vez que ejecutes un comando. Haz commit del cambio para que la CI use la misma versión:

{
  "packageManager": "pnpm@12.8.1"
}

Usa la última versión 12.x. Si tu instalación depende de funciones menos habituales, como pnpm deploy o determinados modos de linker, prueba primero la actualización en una rama. Los equipos que todavía usan npm pueden consultar si tiene sentido pasar de npm a pnpm antes de abordar ambos cambios a la vez.

Conclusión

pnpm 12 conserva lo que usas a diario, incluidos los comandos, el formato del lockfile y el modelo de almacén, y reconstruye el motor que hay detrás. La reescritura ha merecido la pena porque dos costes limitaban la versión en JavaScript: el arranque de Node.js en cada invocación y la E/S de archivos canalizada a través de un único runtime. Antes de actualizar, busca --resolution-only y --frozen-lockfile false en tu configuración de CI, comprueba si tienes dependencias Git privadas a las que accedes por SSH y haz commit del primer lockfile re-resuelto por separado para poder revisar el diff.

Preguntas frecuentes

¿Necesita pnpm 12 tener Node.js instalado para funcionar?

No. Una vez instalado, pnpm 12 se ejecuta como un programa nativo, así que no necesita Node.js. El script de instalación independiente tampoco necesita Node.js, ni siquiera durante la instalación. La única excepción es instalar pnpm 12 mediante npm, en cuyo caso el instalador requiere Node.js 22.13 o posterior. Si no hay un binario precompilado de pnpm 12 para tu plataforma, la documentación de pnpm recomienda usar pnpm 11, la versión en JavaScript.

¿Cómo puedo seguir usando SSH para las dependencias Git privadas en pnpm 12?

pnpm 12 obtiene las dependencias de GitHub, GitLab y Bitbucket a través de la URL HTTPS de cada host. Para seguir usando SSH, configura una reescritura de URL de Git, por ejemplo con git config --global url.'git@github.com:'.insteadOf https://github.com/. pnpm invoca git internamente, así que esa regla se aplica a todos los comandos Git que ejecuta pnpm. Los hosts que pnpm no reconoce y las URL que incluyen credenciales se mantienen exactamente como las escribiste, incluidas las SSH.

¿Por qué falla pnpm 12 con un ajuste no reconocido en pnpm-workspace.yaml?

Solo falla cuando el proyecto fija una versión de pnpm y la versión de pnpm que estás ejecutando cumple esa restricción. En ese caso, pnpm considera la clave desconocida un error y se detiene con ERR_PNPM_UNRECOGNIZED_WORKSPACE_SETTINGS. Si no hay una versión fijada que coincida, recibes una advertencia y el comando continúa. Si la clave parece una errata, pnpm indica el ajuste al que probablemente te referías. Los comandos pnpm config siguen funcionando con un archivo que contiene una clave incorrecta, así que puedes usarlos para localizarla y corregirla.

¿Qué comandos de pnpm 12 fallan al ejecutarse con sudo?

Con sudo, pnpm setup, pnpm self-update y cualquier comando que modifique la instalación global, como pnpm add --global, se detienen con ERR_PNPM_SUDO_NOT_SUPPORTED. Las versiones anteriores escribían discretamente en el directorio personal de root. Los paquetes y ajustes globales residen en tu propio directorio personal, así que ninguno de estos comandos necesita permisos de root. Los comandos de solo lectura, como pnpm bin --global, siguen funcionando con sudo.

DevTools for the frontend

Gain Debugging Superpowers

Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers.

Star on GitHub12k

We use cookies to improve your experience. By using our site, you accept cookies.