Envíos v2.13: Lighthouse, Turnstile y Cinco Meses de No Terminar
Lorenzo Lopez Villalobos
Cuando escribí Camino a Vector 2.0 allá por febrero, el sitio acababa de pasar por su primera revisión seria. Nuevo framework, nuevo sistema de diseño, nuevo pipeline de despliegue. Lo llamé un informe de progreso, no una vuelta de la victoria. Resultó ser más preciso de lo que esperaba.
Desde ese post, el sitio ha pasado por diecinueve releases más. No porque la base estuviera rota — se mantuvo bien — sino porque en el momento en que empiezas a tratar tu portafolio como un producto real en lugar de un proyecto paralelo, el backlog se vuelve infinito. Cada mejora revela tres cosas más que vale la pena mejorar. Esta es la historia de todo lo que sucedió entre v2.0 y v2.16.1.
Desmantelando WakaTime

Tuve una integración de WakaTime en el sitio durante un tiempo. La propuesta era sencilla: estadísticas de codificación en tiempo real, prueba de que realmente escribo código todos los días. Lenguajes, horas, rachas, todo el dashboard.
Funcionó. Pero nunca se sintió como mío. WakaTime es la API de otra persona, los límites de velocidad de otra persona, el esquema de datos de otra persona. Cuando su endpoint tuvo un hipo, mi portafolio tuvo un hipo. Y "12 horas de TypeScript esta semana" no le dice a un visitante nada significativo sobre lo que estoy construyendo o cómo trabajo.
Así que lo maté. No solo el widget — toda la integración. Cliente API, tipos, variables de entorno, capa de caché, dependencia de chart.js, CSS, claves i18n, snapshots de datos, documentación. Todo. Eso fue v2.1.0, y marcó la pauta para cada release que siguió: si una dependencia no se está ganando su lugar, se va.
Construyendo DevActivity desde Orion

El reemplazo de WakaTime vino de nuestra propia stack. Habíamos estado construyendo Orion — la plataforma de gestión de proyectos de Vector — y ya tenía todos mis datos de desarrollo. Cada commit, cada tarea abierta y cerrada, cada revisión de código. ¿Por qué canalizar las estadísticas a través de un servicio de terceros cuando la historia real estaba en nuestra propia base de datos?
El widget DevActivity extrae datos de la API pública de Orion. Un heatmap de contribuciones al estilo de GitHub que cubre 52 semanas, patrones de commit desglosados por hora y día, distribuciones de tipo de tarea y prioridad a través de gráficos de dona, una tarjeta de productividad con rachas y velocidad. La diferencia con WakaTime: estos son datos reales del proyecto, no solo "tiempo dedicado en un editor".
Pasé por varias iteraciones en los gráficos. La primera versión usaba una librería de gráficos y renderizaba SVGs. La versión final usa HTML y CSS puros — divs con anchos y colores de fondo calculados. Cero dependencias externas. Todo el componente tiene aproximadamente 3KB gzipped. A veces, el enfoque más simple es realmente el correcto.
Para v2.7.0, DevActivity se había convertido en un dashboard completo: modales de ayuda que explican lo que significan burndown y velocity, un temporizador de auto-refresh sincronizado con el TTL de la caché de Orion, pills de changelog que muestran lo que cambió entre refrescos, y un proxy del lado del servidor para que la clave API nunca toque el navegador. Para v2.10.0, la barra de navegación tenía una insignia de cuenta regresiva en vivo que enlazaba a la sección de estadísticas, y el widget mostraba insignias de diff en el refresh para que pudieras ver tus números moverse en tiempo real.
Es la sección del sitio de la que estoy más orgulloso. Te dice algo real sobre cómo trabajo, y cada línea es nuestra.
El Blog Que Casi No Fue

Había querido un blog desde la reconstrucción de v2.0. Seguía siendo despriorizado — siempre había un proyecto de cliente o una función de Orion o alguna tarea de infraestructura que se sentía más urgente. El blog vivía permanentemente en "próximo sprint".
Lo que inclinó la balanza fue que Orion desarrollara un CMS real. Una vez que tuvo gestión de contenido con edición de texto enriquecido, manejo de imágenes a través de Lyra (nuestro pipeline de optimización de CDN), y una API pública, construir el blog se convirtió en unas pocas horas de trabajo en lugar de un proyecto.
La integración se puso en marcha en v2.4.0: páginas de listado en /blog y /es/blog, páginas de detalle con renderizado HTML completo, datos estructurados JSON-LD para SEO, layouts de tarjetas responsive, y 10 tests de Playwright que cubren toda la superficie. El contenido vive en Orion, se sirve a través de un endpoint API, y el portafolio simplemente lo renderiza. No hay markdown en el repo. No hay generación estática para los posts. Solo una llamada API y algunas páginas de Astro.
Luego vino v2.4.1 — un patch release para un byte. El blog funcionaba perfectamente en desarrollo. En producción, cada llamada API devolvía un 401. Pasé más tiempo del que me gustaría admitir depurando el middleware de autenticación antes de descubrir que la clave API en el archivo env encriptado tenía un carácter final extra. Un carácter, 401 en cada request. El tipo de bug que te mantiene humilde.
Las imágenes responsive llegaron en v2.5.0. El pipeline Lyra de Orion genera variantes WebP responsive en diferentes breakpoints para cada imagen subida, y el blog necesitaba usarlas realmente. Atributos srcset y sizes apropiados para que el navegador elija la variante correcta para el viewport. Conseguir que sizes funcione bien cuando tienes un contenedor de ancho máximo con padding que se colapsa a ancho completo en el móvil tomó más retoques de lo que esperarías de lo que suena como una característica simple.
Para v2.10.0, el blog tenía una barra lateral completa: nube de tags con recuentos, filtrado de tags clickeables, timeline de archivo mensual y un layout móvil que apila todo limpiamente. Pasó de "deberíamos tener un blog" a una plataforma de publicación adecuada en aproximadamente una semana de trabajo enfocado.
Formulario de Contacto: Una Historia en Tres Partes

El formulario de contacto se envió en v2.8.0 como una experiencia modal completa: nombre y apellido, empresa, correo electrónico, teléfono con código de país y formato automático para 26 países, dropdowns de motivo y método (incluida una opción "Programar una Google Meet"), trampa para spam honeypot y entrega de correo electrónico a través de Resend con una plantilla HTML con la marca del sitio.
La segunda parte fue reCAPTCHA. Google reCAPTCHA v2 invisible, añadido para evitar que los bots quemaran mi cuota de Resend. Funcionó. También requirió sesenta líneas de CSS para rediseñar la insignia flotante de Google en algo que no se viera terrible tanto en modo claro como en modo oscuro, cargó 178KB de JavaScript, bloqueó el hilo principal durante 860 milisegundos y estableció cuarenta y nueve cookies de terceros en el navegador de cada visitante.
La tercera parte — v2.13.0 — fue quitar reCAPTCHA y reemplazarlo con Cloudflare Turnstile. Pero eso es parte de la historia de Lighthouse.
Infraestructura: Los Releases Invisibles
Parte del trabajo más importante entre v2.0 y ahora es algo que ningún visitante verá jamás. Releases donde el changelog se lee como el diario de un administrador de sistemas, y importan más que cualquier cambio de UI.
v2.1.0 fue el release de infraestructura. Endpoint de salud en /api/health que devuelve {"status":"ok"} para que Coolify sepa que el contenedor está vivo. Builds de Docker multi-etapa con un usuario no root. Logger estructurado VCR usando process.stdout.write (que sobrevive a la eliminación de la consola de producción — más sobre esto en un segundo). Quality gate pre-push. Git remote migrado a Forgejo en git.vectorcr.com. Todos los documentos consolidados en un directorio /documentation/ en lugar de archivos sueltos que ensucian la raíz.
v2.3.0 fue el release de dotenvx. Nos estandarizamos en dotenvx para secretos encriptados en todos los proyectos de Vector. El archivo .env.production se commitea a git como texto cifrado, y la clave de descifrado vive solo en el entorno de ejecución de Coolify. ¿Exagerado para un sitio de portafolio? Tal vez. Pero el punto no es el portafolio — es el patrón. Cada proyecto de Vector, desde este sitio hasta Orion y las aplicaciones de los clientes, utiliza el mismo flujo de trabajo de secretos. Un modelo mental en cada repo.
Ese release también arregló el logger. Habíamos configurado esbuild para drop: ["console"] en producción, lo que elimina todas las llamadas console.log del bundle del navegador. Genial para la seguridad — sin salida de depuración en DevTools. Terrible para el servidor, donde esas mismas llamadas console.* eran nuestra única salida de logging. La solución: el logger VCR usa process.stdout.write directamente, por lo que sobrevive a la eliminación. Salida estructurada con prefijo de emoji que se ve limpia en el dashboard de logs de Coolify y no se filtra accidentalmente a los usuarios finales.
v2.9.0 fue analytics. GA4 a través de GTM, con 16 eventos dataLayer personalizados en 7 componentes: Clicks de CTA, enlaces sociales, interacciones del modal de contacto, filtros de proyecto, toggles de modo oscuro, cambios de idioma, profundidad de scroll. Tracking granular que te dice cómo la gente realmente usa tu sitio, no solo que aparecieron.
v2.11.0 trajo el Lyra CDN SDK al portafolio. Mi imagen de perfil en la sección hero ahora viene a través de Lyra con WebP srcset responsive y un placeholder blurhash mientras se carga. Fetching del lado del servidor en tiempo de renderizado con un fallback CDN hardcodeado para la resiliencia. Es una imagen, pero ejercita el mismo pipeline que usan nuestros sitios de clientes — detecto problemas del SDK aquí antes de que lleguen a producción en otros lugares.
v2.12.0 fue pura limpieza. 1,477 iconos Phosphor SVG sin usar eliminados (5.8MB). El componente de fondo Three.js muerto eliminado (1.8MB en dependencias que no estábamos importando). Faker.js, fotos de perfil huérfanas, favicons duplicados, artefactos de IDE, documentación obsoleta de WakaTime — todo eliminado. La carpeta .git del repositorio pasó de 45MB a 3.1MB después de que ejecutamos git-filter-repo para purgar los grandes blobs del historial. Los componentes se reorganizaron en la estructura de tres niveles de VCR: base/ para átomos, shared/ para workhorses, layouts/ para la estructura de la página. Dieciséis archivos actualizados para las rutas de importación. No es glamuroso, pero el codebase respira ahora.
v2.14.1 fue el gold standard de Dockerfile. Migramos al patrón de build de Bun / runtime de Node: Bun maneja los pasos rápidos de instalación y build, luego la imagen final se ejecuta en Node para la estabilidad de producción. Build multi-etapa, usuario no root, directiva HEALTHCHECK, caché de capas optimizada. Este mismo patrón de Dockerfile ahora se ejecuta en todos los proyectos de Vector. Escríbelo una vez, úsalo en todas partes.
El Sprint de Lighthouse

Esto fue v2.13.0, y fue una llamada de atención.
Ejecuté Lighthouse en escritorio y móvil. El escritorio devolvió 99 / 91 / 77 / 100 (Performance / Accessibility / Best Practices / SEO). El móvil fue peor: 66 / 91 / 77 / 100. El SEO ya era perfecto, lo que se sintió bien. Todo lo demás necesitaba trabajo.
Los números solos no cuentan la historia. Lo que importa es por qué cada puntaje estaba donde estaba, y lo que eso reveló sobre las decisiones que había estado tomando en piloto automático.
Best Practices: El Ajuste de Cuentas de reCAPTCHA
77 de 100, y la razón fue casi por completo una cosa: cuarenta y nueve cookies de terceros, todas de la infraestructura reCAPTCHA de Google.
Yo no configuré esas cookies. No las pedí. Cargué un script para verificar que los envíos del formulario de contacto provenían de humanos, y ese script trajo todo el aparato de tracking de Google para el viaje. Ese 77 no me estaba diciendo "tus prácticas son mediocres". Me estaba diciendo "cargaste el toolkit de vigilancia de otra persona en tu sitio web personal y no pensaste en lo que eso significa para tus visitantes".
Cloudflare Turnstile fue la solución. Mismo concepto — verificar que el usuario es humano — implementación fundamentalmente diferente. Sin cookies. Sin scripts de tracking. Sin llamar a casa a la infraestructura publicitaria. El widget es ligero, se renderiza en línea, soporta el modo oscuro automático, y la opción size: 'flexible' significa que se adapta a cualquier contenedor en el que lo pongas.
La migración tocó tres archivos: el componente del formulario de contacto (intercambiar la inicialización del widget), el endpoint API (cambiar la URL de verificación) y la configuración del entorno (renombrar las claves). El diff más satisfactorio fue el CSS: sesenta líneas de estilo de la insignia reCAPTCHA, eliminadas. Turnstile simplemente se ve bien desde el principio.
Después del cambio: Best Practices 100.
Performance: Muerte por Mil Scripts
El performance de escritorio ya estaba en 99. El móvil estaba en 66 — una historia muy diferente.
El mayor culpable fue el Total Blocking Time — la cantidad de tiempo que el hilo principal está bloqueado ejecutando JavaScript cuando un usuario podría estar tratando de interactuar. En un escritorio rápido, insignificante. En un procesador móvil, es la diferencia entre una página responsive y una que se siente como si estuviera luchando contra ti.
reCAPTCHA fue parte de esto. 860ms de bloqueo del hilo principal y 178KB de JavaScript, eliminados con el cambio a Turnstile.
Google Tag Manager fue otro golpe. La instalación predeterminada de GTM se carga sincrónicamente en el head del documento, bloqueando todo lo que está debajo. Reescribí el loader para que se difiera hasta la primera interacción del usuario — scroll, click, pulsación de tecla o toque — o un timeout de 3 segundos, lo que ocurra primero. Los analytics todavía capturan todo lo significativo (si alguien interactúa con la página, GTM se carga antes de que haga algo rastreable), pero el renderizado inicial no paga el impuesto.
Google Fonts también estaban bloqueando el renderizado. Cargadas a través de CSS @import, lo que significa que el navegador no puede pintar ningún texto hasta que haya descargado y parseado el archivo de fuente. Cambié a una etiqueta <link rel="preload"> con un controlador onload que intercambia la relación a stylesheet. La fuente se carga asincrónicamente ahora. Breve flash de la fuente de fallback en conexiones muy lentas, pero la página se renderiza inmediatamente en lugar de mirarte con una pantalla en blanco.
React islands fueron la pieza final. El sitio usa la arquitectura de islas de Astro — componentes interactivos de React incrustados en una página estática. Tenía tres componentes usando client:load, lo que significa que se hidratan inmediatamente al cargar la página: el widget DevActivity, el heatmap de Forgejo y la lista de proyectos. Los tres se encuentran muy por debajo del fold. Nadie los ve hasta que se desplaza.
Cambiar a client:visible — que usa IntersectionObserver para diferir la hidratación hasta que el elemento entra en el viewport — redujo significativamente la ejecución inicial de JavaScript. Alrededor de 113KB de JS que se estaban parseando y ejecutando en la carga ahora esperan hasta que realmente te desplaces a esas secciones. En el móvil, donde cada milisegundo de tiempo del hilo principal cuenta, esa diferencia es real.
Accessibility: El HTML Semántico Realmente Importa
91 de 100. Los problemas eran todos estructurales, y todos eran míos.
La jerarquía de encabezados estaba mal. La sección hero tenía un H1 (mi nombre) seguido de un H3 (el subtítulo), saltándose el H2 por completo. Los lectores de pantalla anuncian los niveles de encabezado, y un salto de 1 a 3 señala que falta algo. Los gráficos de DevActivity usaban etiquetas H4 para etiquetas que no eran encabezados de documento en absoluto — solo texto con estilo. La lista de proyectos usaba H5 para los nombres de los proyectos. Mismo problema.
La solución fue ser honesto sobre lo que son las cosas. El subtítulo del hero se convirtió en un H2 con overrides de CSS para mantener el tamaño visual que quería. Las etiquetas de los gráficos y los nombres de los proyectos se convirtieron en elementos <span>, porque eso es lo que son — texto con estilo, no estructura de documento. La jerarquía visual y la jerarquía del documento son cosas diferentes, y las había estado confundiendo.
El modal de contacto tenía aria-labelledby="modal-title", pero nada en el modal tenía id="modal-title". Se le estaba diciendo al lector de pantalla "este diálogo está etiquetado por algo" y no encontraba nada. Añadí el id al encabezado H3 dentro del modal. Un atributo.
El selector de idioma tenía una aria-label que decía "Switch language" — te dice lo que hace el botón pero no qué idioma estás viendo actualmente. Lo cambié para incluir el idioma actual: "EN, switch language". Ahora un usuario de lector de pantalla conoce tanto el estado actual como la acción disponible.
La Migración a Vela
Esta es la grande. El trabajo que ocurrió en v2.15.0 y v2.16.0, y la razón por la que el sitio se ve y se siente fundamentalmente diferente ahora.
Vela es el sistema de diseño de Vector. Lo habíamos estado construyendo en paralelo con los proyectos de los clientes — una librería de componentes compartida, un sistema de tokens y un framework de motion del que cada sitio de VCR puede extraer. El portafolio todavía se ejecutaba en componentes personalizados únicos: ButtonMain, ButtonSecondary, H1, H2, H3, P, TagPill. Cada uno escrito específicamente para este sitio, cada uno ligeramente diferente de lo que estábamos construyendo para los clientes.
La inconsistencia se estaba convirtiendo en un problema. Cada vez que refinaba un patrón en Vela para un proyecto de cliente, el portafolio se alejaba aún más del estándar. Se suponía que el portafolio era el escaparate de Vector, y ni siquiera estaba usando el propio sistema de diseño de Vector.

v2.15.0: El Intercambio Completo
Esta fue una migración quirúrgica. Cada componente base personalizado fue reemplazado con su equivalente de Vela o con HTML raw + utilidades de Tailwind usando las propiedades personalizadas de CSS de Vela. ButtonMain y ButtonSecondary se convirtieron en Button con props de variante. H1 a través de H3 y P se convirtieron en HTML semántico con clases de Tailwind. TagPill se convirtió en Badge.
El ContactForm solo tenía un bloque <style> con scope de 113 líneas — todas las clases CSS personalizadas que duplicaban lo que las utilidades de Tailwind ya manejan. Eliminado y reemplazado con clases de utilidad. Los componentes ForgejoHeatmap, DevActivity y ProjectList se ejecutaban con colores hexadecimales hardcodeados. Migré cada uno de ellos a propiedades personalizadas de CSS de Vela. No quedan colores hardcodeados.

global.css se redujo a un tema Vela puro. Todas las animaciones de keyframe personalizadas — fade-in, slide-up, scale-up, bounce, spin, pulse — eliminadas. Vela Motion se encarga de todo eso ahora.
Cada test de Playwright tuvo que ser actualizado: selectores, aserciones de meta tags, estructura JSON-LD, etiquetas de formulario, espaciado de secciones. Veinticinco componentes de Vela scaffolded y cableados. Esto no fue un reskin — fue un intercambio de base, y nada se rompió.
v2.16.0: Motion y Pulido
Con la base de Vela en su lugar, v2.16.0 se trataba de dar vida al sitio.
Vela Motion reemplazó el sistema personalizado de IntersectionObserver + transición CSS que había hecho a mano en las páginas de índice EN y ES. El enfoque anterior era código duplicado — lógica idéntica de revelación de scroll escrita dos veces. Vela Motion usa atributos data-vela-motion y una única llamada init(). Las secciones ahora se animan con motion-slide-in-bottom a 600ms con curvas ease-out. Un sistema, cero duplicación.
La sección hero recibió una reelaboración. El título cambió de "Founder & Engineering Lead at Vector Costa Rica" a "Full-Stack Developer & Project Rockstar" — menos corporativo, más yo. Los enlaces sociales pasaron de círculos solo de iconos a botones de pill etiquetados (LinkedIn, Bluesky, GitHub, Upwork, Fiverr). El nuevo componente BgFloatingOrbs añade sutiles orbes de gradiente animados detrás del hero. El nuevo componente SkillTooltip muestra proyectos coincidentes cuando pasas el ratón por encima de una habilidad — haz click en uno y se desplaza hacia abajo y expande la tarjeta del proyecto.
El modo oscuro recibió un tratamiento de acento adecuado. El nombre del hero, las value props, los enlaces sociales y los botones CTA ahora se iluminan con un acento verde brillante en el modo oscuro. El barrido de color pasó por cada componente, reemplazando text-accent con text-primary en fondos claros (accesibilidad — los colores de acento no siempre tienen suficiente contraste en blanco) y manteniendo el acento para el modo oscuro donde destaca.
Todo el barrido de color, la reescritura de la copia y la alineación de los componentes ocurrieron a través de múltiples commits enfocados. Al final, el sitio se sintió cohesivo de una manera que no lo había hecho antes — no porque ningún cambio individual fuera dramático, sino porque todo finalmente estaba extrayendo del mismo sistema.
Lo Que Esto Realmente Me Enseñó
Cinco meses y diecinueve releases. Esto es lo que se quedó.
Lighthouse es un espejo, no una calificación. Los números no importan de forma aislada. Lo que importa es lo que sacan a la superficie sobre tus decisiones. Un 77 en Best Practices no era una puntuación — era una señal de que había cargado cuarenta y nueve cookies en mi sitio sin cuestionar por qué. Un 66 en Performance móvil no se trataba de código lento — se trataba de cargar JavaScript que nadie necesitaba hasta que se desplazaba.
Los scripts de terceros son deuda que no escribiste. Cada script externo que cargas es el código de otra persona, que sirve a los intereses de otra persona, con características de performance que no puedes controlar. reCAPTCHA funcionó bien para la protección contra bots. También inyectó la infraestructura de tracking de Google en mi portafolio personal. Esa no es una elección técnica — es una elección de valores que había estado haciendo en piloto automático.
La mejor optimización es la eliminación. Cada victoria de performance que realmente movió la aguja fue una eliminación. Eliminar reCAPTCHA. Eliminar la carga síncrona de fuentes. Eliminar la hidratación eager para los componentes below-fold. Eliminar el bloqueo de GTM. El sitio se hizo más rápido haciendo menos, no haciendo las cosas de forma más inteligente.
Tu propio sistema de diseño cambia el juego. Antes de Vela, cada decisión de UI era local a cualquier componente en el que estuviera trabajando. Después de Vela, cada decisión se retroalimenta en un sistema compartido. Arregla una variante de botón una vez, se arregla en todas partes — este sitio, sitios de clientes, proyectos futuros. La migración fue dolorosa (veinticinco componentes scaffolded, cada test reescrito), pero la recompensa se está acumulando. Ya no estoy escribiendo CSS único. Estoy construyendo infraestructura.
La consistencia de la infraestructura supera la inteligencia por proyecto. dotenvx para secretos encriptados en un sitio de portafolio es más ceremonia de lo estrictamente necesario. El patrón de Dockerfile de build de Bun / runtime de Node es más pesado que un simple npm run build. Pero usar el mismo flujo de trabajo en cada proyecto de Vector — desde este portafolio hasta Orion y las aplicaciones de los clientes — significa que nunca pierdo tiempo recordando "¿cómo funciona este repo?" La sobrecarga cognitiva de la inconsistencia siempre cuesta más que un proceso estándar ligeramente más pesado.
Un portafolio nunca está terminado. Dije esto en v2.0 y lo digo de nuevo en v2.16.1. El sitio en octubre era bueno. El sitio ahora es mensurablemente mejor en formas que no podría haber predicho hace cinco meses: un dashboard de estadísticas de desarrollo personalizado, un blog completo respaldado por nuestro propio CMS, imágenes CDN responsive, secretos encriptados, puntajes perfectos de Lighthouse, una migración de sistema de diseño, animaciones de scroll, tooltips de habilidades y un codebase que ha perdido 45MB de peso muerto. Nada de eso fue planeado. Todo vino de tratar el sitio como un producto, ejecutar auditorías, integrar sistemas que estaba construyendo para otros proyectos y prestar atención a lo que se sentía mal.
Dónde Se Encuentra
El estado actual, para que conste:
- Lighthouse: 99 Performance (escritorio), 100 Accessibility, 100 Best Practices, 100 SEO
- Sistema de diseño: Migración completa a Vela — componentes, tokens, motion, cero keyframes personalizados
- Protección contra spam: Cloudflare Turnstile, cero cookies, lazy-loaded
- Analytics: GA4 + GTM con 16 eventos personalizados, carga diferida
- Blog: Integración completa de Orion CMS con imágenes Lyra CDN responsive, filtrado de tags, barra lateral de archivo
- Estadísticas de desarrollo: Widget en vivo con heatmap de Forgejo, gráficos de velocidad, auto-refresh, insignias de diff
- Secretos: dotenvx encriptado en reposo, desencriptado en tiempo de ejecución
- Infraestructura: Bun build / Node runtime Docker, health checks, contenedor no root, auto-deploy de Coolify
- Codebase: Arquitectura de componentes de tres niveles de Vela, reducción del 93% del historial de git, cero dependencias muertas
¿Está terminado? No. Siempre hay lo siguiente. Más contenido del blog (escribir regularmente es un hábito que todavía estoy construyendo). Edge caching para las respuestas de la API. Tal vez service workers para el soporte offline. La sección DevActivity podría mostrar más detalles sobre proyectos específicos. Vela en sí sigue evolucionando, y este sitio es siempre el primer lugar donde aterrizan nuevos patrones.
Pero la base es sólida. La arquitectura es limpia. El sistema de diseño es compartido. El pipeline de despliegue es fiable. Lo que venga después se basa en un terreno en el que confío.
Diecinueve releases, cinco meses y muchas lecciones aprendidas. Eso es lo que realmente parece construir en público — no un post de lanzamiento y luego silencio, sino un largo flujo de pequeñas mejoras, cada una haciendo que todo sea un poco mejor de lo que era ayer.