Open Source · Seguridad Publicado

Auditor de enfriamiento de dependencias

CLI open source que audita el enfriamiento de dependencias (min-release-age) de un proyecto JavaScript desde su lockfile, para npm, pnpm, Yarn y Bun, y da la configuración lista para pegar.

Rol
Diseño y desarrollo
Año
2026
Publicado
14 de septiembre de 2026
Portada de dep-cooldown con un informe del lockfile a 7 días que marca pnpm, vitest y rolldown como YOUNG y 109 paquetes bajo el umbral con salida 1, un sello de enfriamiento de 7 días y ese mismo umbral en las unidades de npm, pnpm, Yarn y Bun sobre fondo oscuro.

dep-cooldown es una herramienta de línea de comandos en TypeScript que audita el enfriamiento de dependencias (cooldown; npm lo llama min-release-age) de un proyecto JavaScript leyendo el lockfile que ya tienes: cuándo se publicó de verdad cada versión resuelta, cuántos días tenía, si trae procedencia y si está deprecada. Funciona con npm, pnpm, Yarn y Bun, e imprime el bloque de configuración para activar el enfriamiento en los cuatro. No instala nada: lee el lockfile, no node_modules.

Se ejecuta sin clonar ni instalar: npx dep-cooldown

Dos preguntas

Un enfriamiento le dice al gestor de paquetes que ignore las versiones publicadas hace menos de N días. Casi todas las campañas recientes contra npm se detectaron y retiraron en horas —las versiones maliciosas de debug y chalk estuvieron vivas dos horas—, así que un retraso modesto te saca de la ventana de exposición. Los cuatro gestores ya lo soportan de forma nativa; lo que quedaba por contestar era ¿me habría servido? y ¿cómo lo activo sin equivocarme de unidad?

Es la herramienta que acompaña al artículo «npm y la cadena de suministro: el gusano que se coló por el trusted publishing», donde el enfriamiento es la primera de las cuatro medidas.

Características

  • Los cuatro formatos de lockfile: package-lock.json y npm-shrinkwrap.json (v3, v2 y v1), pnpm-lock.yaml (v9, v6 y v5, incluido el documento de entorno que escribe pnpm 11+), yarn.lock (classic y Berry) y bun.lock. Detecta cuál hay —y avisa si encuentra varios—, separa dependencias directas de transitivas y consulta los alias por su nombre publicado.
  • Una tabla con lo que importa: fecha de publicación de cada versión (el time del registro), edad en días —en horas si no llega a uno—, directa o transitiva, procedencia (dist.attestations) y deprecación. Por defecto solo lista lo que pide atención; --all lo enseña todo y --json da la estructura completa.
  • --as-of <fecha> rebobina el reloj: calcula las edades respecto al día que instalaste y no respecto a hoy, porque el día de la instalación es cuando el riesgo fue mayor. Si no la pasas, el informe sugiere la fecha de modificación de tu propio lockfile.
  • --config imprime la configuración de npm, pnpm, Yarn, Bun o los cuatro, con la conversión de unidades hecha y la URL de la documentación oficial como comentario.
  • Pensado para CI: sale con 1 si algo es más joven que el umbral, con 2 si hay un error de uso, con 0 si todo tiene la edad mínima y con 3 si nada es joven pero algo no se pudo comprobar —porque lo que no se comprobó no cuenta como aprobado—. Como nunca instala nada, en ese job no corre ningún script de ciclo de vida de terceros.
  • No se fía del lockfile a ciegas: comprueba que el resolved de cada entrada sea de verdad el tarball del registro para esa versión —npm ci instala lo que dice resolved, no lo que dice version— y lista como omitido lo que no tiene fecha de registro (git, file:, workspaces) en lugar de hacerlo desaparecer.
  • Respeta tu registro sin filtrar secretos: lee registry= y @scope:registry= del .npmrc como lo hace npm 11, nunca envía tokens y oculta en los informes las credenciales de la URL; consulta como máximo 8 paquetes a la vez, con tiempo y tamaño acotados, y guarda en caché 24 horas lo que necesita.
  • Probado y ligero: 245 pruebas sin red —con lockfiles reales de npm 11, pnpm 7, 9 y 12, Yarn 1 y 4 y Bun, y una revisión de seguridad cuyas reproducciones quedaron como pruebas—, CI en Node 20, 22 y 24 que instala el paquete empaquetado y lo ejecuta como lo haría un usuario, y una sola dependencia en tiempo de ejecución. Se aplica su propia medicina: su .npmrc lleva min-release-age=7 y el CI audita su propio lockfile.

La trampa de las unidades

Los cuatro gestores coinciden en la idea y discrepan en todo lo demás, empezando por la unidad: npm mide en días (min-release-age), pnpm en minutos (minimumReleaseAge), Yarn en minutos (npmMinimalAgeGate, que también acepta 7d) y Bun en segundos (minimumReleaseAge). Siete días son 7, 10080, 10080 y 604800: quien copia en Bun el valor de pnpm se queda con menos de tres horas de enfriamiento sin enterarse. --config all hace la cuenta.

Hay dos detalles más que las claves no dejan ver: la lista de exclusión de Yarn no se llama como su puerta de edad (es npmPreapprovedPackages, y exime de todas las puertas), y el enfriamiento se aplica al instalar, no al sugerir actualizaciones, así que el bot de dependencias abrirá el PR igual y el npm ci fallará después.

Lo que un enfriamiento no para

Un enfriamiento compra tiempo contra una publicación comprometida, y nada más. La herramienta lo dice en su propia documentación para que nadie la despliegue creyendo otra cosa:

  • Un runner de CI comprometido. La oleada de Shai-Hulud contra TanStack de mayo de 2026 entró por el propio trusted publishing y generó una procedencia Sigstore auténtica. Por eso la columna de procedencia es información, no una nota de seguridad.
  • Un script de instalación malicioso. El enfriamiento decide qué versión instalas, no qué pasa al instalarla: para eso está npm ci --ignore-scripts.
  • Una campaña que dure más que tu umbral, ni lo que ya está fijado en tu lockfile.

Frente a lo que ya existe

Hay trabajo previo: pkg-age, pmsec, dos proyectos distintos llamados npm-cooldown, screen-node, supply-chain-guard, check-outdated --min-age y npm-check-updates --cooldown. Cada uno responde otra pregunta, de si una dependencia está abandonada a qué actualizaciones respetan un umbral. Lo nuevo de dep-cooldown es la combinación: auditoría del lockfile en los cuatro formatos, simulación retrospectiva con --as-of, procedencia y deprecación en la misma tabla, y configuración para los cuatro gestores. En la comparación del README, contrastada con el código publicado de cada una el 14 de septiembre de 2026, ninguna de las otras ocho simula contra una fecha arbitraria ni genera la configuración de los gestores, y solo screen-node mira la procedencia, y únicamente en las dependencias directas.

Stack técnico

  • TypeScript estricto, compilado a ESM con tsup
  • Node.js ≥ 20, con yaml como única dependencia (para pnpm-lock.yaml)
  • Parsers propios para los lockfiles de npm, Yarn y Bun
  • node:test para las pruebas, con el registro simulado desde fixtures
  • GitHub Actions para el CI
  • Licencia MIT; las piezas también se exportan como librería (detectAndParse, buildAudit, createRegistryClient)

Repositorio

Ver en GitHub → · Paquete en npm →

Objetivo

Convertir en una comprobación la medida con mejor relación impacto/esfuerzo del artículo sobre la cadena de suministro de npm: saber, con el lockfile en la mano, qué habría frenado un enfriamiento el día que instalaste, y activarlo en cualquier gestor sin caer en la trampa de las unidades. Y dejar escrito, en la misma herramienta, lo que un enfriamiento no protege.

07 / Contacto

¿Te sirvió algo de lo que leíste? Si tu empresa necesita construirlo, hablemos.

Completa el formulario y te respondo en menos de 24 horas. También puedes escribirme directo: