Abrí un package.json viejo hace poco — de un proyecto de práctica, no de nada productivo — y conté 340 líneas en el node_modules listado por pnpm. Una sola dependencia directa. El resto, transitivas. Ninguna la elegí yo.
Y ahí me quedé pensando: en algún momento alguien eligió una librería para resolver un problema puntual, sin pensar en lo que arrastraba. Es un patrón que se repite en cualquier proyecto con un lockfile de más de un año: capas de decisiones ajenas apiladas una arriba de la otra, la mayoría invisibles hasta que un CVE las obliga a mostrarse.
Ahí está el problema real: npm install tarda tres segundos y la decisión que representa dura años.
Mi tesis es simple y no es original, pero casi nadie la aplica con disciplina: agregar una dependencia también es asumir mantenimiento. No es "usar código de otro gratis". Es firmar un contrato tácito donde vos te hacés responsable de que ese código siga funcionando, siga siendo seguro y siga siendo compatible con lo que el proyecto necesite dentro de dos años — aunque el autor original haya abandonado el repo hace dieciocho meses.
Evaluar dependencias npm: seguridad y mantenimiento no son lo mismo
La documentación oficial de npm sobre paquetes y módulos explica bien qué es un paquete, cómo se resuelve package.json, cómo funciona el árbol de dependencias y semver. Es la referencia correcta para entender la mecánica.
Lo que esa documentación no dice — porque no es su trabajo decirlo — es cómo evaluar si una librería es una buena idea para el proyecto. No hay una sección de "mantenimiento" en la doc de npm, ni un score de confiabilidad. La mecánica de instalar un paquete es trivial. El criterio para decidir si conviene instalarlo es un problema completamente distinto, y ahí es donde la mayoría improvisa.
Seguridad y mantenimiento tampoco son sinónimos, aunque se los trate como si lo fueran. Una librería puede tener cero vulnerabilidades conocidas hoy y estar completamente abandonada — sin nadie revisando issues, sin releases desde hace dos años, con un mainteiner que dejó de responder. Eso no aparece en npm audit. Aparece cuando necesitás que alguien arregle algo y no hay nadie del otro lado.
Dónde se equivoca la gente: la receta común y su costo oculto
La receta típica cuando aparece un problema es: buscar en npm, filtrar por descargas semanales, elegir la que tiene más estrellas en GitHub, instalar, seguir. Es razonable como primer filtro — descargas y estrellas correlacionan con adopción — pero como único criterio deja afuera todo lo que importa después del día uno.
Contraejemplo típico: una librería de utilidades con 2 millones de descargas semanales, pero cuyo último commit tiene 3 años y cuyo mainteiner respondió el último issue hace 14 meses. Las descargas altas muchas veces reflejan adopción pasada, no salud presente — proyectos legacy siguen bajándola porque ya está en el lockfile de miles de repos, no porque alguien la vuelva a elegir hoy.
El costo oculto aparece tarde: Node sube de versión mayor, algo en el runtime cambia, la librería no se actualiza porque no hay quién la actualice, y el equipo termina con dos opciones feas — forkearla y mantenerla ellos mismos, o migrar todo el código que depende de ella bajo presión, sin planificación. Ninguna de las dos es gratis, y las dos eran evitables si alguien hubiera mirado la fecha del último commit antes de instalar.
Matriz de decisión: qué mirar antes de instalar
Esto es lo que reviso, en orden, antes de sumar una dependencia nueva a un proyecto TypeScript:
1. Mantenimiento activo
- Último commit: menos de 6 meses es buena señal, más de 18 meses es alerta.
- Issues abiertos vs. cerrados: un ratio muy desbalanceado hacia abiertos sugiere que nadie triagea.
- Cantidad de mainteiners: uno solo es un punto único de falla — si esa persona se cansa, el proyecto muere.
2. Superficie de la librería
- ¿Resuelve un problema puntual o es un framework completo? Cuanto más chica la superficie, menos cosas puede romper y menos cosas hay que auditar.
- ¿Cuántas cosas exporta que en realidad no vas a usar? Superficie no usada es riesgo sin beneficio.
3. Tipos de TypeScript
- ¿Tiene tipos propios o depende de
@types/paqueteseparado? Los tipos separados se desincronizan de la implementación real más seguido de lo que gustaría admitir. - Si trabajás con
strict: truey strict null checks activados, como comenté en el post sobre strict null checks en producción, una librería con tipos mal hechos te va a generaranyimplícitos que el compilador no va a poder atajar.
4. Transitive dependencies
- Corré
pnpm why <paquete>para ver qué arrastra. Una librería "liviana" puede traer quince dependencias transitivas que vos nunca elegiste. - Cuantas más transitivas, más superficie de ataque y más probabilidad de que un CVE en un paquete de tercer nivel te afecte sin que lo sepas.
5. Salida (exit strategy)
- Si esta librería se abandona en dos años, ¿cuánto cuesta sacarla? Si está esparcida por todo el codebase sin una capa de abstracción intermedia, el costo de salida es alto.
- Si es reemplazable por código propio en un día, el riesgo de dependencia baja mucho.
Un chequeo rápido y reproducible para el punto 4:
# Ver el arbol de dependencias transitivas de un paquete
pnpm why nombre-del-paquete
# Auditoria de vulnerabilidades conocidas
pnpm audit
# Ver fecha del ultimo publish en el registro de npm
npm view nombre-del-paquete time.modifiedNinguno de estos comandos te da una respuesta binaria. Te dan datos para decidir con criterio, que es distinto a tener una regla automática. Ese mismo principio — evaluar con datos concretos en vez de confiar en la reputación general de una herramienta — es el que aplico cuando reviso integraciones de modelos externos, como conté al evaluar la API de DeepSeek en TypeScript: la pregunta nunca es "¿es buena la herramienta en general?", es "¿es buena para esto específico, con este nivel de mantenimiento?".
flowchart TD
A[Necesito resolver X] --> B{¿Lo resuelvo en menos de un dia con codigo propio?}
B -->|si| C[Escribo codigo propio]
B -->|no| D{¿Mantenimiento activo y tipos propios?}
D -->|no| E[Buscar alternativa o reconsiderar]
D -->|si| F{¿Transitivas razonables y salida clara?}
F -->|no| E
F -->|si| G[Instalar con abstraccion intermedia]Los límites de esta evaluación
Esta matriz no reemplaza un experimento real. Todo lo de arriba es criterio de lectura previa — mirar metadata, historial, tipos — no es lo mismo que correr la librería bajo carga, medir su comportamiento en el runtime específico del proyecto, o ver cómo reacciona el mainteiner ante un issue real reportado por el propio equipo.
Tampoco se puede concluir, a partir de "mantenimiento activo hoy", que la librería va a seguir manteniéndose activamente el año que viene. El historial de commits es evidencia de comportamiento pasado, no una garantía de comportamiento futuro. Proyectos con mainteiners solitarios cambian de estado de golpe — por trabajo nuevo, por burnout, por decisión personal — y no hay checklist que prediga eso con certeza.
Y ojo con npm audit en particular: te dice qué vulnerabilidades están reportadas y catalogadas hoy en la base de datos de npm. No te dice qué vulnerabilidades existen pero todavía no fueron reportadas, ni te dice si esa vulnerabilidad reportada aplica realmente al patrón de uso que tenés en el proyecto. Es una señal, no un veredicto.
Si el proyecto es crítico — maneja datos sensibles, corre en un entorno regulado, tiene SLA de disponibilidad — esta matriz es el punto de partida, no el final. Ahí corresponde una revisión más profunda: leer el código fuente de la librería entera, no solo su README, y considerar un experimento propio con carga controlada antes de decidir.
FAQ
¿Cómo sé si una librería npm está bien mantenida? Mirá la fecha del último commit y del último release, la cantidad de mainteiners activos, y el ratio de issues cerrados versus abiertos. Ninguno de estos datos solo es determinante, pero juntos dan una foto bastante clara.
¿npm audit es suficiente para evaluar la seguridad de una dependencia?
No. npm audit chequea vulnerabilidades ya reportadas y catalogadas. No detecta vulnerabilidades desconocidas ni evalúa si el patrón de uso propio te expone realmente a un CVE listado.
¿Vale la pena usar una librería sin tipos propios de TypeScript?
Depende de la superficie. Si es algo chico y con @types bien mantenido, es aceptable. Si es algo central en la arquitectura, tipos propios y bien mantenidos deberían ser un requisito, no un lujo.
¿Cómo reviso las dependencias transitivas de un paquete antes de instalarlo?
Con pnpm why <paquete> después de instalar, o revisando el package.json del paquete en el registro de npm antes de decidir. También sirve mirar el tamaño del árbol con herramientas como npm ls en modo dry-run.
¿Qué hago si la librería que necesito está prácticamente abandonada? Evaluá el costo de forkearla vos mismo versus escribir una alternativa propia acotada al problema real. Si la superficie que usás es chica, muchas veces conviene más código propio de diez líneas que una dependencia externa sin dueño.
¿pnpm cambia algo respecto a npm en esta evaluación? La mecánica de instalación cambia — pnpm usa un almacén de contenido compartido y es más estricto con el acceso a dependencias no declaradas — pero el criterio de evaluación de mantenimiento, tipos y superficie es el mismo independientemente del gestor de paquetes que uses.
Mi postura
No voy a decirte que dejes de usar librerías externas. Sería una postura ridícula viniendo de alguien que labura con Next.js, Docker y media docena de paquetes en cada proyecto. Pero cada pnpm add merece la misma pregunta que le harías a una contratación: ¿quién está del otro lado, y qué pasa si desaparece?
La próxima vez que estés a punto de instalar algo para resolver un problema chico, probá primero si lo podés resolver en una función propia de diez líneas. Si no podés, corré pnpm why después de instalar y mirá qué trajiste puertas adentro sin haberlo decidido. Esa costumbre, más que cualquier checklist, es la que separa un proyecto que se puede mantener en tres años de uno que se convierte en arqueología.
Fuente original: npm package documentation
Artículos Relacionados
Strict null checks en TypeScript: lo que el compilador no te dice y dónde sí duele en producción
El compilador dice OK. Runtime explota igual. Acá están los 4 patrones donde strict null checks no alcanza: assertion functions, librerías sin tipos, Prisma ORM y JSON.parse — con código real del stack Next.js/Prisma.
23 jul 2026 · 8′ · Tutoriales · Next.js · TypeScript
DeepSeek API en TypeScript: integración segura y evaluación honesta del modelo para código
La API de DeepSeek es compatible con el SDK de OpenAI: eso hace la integración casi trivial. El problema real no es la plomería — es decidir si el modelo vale para lo que necesitás sin comprar el hype ni ignorarlo. Acá está el criterio.
22 jul 2026 · 8′ · Tutoriales · TypeScript · nextjs
Rate limiting en aplicaciones web: qué proteger antes de elegir una librería
Rate limiting no es una dependencia que se agrega al middleware y listo. Es una política de abuso. Antes de copiar el snippet de turno, hay que definir qué activo protegés, qué abuso esperás y cuánto te cuesta un falso positivo.
07 jul 2026 · 10′ · Tutoriales · TypeScript · nextjs
Comentarios (0)
¿Qué pensás de esto?
Dejá tu comentario en 10 segundos.
Usamos tu login solo para mostrar tu nombre y avatar. Nada de spam.
Todavía nadie comentó. Sé el primero — tu opinión vale oro cuando somos pocos.