Lo que una migración de 9.000 millones de solicitudes diarias nos enseña sobre construir con criterio
npm 12 desactivó por defecto los scripts que causaban la mitad de los ataques a su ecosistema, y Cloudflare migró una CDN de 9.000 millones de solicitudes diarias sin pausar el servicio. Dos lecciones de ingeniería seria, sin ruido.

La semana pasada no hubo un lanzamiento espectacular ni una cifra de inversión con muchos ceros. Hubo, eso sí, dos decisiones de ingeniería que nos parecen mucho más reveladoras que cualquier titular llamativo: npm cambió su comportamiento por defecto para cerrarle la puerta a uno de los vectores de ataque más usados contra el ecosistema JavaScript, y Cloudflare terminó de migrar una infraestructura que sirve 9 mil millones de solicitudes al día sin que casi nadie lo notara.
Dos historias distintas. Un mismo tipo de disciplina detrás: la de equipos que construyen pensando en quién va a depender de su trabajo dentro de un año, no solo en la demo de mañana.
Como estudio que se dedica a llevar productos digitales a producción de verdad —no prototipos que nadie vuelve a tocar—, esta semana nos pareció una buena excusa para hablar de lo que casi nunca sale en los titulares: las decisiones aburridas, técnicas y poco glamorosas que determinan si un producto aguanta el tiempo o se convierte en un problema.
npm 12 cierra una puerta que llevaba años abierta
Si trabajas con Node.js, probablemente instalaste paquetes miles de veces sin pensar demasiado en lo que pasa en el momento exacto de npm install. Ese comando puede ejecutar scripts automáticos —preinstall, install, postinstall— con los mismos permisos que tiene tu usuario en la máquina. Durante años, esa ha sido una de las puertas de entrada favoritas para ataques a la cadena de suministro de software.
Con el lanzamiento de npm 12, esa puerta cambió de estado por defecto. Ahora los scripts de instalación vienen desactivados salvo que el equipo los apruebe explícitamente, mediante un comando (npm approve-scripts) que además deja un registro versionado de qué se autorizó y por qué. Lo mismo ocurre con las dependencias que apuntan a repositorios Git o a URLs remotas: antes se resolvían automáticamente, ahora requieren permiso explícito (InfoQ).
El dato que explica por qué esto importa es contundente: investigadores de seguridad estiman que estos tres vectores —scripts de instalación, dependencias Git y fuentes remotas— estuvieron involucrados en cerca del 53% de los ataques maliciosos detectados en el ecosistema npm durante el último año (The Hacker News).
npm no inventó esta idea. Yarn, pnpm y Bun ya habían adoptado modelos similares de "confianza explícita" antes que npm, lo que confirma algo que creemos firmemente: cuando toda una industria converge hacia la misma decisión de seguridad, probablemente dejó de ser una opción y se convirtió en un estándar mínimo esperado.
Lo que más nos gusta de este cambio es lo que revela sobre cómo debería diseñarse cualquier sistema, no solo un gestor de paquetes: el comportamiento seguro debería ser el que ocurre si nadie hace nada. No un checkbox opcional que alguien tiene que acordarse de marcar, sino el estado natural del sistema. Diseñar para que lo correcto sea también lo más fácil es, para nosotros, una de las decisiones de producto más subestimadas que existen.
Eso sí, el cambio no viene sin fricción. Algunos equipos usan scripts de instalación de forma legítima —por ejemplo, para aplicar parches automáticos con herramientas como patch-package— y ahora tendrán que aprobarlos explícitamente. Especialistas en seguridad ya advirtieron sobre un riesgo conocido en estos escenarios: la "fatiga de aprobación". Si un equipo empieza a aprobar scripts de forma automática solo para que el build deje de romperse, la protección se convierte en un trámite que nadie realmente revisa. Un mecanismo de seguridad que se vuelve reflejo pierde buena parte de su valor.
Esa tensión —entre seguridad real y seguridad de trámite— es exactamente el tipo de decisión que discutimos con los equipos con los que trabajamos cuando definimos procesos de CI/CD y políticas de dependencias. No se trata de activar todas las restricciones posibles. Se trata de diseñar procesos que el equipo realmente pueda sostener en el día a día, sin que se conviertan en un obstáculo que la gente aprende a esquivar.
Migrar una infraestructura que sirve 9.000 millones de solicitudes diarias, sin apagar las luces
La segunda historia de la semana es, en cierto modo, la contracara técnica de la primera: no se trata de cerrar una puerta, sino de reconstruir toda una casa mientras la gente sigue viviendo adentro.
cdnjs es una red de distribución de contenido gratuita y de código abierto que sirve librerías de JavaScript y CSS a una porción enorme de la web —se estima que está presente en cerca del 12% de todos los sitios web activos—. Hablamos de aproximadamente 108.000 solicitudes por segundo, unos 9.000 millones al día, distribuidas en más de 330 centros de datos, con una tasa de acierto de caché del 98,6% (Cloudflare Blog).
Durante años, esa infraestructura vivió repartida entre Google Cloud Platform y Cloudflare. Funcionaba, pero cada cambio se volvía más costoso de lo que debería: no había observabilidad unificada, y depurar un problema significaba juntar manualmente registros de dos plataformas distintas. El equipo lo resumió con una frase que cualquier persona que haya mantenido un sistema legado reconoce de inmediato: publicar algo nuevo o corregir un error se estaba volviendo cada vez más difícil.
La solución fue consolidar todo en la plataforma de desarrollo de Cloudflare, combinando piezas que normalmente vemos usadas por separado: R2 como fuente única de almacenamiento de archivos, KV para los metadatos de cada paquete, Workers sirviendo las solicitudes en el borde de la red, Workflows orquestando el pipeline de publicación, Queues gestionando trabajos de compresión de forma asíncrona, y Durable Objects coordinando el estado de todo el proceso.
Lo más honesto del caso —y lo que más valoramos como equipo que también construye sobre infraestructura ajena— es que la migración no salió perfecta al primer intento. El equipo chocó con límites reales de la plataforma: un tope de mil subsolicitudes y otro de 1.024 pasos por flujo de trabajo, ambos insuficientes para una operación de este tamaño. En lugar de diseñar soluciones alternativas complicadas para esquivar esos límites, simplemente los reportaron y pidieron que se ampliaran. Cloudflare los subió a 10 millones de subsolicitudes y 25.000 pasos por flujo.
Nos parece un buen recordatorio de algo que repetimos seguido: la arquitectura correcta no siempre es la más elegante en el papel. A veces es la que reconoce sus propios límites, los comunica con claridad al proveedor o al equipo correspondiente, y resuelve el problema real en lugar de construir una solución más compleja solo para evitar pedir ayuda.
Cuando el prototipo también necesita reglas claras
Un tercer movimiento de la semana, más pequeño pero relevante para cualquier equipo que construye MVPs rápido, viene del mundo de GraphQL. Expedia abrió el código de mockql-rs, una herramienta en Rust que genera datos simulados para APIs GraphQL usando modelos de lenguaje en tiempo de ejecución, combinando respuestas reales del backend con campos generados donde el equipo lo indique explícitamente mediante una directiva @mock (InfoQ).
La idea resuelve un dolor conocido: los datos de prueba escritos a mano se desactualizan cada vez que cambia el esquema, y alguien tiene que acordarse de mantenerlos. Airbnb ya había resuelto un problema similar meses atrás con su propia herramienta, @generateMock, aunque con una arquitectura distinta: genera los mocks en tiempo de compilación en lugar de hacerlo en cada solicitud.
El detalle que nos parece más interesante no es la herramienta en sí, sino lo que revela: dos empresas grandes llegaron a la misma necesidad —permitir que los equipos de frontend avancen sin esperar a que el backend esté listo— y construyeron dos soluciones incompatibles entre sí, mientras la propuesta de estandarización de la comunidad GraphQL todavía está en una etapa muy temprana, sin ni siquiera un responsable formal que la impulse.
Esto confirma algo que vemos seguido cuando acompañamos a equipos en la fase de prototipado: moverse rápido para validar una idea es exactamente lo correcto, pero "rápido" no debería significar "sin ningún criterio". Elegir bien qué herramienta usar para simular datos, documentar esa decisión y tener claro qué pasará cuando el backend real esté listo, ahorra semanas de retrabajo más adelante.
Lo que estas tres historias tienen en común
Ninguna de las tres noticias de esta semana tiene el brillo de un lanzamiento de producto o una ronda de inversión millonaria. Y, sin embargo, creemos que son más útiles para cualquier empresa que esté construyendo tecnología en serio.
npm nos recuerda que la seguridad no debería depender de que alguien se acuerde de activarla. Cloudflare nos recuerda que migrar una infraestructura crítica exige reconocer límites reales en lugar de esquivarlos con complejidad innecesaria. Y Expedia nos recuerda que incluso las decisiones más pequeñas de un prototipo —cómo simular datos, qué herramienta usar— merecen el mismo criterio que cualquier otra decisión de arquitectura.
Esa es exactamente la combinación que buscamos aportar cuando acompañamos a una empresa en el desarrollo de su producto: no solo escribir código que funcione hoy, sino tomar las decisiones de seguridad, arquitectura y velocidad de desarrollo que hacen que ese producto siga funcionando bien dentro de un año, con un equipo que pueda mantenerlo sin miedo a lo que hay debajo.
Si tu empresa está construyendo un producto desde cero, migrando una infraestructura que ya no da abasto, o simplemente sospecha que algunas decisiones técnicas se tomaron con más apuro del que deberían, conversemos. Preferimos revisar esas decisiones contigo mientras todavía son fáciles de corregir.