<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>DevLog</title><description>Artículos sobre desarrollo web, tecnología y proyectos.</description><link>http://localhost:4321/</link><language>es</language><item><title>Ciberseguridad en 2026: amenazas emergentes y qué deben saber los desarrolladores web</title><link>http://localhost:4321/blog/ciberseguridad-2026-amenazas/</link><guid isPermaLink="true">http://localhost:4321/blog/ciberseguridad-2026-amenazas/</guid><description>Un análisis completo de las principales tendencias de ciberseguridad para 2026 y cómo los desarrolladores web pueden adaptarse.</description><pubDate>Fri, 22 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Ciberseguridad en 2026: amenazas emergentes y qué deben saber los desarrolladores web&lt;/h2&gt;
&lt;p&gt;La ciberseguridad ya no es un tema solo para equipos especializados: &lt;strong&gt;las amenazas evolucionan tan rápido que cualquier desarrollador web moderno debe entenderlas y mitigarlas&lt;/strong&gt;. En 2026, varios vectores de ataque nuevos y tecnologías defensivas están cambiando la forma en que construimos, desplegamos y mantenemos aplicaciones — y eso incluye tus proyectos web.&lt;/p&gt;
&lt;p&gt;En este post profundizamos en las &lt;strong&gt;tendencias claves de amenazas en 2026&lt;/strong&gt;, con ejemplos actuales, implicaciones para devs y recomendaciones prácticas.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;1. AI y agentes autónomos redefinen la seguridad&lt;/h2&gt;
&lt;p&gt;Una de las tendencias más notables es el auge de los &lt;strong&gt;ataques y defensas automatizados mediante IA&lt;/strong&gt;. En 2026, los actores maliciosos ya no dependen únicamente de herramientas tradicionales o scripts: están utilizando &lt;em&gt;&lt;strong&gt;agentes inteligentes que actúan de forma autónoma&lt;/strong&gt;&lt;/em&gt; para encontrar vulnerabilidades, escalar ataques o engañar sistemas de seguridad.&lt;/p&gt;
&lt;p&gt;Por ejemplo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Los agentes pueden &lt;strong&gt;automatizar reconocimiento y explotación&lt;/strong&gt; de fallos.&lt;/li&gt;
&lt;li&gt;Pueden &lt;em&gt;suplantar usuarios&lt;/em&gt; o &lt;em&gt;simular patrones de comportamiento&lt;/em&gt; para engañar sistemas de detección.&lt;/li&gt;
&lt;li&gt;A la defensiva, los equipos de seguridad usan IA para &lt;strong&gt;escaneo continuo y respuesta automática&lt;/strong&gt; en producción.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;¿Qué significa para ti como desarrollador?&lt;/strong&gt;
No basta con barreras estáticas (firewalls, WAF o filtros básicos): necesitas integrar defensas dinámicas y &lt;strong&gt;monitorización continua&lt;/strong&gt; que puedan detectar y responder a amenazas en tiempo real.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;2. Deepfakes y ataques de suplantación avanzados&lt;/h2&gt;
&lt;p&gt;La tecnología deepfake no solo es noticia en redes sociales: &lt;strong&gt;puede utilizarse para ingeniería social sofisticada&lt;/strong&gt;, como engañar a usuarios o empleados con llamadas o vídeos falsos para obtener credenciales o acceso interno.&lt;/p&gt;
&lt;p&gt;Esto tiene impacto directo en aplicaciones web cuando:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;los usuarios son &lt;em&gt;engañados para revelar datos sensibles&lt;/em&gt;,&lt;/li&gt;
&lt;li&gt;se interceptan comunicaciones para saltarse autenticaciones,&lt;/li&gt;
&lt;li&gt;o se manipulan flujos de login con identidades falsificadas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Mitigación práctica&lt;/strong&gt;
Implementa autenticación multifactor (&lt;em&gt;2FA/Passwordless&lt;/em&gt;), verifica identidad por más de un canal y regula la duración de tokens y sesiones para reducir el riesgo de suplantación.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;3. Ransomware sigue creciendo con mayor sofisticación&lt;/h2&gt;
&lt;p&gt;El ransomware —software que cifra datos o sistemas y exige rescate— &lt;strong&gt;no solo sigue creciendo, sino que lo hace con tácticas más inteligentes&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;exfiltración de datos antes del cifrado para extorsión dual,&lt;/li&gt;
&lt;li&gt;ataques dirigidos a backups y sistemas de recuperación,&lt;/li&gt;
&lt;li&gt;herramientas de &amp;quot;ransomware as a service&amp;quot; que facilitan ataques incluso a actores sin habilidades profundas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;¿Cómo te afecta como dev web?&lt;/strong&gt;
Aunque no construyas infraestructuras completas, tus aplicaciones pueden ser punto de entrada o vector para estos ataques si:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;tus APIs no tienen límites de acceso,&lt;/li&gt;
&lt;li&gt;manejas mal la gestión de sesiones,&lt;/li&gt;
&lt;li&gt;o no validas correctamente entradas de usuario.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;4. Software supply chain y dependencias inseguras&lt;/h2&gt;
&lt;p&gt;La cadena de suministro de software sigue siendo una de las áreas más vulnerables. Vulnerabilidades en dependencias (librerías, paquetes npm, componentes de terceros) pueden abrir puertas sin que tú mismo lo sepas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;librerías desactualizadas o abandonadas,&lt;/li&gt;
&lt;li&gt;malwares incrustados en paquetes populares,&lt;/li&gt;
&lt;li&gt;cadenas de herramientas que pasan código sin revisión.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Buenas prácticas de protección&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Usa &lt;em&gt;lockfiles&lt;/em&gt; y revisa versiones con herramientas como Dependabot o Renovate.&lt;/li&gt;
&lt;li&gt;Implementa &lt;em&gt;SCA&lt;/em&gt; (Software Composition Analysis) en tu CI/CD.&lt;/li&gt;
&lt;li&gt;Audita tus dependencias regularmente, no solo al inicio del proyecto.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;5. Identidad como nuevo perímetro de seguridad&lt;/h2&gt;
&lt;p&gt;Los modelos tradicionales de seguridad basados en redes perimetrales están siendo reemplazados por enfoques donde &lt;strong&gt;la identidad del usuario es el nuevo foco principal de defensa&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;¿Por qué? Porque los atacantes usan credenciales robadas, phishing o deepfakes para &lt;em&gt;parecer usuarios legítimos&lt;/em&gt; y así saltarse barreras estáticas.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Recomendaciones para devs&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implementa controles de acceso basados en roles (RBAC).&lt;/li&gt;
&lt;li&gt;Usa autenticación fuerte (MFA, claves físicas, biometría donde sea posible).&lt;/li&gt;
&lt;li&gt;Monitorea patrones de uso anómalos (IPs, dispositivos, geografías).&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;6. API-first architectures y nuevas vulnerabilidades&lt;/h2&gt;
&lt;p&gt;Las APIs se han convertido en el &lt;em&gt;núcleo de casi todas las aplicaciones modernas&lt;/em&gt;. Eso las convierte en un blanco principal: ataques dirigidos a endpoints, fuga de datos y abusos de recursos se intensifican.&lt;/p&gt;
&lt;p&gt;Algunas tendencias destacadas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;ataques DDoS orientados a APIs con lógica compleja,&lt;/li&gt;
&lt;li&gt;búsqueda de endpoints mal documentados o sin autenticación,&lt;/li&gt;
&lt;li&gt;APIs internas expuestas indirectamente por configuraciones erróneas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Qué hacer&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Asegura tus APIs con OAuth/OpenID Connect o JWT bien configurado.&lt;/li&gt;
&lt;li&gt;Limita el &lt;em&gt;rate&lt;/em&gt; de peticiones y habilita WAF/WAAP.&lt;/li&gt;
&lt;li&gt;Haz revisiones de seguridad automatizadas (Scanner API, fuzzing).&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;7. Integración DevSecOps como estándar&lt;/h2&gt;
&lt;p&gt;El desarrollo moderno ya no puede separar el desarrollo de la seguridad: &lt;strong&gt;DevSecOps se está convirtiendo en la norma&lt;/strong&gt;. Eso significa que desde el primer commit hasta el despliegue y el mantenimiento, &lt;strong&gt;las prácticas de seguridad deben integrarse en cada paso&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Esto incluye:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;escaneo de código estático (SAST),&lt;/li&gt;
&lt;li&gt;análisis de dependencias (SCA),&lt;/li&gt;
&lt;li&gt;pruebas dinámicas de aplicación (DAST),&lt;/li&gt;
&lt;li&gt;y monitores en producción con alertas automáticas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Integrar estas herramientas en tu pipeline CI/CD &lt;strong&gt;reduce bugs y vulnerabilidades antes de que lleguen a producción&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;En 2026, la seguridad ya no es un simple &amp;quot;tema aparte&amp;quot;: es una &lt;strong&gt;parte esencial de cualquier ciclo de vida de desarrollo web&lt;/strong&gt;. Con amenazas cada vez más automatizadas, sofisticadas y basadas en IA, los desarrolladores que entienden y aplican prácticas defensivas están un paso por delante.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Invertir tiempo en aprender sobre ciberseguridad desde autenticación robusta y API hardening hasta pipelines de DevSecOps ya no es opcional; es crucial para mantener tus proyectos y usuarios seguros.&lt;/em&gt;&lt;/p&gt;
</content:encoded><category>IA</category><category>DevSecOps</category><category>Seguridad</category><category>Desarrollo web</category><category>Ciberseguridad</category><author>Hugo Cayón Laso</author></item><item><title>Menta: Por qué creé mi propio gestor de tiempo para el trabajo</title><link>http://localhost:4321/blog/menta-gestor-de-tiempo/</link><guid isPermaLink="true">http://localhost:4321/blog/menta-gestor-de-tiempo/</guid><description>Cansado de la fricción al registrar tiempos por tickets, decidí crear Menta: una solución rápida, centralizada y con estética minimalista.</description><pubDate>Thu, 21 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;El problema de los tickets y el registro de horas&lt;/h2&gt;
&lt;p&gt;Si trabajas en desarrollo, soporte o cualquier sector basado en tareas, conocerás este problema: al final del día (o de la semana), tienes que &lt;strong&gt;registrar cuánto tiempo has dedicado a cada ticket o tarea&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Muchas herramientas corporativas son lentas, farragosas o requieren demasiados clics. En mi día a día, sentía que perdía el hilo de lo que estaba haciendo solo por intentar anotar cuándo empezaba y cuándo terminaba. Necesitaba algo que fuera &lt;strong&gt;instantáneo&lt;/strong&gt;, y como no lo encontraba, decidí construirlo.&lt;/p&gt;
&lt;p&gt;Así nace &lt;strong&gt;Menta&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Por qué decidí crear Menta&lt;/h2&gt;
&lt;p&gt;La idea principal era eliminar cualquier tipo de fricción. Quería una aplicación centralizada donde el flujo fuera lo más simple y rápido posible:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Escribir el &lt;strong&gt;nombre del ticket&lt;/strong&gt; y pegar el &lt;strong&gt;link directo&lt;/strong&gt; a la tarea.&lt;/li&gt;
&lt;li&gt;Darle a empezar.&lt;/li&gt;
&lt;li&gt;Tener un historial claro con los &lt;strong&gt;tiempos exactos de inicio y fin&lt;/strong&gt; para luego pasarlos a la plataforma oficial de la empresa sin errores.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;He buscado crear una herramienta que no te obligue a pensar en ella. Menta está ahí para servirte, registrar el dato y dejarte seguir con tu trabajo real.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Privacidad total: Tus datos son solo tuyos&lt;/h2&gt;
&lt;p&gt;Uno de los pilares de Menta es la &lt;strong&gt;seguridad y la privacidad&lt;/strong&gt;. He desarrollado esta herramienta como una aplicación &lt;strong&gt;puramente frontend&lt;/strong&gt;. ¿Qué significa esto para ti?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Sin base de datos externa:&lt;/strong&gt; No hay un servidor central guardando lo que escribes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Almacenamiento local:&lt;/strong&gt; Todos los nombres de tareas, enlaces y registros de tiempo se guardan exclusivamente en el &lt;strong&gt;almacenamiento local de tu navegador (LocalStorage)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Privacidad por diseño:&lt;/strong&gt; Al no haber backend, tus datos nunca viajan por internet ni salen de tu equipo.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;Diseñada para la velocidad y la simplicidad&lt;/h2&gt;
&lt;p&gt;Cuando estás en medio de una jornada intensa, no quieres configurar proyectos complejos ni rellenar formularios infinitos. Por eso, Menta destaca en tres aspectos:&lt;/p&gt;
&lt;h3&gt;Registro centralizado y rápido&lt;/h3&gt;
&lt;p&gt;Simplemente introduces el identificador de tu tarea y empiezas. No hay menús desplegables innecesarios ni cargas tediosas. Si tienes el link del ticket, lo pegas y listo. Al final del día, tu historial es una lista limpia de todo lo que has hecho, con el &lt;strong&gt;minuto exacto en el que empezaste y terminaste&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Control total del tiempo&lt;/h3&gt;
&lt;p&gt;A veces sabes que un ticket te llevará exactamente 25 minutos; otras veces, necesitas un cronómetro abierto. Menta te ofrece ambos mundos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Botones rápidos&lt;/strong&gt; para sesiones estándar de 15, 25, 30, 45 o 60 minutos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Entrada manual&lt;/strong&gt; para cualquier duración entre 1 y 180 minutos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Todo esto bajo una lógica de pausa y reanudación que calcula automáticamente el tiempo real trabajado, evitando que los errores de cálculo arruinen tu registro de jornada.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Estética &amp;quot;Menta&amp;quot; para el enfoque profundo&lt;/h2&gt;
&lt;p&gt;El diseño no es solo una capa de pintura. He elegido una estética de &lt;strong&gt;modo oscuro con toques verde menta&lt;/strong&gt; por una razón específica: la calma.&lt;/p&gt;
&lt;p&gt;Cuando trabajas con tickets estresantes, tener una interfaz oscura con un color de acento fresco ayuda a mantener la cabeza fría. El contraste es el justo para ser legible sin ser agresivo, permitiendo que la app viva en una pantalla secundaria sin distraerte de tu editor de código o de tu herramienta principal.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;¿Qué puedes esperar de Menta?&lt;/h2&gt;
&lt;p&gt;En esta primera versión disponible, Menta ya te permite:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Asignar nombres y enlaces&lt;/strong&gt; a cada sesión de trabajo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Visualizar un historial detallado&lt;/strong&gt; con fecha, hora de comienzo y hora de finalización.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Administrar sesiones&lt;/strong&gt; de forma flexible y sin esperas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gestión local y segura&lt;/strong&gt;, todo lo que ves se queda en tu navegador.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mi objetivo era crear la herramienta más rápida y simple para los que, como yo, necesitan centralizar sus tiempos de trabajo sin complicaciones. Si alguna vez has olvidado a qué hora empezaste aquel ticket tan importante, Menta es para ti.&lt;/p&gt;
&lt;p&gt;¡Espero que esta herramienta os resulte tan útil como me está resultando a mí en mi día a día!&lt;/p&gt;
</content:encoded><category>Proyectos</category><category>Menta</category><category>Workflow</category><category>Herramientas</category><category>Desarrollo</category><category>Productividad</category><author>Hugo Cayón Laso</author></item><item><title>Cookies, localStorage y sessionStorage: diferencias, usos y cuándo elegir cada uno</title><link>http://localhost:4321/blog/cookies-localstorage-sessionstorage/</link><guid isPermaLink="true">http://localhost:4321/blog/cookies-localstorage-sessionstorage/</guid><description>Los tres sirven para guardar datos en el navegador, pero funcionan de forma muy distinta.</description><pubDate>Mon, 18 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;El navegador ofrece tres formas de guardar datos en el cliente: cookies, &lt;code&gt;localStorage&lt;/code&gt; y &lt;code&gt;sessionStorage&lt;/code&gt;. Los tres hacen algo parecido a simple vista, pero tienen comportamientos, límites y implicaciones de seguridad muy distintos.&lt;/p&gt;
&lt;p&gt;Elegir el equivocado puede ser un bug difícil de encontrar, o peor, una vulnerabilidad de seguridad.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Cookies&lt;/h2&gt;
&lt;p&gt;Las cookies son el mecanismo más antiguo y el más potente, aunque también el más complejo. Se inventaron en 1994 y siguen siendo la base de la autenticación en la mayoría de las webs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cómo funcionan:&lt;/strong&gt; el servidor puede establecer una cookie en la respuesta HTTP. El navegador la guarda y la envía automáticamente en cada petición posterior al mismo dominio. El servidor también puede leerla y modificarla.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;HTTP/1.1 200 OK
Set-Cookie: session_id=abc123; HttpOnly; Secure; SameSite=Lax; Max-Age=86400
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Lo que las hace únicas:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Las envía el navegador &lt;strong&gt;automáticamente&lt;/strong&gt; en cada petición. No tienes que hacer nada en JavaScript.&lt;/li&gt;
&lt;li&gt;El &lt;strong&gt;servidor&lt;/strong&gt; puede crearlas y leerlas, no solo el cliente.&lt;/li&gt;
&lt;li&gt;Tienen fecha de expiración configurable.&lt;/li&gt;
&lt;li&gt;Se pueden restringir a un dominio y a una ruta específica.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Capacidad:&lt;/strong&gt; ~4 KB por cookie.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cuándo usarlas:&lt;/strong&gt; sesiones de usuario, autenticación, preferencias que el servidor necesita conocer.&lt;/p&gt;
&lt;h3&gt;Atributos de seguridad importantes&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-http&quot;&gt;Set-Cookie: token=xyz; 
  HttpOnly;    /* JavaScript no puede leerla */
  Secure;      /* Solo se envía por HTTPS */
  SameSite=Lax /* Protección contra CSRF */
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;HttpOnly&lt;/code&gt;&lt;/strong&gt;: impide que JavaScript acceda a la cookie con &lt;code&gt;document.cookie&lt;/code&gt;. Protege contra XSS.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;Secure&lt;/code&gt;&lt;/strong&gt;: la cookie solo viaja por HTTPS, nunca por HTTP.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;SameSite&lt;/code&gt;&lt;/strong&gt;: controla cuándo se envía la cookie en peticiones cross-site. &lt;code&gt;Lax&lt;/code&gt; es el equilibrio razonable; &lt;code&gt;Strict&lt;/code&gt; es más seguro pero puede romper flujos de OAuth.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;localStorage&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;localStorage&lt;/code&gt; es una API de JavaScript para guardar datos en el navegador de forma persistente. Los datos no tienen fecha de expiración y no se borran al cerrar el navegador ni el sistema.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;// Guardar
localStorage.setItem(&amp;#39;tema&amp;#39;, &amp;#39;oscuro&amp;#39;);
localStorage.setItem(&amp;#39;usuario&amp;#39;, JSON.stringify({ nombre: &amp;#39;Hugo&amp;#39;, rol: &amp;#39;admin&amp;#39; }));

// Leer
const tema = localStorage.getItem(&amp;#39;tema&amp;#39;);
const usuario = JSON.parse(localStorage.getItem(&amp;#39;usuario&amp;#39;));

// Borrar
localStorage.removeItem(&amp;#39;tema&amp;#39;);
localStorage.clear(); // borra todo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Características:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Persiste indefinidamente hasta que se borra explícitamente.&lt;/li&gt;
&lt;li&gt;Solo accesible desde JavaScript (el servidor no lo ve).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No se envía al servidor&lt;/strong&gt; en cada petición.&lt;/li&gt;
&lt;li&gt;Compartido entre todas las pestañas del mismo origen.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Capacidad:&lt;/strong&gt; ~5-10 MB según el navegador.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cuándo usarlo:&lt;/strong&gt; preferencias de usuario (tema claro/oscuro), borradores guardados localmente, datos de la app que no necesita el servidor.&lt;/p&gt;
&lt;h3&gt;El error más común con localStorage&lt;/h3&gt;
&lt;p&gt;Guardar tokens de autenticación en &lt;code&gt;localStorage&lt;/code&gt; es una mala práctica extendida:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;// MAL: el token queda expuesto a cualquier script de la página
localStorage.setItem(&amp;#39;auth_token&amp;#39;, token);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cualquier script de terceros (analytics, widgets, librerías comprometidas) puede leer &lt;code&gt;localStorage&lt;/code&gt;. Si hay una vulnerabilidad XSS, el atacante roba el token con una línea de JavaScript. Una cookie &lt;code&gt;HttpOnly&lt;/code&gt; no tiene ese problema porque JavaScript directamente no puede acceder a ella.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;sessionStorage&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;sessionStorage&lt;/code&gt; funciona igual que &lt;code&gt;localStorage&lt;/code&gt; en la API, con una diferencia clave: &lt;strong&gt;los datos se borran cuando se cierra la pestaña&lt;/strong&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;sessionStorage.setItem(&amp;#39;paso_actual&amp;#39;, &amp;#39;2&amp;#39;);
const paso = sessionStorage.getItem(&amp;#39;paso_actual&amp;#39;);
sessionStorage.removeItem(&amp;#39;paso_actual&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Características:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Se borra al cerrar la pestaña (no la ventana del navegador completa).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;No se comparte entre pestañas&lt;/strong&gt;, aunque sean del mismo origen.&lt;/li&gt;
&lt;li&gt;Solo accesible desde JavaScript.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Capacidad:&lt;/strong&gt; ~5-10 MB.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cuándo usarlo:&lt;/strong&gt; estado temporal de un formulario multipaso, datos de una sesión de compra que no deben persistir, cualquier cosa que solo tiene sentido mientras el usuario está en esa pestaña concreta.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Comparativa directa&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Cookies&lt;/th&gt;
&lt;th&gt;localStorage&lt;/th&gt;
&lt;th&gt;sessionStorage&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Capacidad&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;~4 KB&lt;/td&gt;
&lt;td&gt;~5-10 MB&lt;/td&gt;
&lt;td&gt;~5-10 MB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Persistencia&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Configurable&lt;/td&gt;
&lt;td&gt;Permanente&lt;/td&gt;
&lt;td&gt;Solo la pestaña&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Acceso servidor&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sí (automático)&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Acceso JS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sí (salvo HttpOnly)&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Compartido entre pestañas&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Se envía en peticiones&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Sí&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;Guía de decisión rápida&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;¿El servidor necesita los datos?&lt;/strong&gt;
→ Cookie.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;¿Son datos de autenticación?&lt;/strong&gt;
→ Cookie con &lt;code&gt;HttpOnly&lt;/code&gt; y &lt;code&gt;Secure&lt;/code&gt;. Nunca &lt;code&gt;localStorage&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;¿Son preferencias del usuario que deben persistir entre sesiones?&lt;/strong&gt;
→ &lt;code&gt;localStorage&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;¿Son datos temporales que solo tienen sentido en esta pestaña?&lt;/strong&gt;
→ &lt;code&gt;sessionStorage&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;¿Necesitas más de 4 KB en el cliente y el servidor no los necesita?&lt;/strong&gt;
→ &lt;code&gt;localStorage&lt;/code&gt; o &lt;code&gt;sessionStorage&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Las tres opciones existen porque resuelven problemas distintos. La elección incorrecta no siempre rompe la funcionalidad de inmediato, pero puede crear problemas de seguridad o de experiencia de usuario que son difíciles de diagnosticar.&lt;/p&gt;
&lt;p&gt;La regla más importante: &lt;strong&gt;nunca guardes tokens de sesión o credenciales en &lt;code&gt;localStorage&lt;/code&gt;&lt;/strong&gt;. Para eso están las cookies con los atributos de seguridad adecuados.&lt;/p&gt;
</content:encoded><category>Desarrollo web</category><category>Seguridad</category><category>Frontend</category><category>JavaScript</category><author>Hugo Cayón Laso</author></item><item><title>Bun: el runtime JavaScript que quiere reemplazar a Node.js</title><link>http://localhost:4321/blog/bun-runtime-javascript/</link><guid isPermaLink="true">http://localhost:4321/blog/bun-runtime-javascript/</guid><description>Bun no es solo un runtime más rápido. Es un intento de rediseñar el ecosistema JavaScript desde cero: runtime, gestor de paquetes, bundler y test runner en uno solo.</description><pubDate>Mon, 18 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Node.js lleva más de quince años siendo el runtime JavaScript por defecto fuera del navegador. Deno intentó reemplazarlo hace unos años con una apuesta por la seguridad y los estándares web. Ahora hay un tercer competidor que está generando mucho más ruido: &lt;strong&gt;Bun&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;¿Qué hace diferente a Bun? ¿Deberías aprender a usarlo? ¿Vale la pena migrar proyectos existentes?&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Qué es Bun&lt;/h2&gt;
&lt;p&gt;Bun es un runtime de JavaScript y TypeScript construido desde cero, diseñado para ser extremadamente rápido. A diferencia de Node.js (que usa el motor V8 de Chrome) o Deno (que también usa V8), Bun usa &lt;strong&gt;JavaScriptCore&lt;/strong&gt;, el motor del navegador Safari de Apple, que en ciertos escenarios tiene un tiempo de arranque significativamente menor.&lt;/p&gt;
&lt;p&gt;Pero la velocidad del motor es solo una parte. Lo que hace a Bun ambicioso es que &lt;strong&gt;no es solo un runtime&lt;/strong&gt;. Es todo esto a la vez:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Runtime&lt;/strong&gt; de JavaScript/TypeScript&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gestor de paquetes&lt;/strong&gt; (alternativa a npm/pnpm/yarn)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bundler&lt;/strong&gt; (alternativa a webpack/esbuild/vite)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Test runner&lt;/strong&gt; (alternativa a Jest/Vitest)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Un solo binario para hacer lo que antes requería cuatro herramientas distintas.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Por qué es tan rápido&lt;/h2&gt;
&lt;p&gt;Bun está escrito en &lt;strong&gt;Zig&lt;/strong&gt;, un lenguaje de sistemas de bajo nivel (comparable a C o Rust en términos de rendimiento). Esto le permite tener un control muy fino sobre la memoria y las operaciones del sistema operativo.&lt;/p&gt;
&lt;p&gt;Las diferencias de velocidad frente a Node.js son llamativas en algunos escenarios:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Inicio más rápido:&lt;/strong&gt; los scripts arrancan hasta 4× más rápido, lo que importa especialmente en entornos serverless o CLIs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Instalación de paquetes:&lt;/strong&gt; el gestor de paquetes de Bun puede ser 10-25× más rápido que npm gracias a que mantiene una caché global de paquetes en formato binario.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Servidor HTTP:&lt;/strong&gt; en benchmarks de servidores HTTP simples, Bun supera a Node.js de forma consistente.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Dicho esto, los benchmarks siempre miden escenarios ideales. En una aplicación real con base de datos, lógica de negocio compleja y dependencias de terceros, la diferencia es menos pronunciada.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Instalación y primeros pasos&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# macOS y Linux
curl -fsSL https://bun.sh/install | bash

# Verificar instalación
bun --version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Desde ese momento tienes acceso a todos los comandos:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;bun run index.ts        # Ejecutar un archivo TypeScript directamente
bun install             # Instalar dependencias (lee el package.json)
bun add express         # Añadir un paquete
bun test                # Ejecutar tests
bun build ./index.ts    # Bundlear para producción
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;TypeScript de serie, sin configuración&lt;/h2&gt;
&lt;p&gt;Una de las cosas más cómodas de Bun es que ejecuta TypeScript directamente, sin necesidad de compilar primero ni de configurar &lt;code&gt;ts-node&lt;/code&gt; o &lt;code&gt;tsx&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;// server.ts
const server = Bun.serve({
  port: 3000,
  fetch(req) {
    return new Response(&amp;quot;Hola desde Bun&amp;quot;);
  },
});

console.log(`Servidor en http://localhost:${server.port}`);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;bun run server.ts  # funciona directamente
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esto elimina un paso de configuración que en Node.js siempre ha sido algo engorroso.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Compatibilidad con Node.js&lt;/h2&gt;
&lt;p&gt;Bun implementa las APIs de Node.js más comunes: &lt;code&gt;fs&lt;/code&gt;, &lt;code&gt;path&lt;/code&gt;, &lt;code&gt;http&lt;/code&gt;, &lt;code&gt;crypto&lt;/code&gt;, &lt;code&gt;stream&lt;/code&gt;... El objetivo es que la mayoría del código Node.js existente funcione sin modificaciones.&lt;/p&gt;
&lt;p&gt;En la práctica la compatibilidad es muy alta pero no perfecta. Algunos paquetes que dependen de módulos nativos (&lt;code&gt;.node&lt;/code&gt; files) o de partes muy específicas de la API de Node.js pueden necesitar ajustes.&lt;/p&gt;
&lt;p&gt;También es compatible con los módulos de npm: el &lt;code&gt;package.json&lt;/code&gt; sigue siendo el formato estándar y puedes instalar cualquier paquete del registro de npm.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;El test runner integrado&lt;/h2&gt;
&lt;p&gt;Bun incluye su propio test runner con una API compatible con Jest:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-typescript&quot;&gt;import { describe, it, expect } from &amp;quot;bun:test&amp;quot;;

describe(&amp;quot;suma&amp;quot;, () =&amp;gt; {
  it(&amp;quot;suma dos números&amp;quot;, () =&amp;gt; {
    expect(1 + 2).toBe(3);
  });

  it(&amp;quot;gestiona negativos&amp;quot;, () =&amp;gt; {
    expect(-1 + -1).toBe(-2);
  });
});
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;bun test
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El test runner es significativamente más rápido que Jest porque no necesita transpilación previa. Si ya tienes tests escritos con Jest, la migración suele requerir pocos cambios.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;¿Deberías usarlo ahora?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Sí, tiene sentido si:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Estás empezando un proyecto nuevo y quieres un ecosistema más simple.&lt;/li&gt;
&lt;li&gt;Tienes CLIs o scripts donde el tiempo de arranque importa.&lt;/li&gt;
&lt;li&gt;Quieres ejecutar TypeScript sin fricción.&lt;/li&gt;
&lt;li&gt;Quieres consolidar herramientas (npm + bundler + test runner → Bun).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Tómalo con calma si:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Tienes un proyecto en producción con dependencias nativas o un stack muy específico de Node.js.&lt;/li&gt;
&lt;li&gt;Tu equipo no está familiarizado con herramientas fuera del ecosistema Node estándar.&lt;/li&gt;
&lt;li&gt;Usas servicios de hosting que aún no tienen soporte oficial para Bun.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;El estado actual&lt;/h2&gt;
&lt;p&gt;Bun lanzó su versión 1.0 en septiembre de 2023, lo que significa que ya no es un experimento. Ha tenido una adopción creciente, especialmente en proyectos de nueva creación y en la comunidad de desarrolladores que trabajan mucho con TypeScript.&lt;/p&gt;
&lt;p&gt;El ecosistema sigue madurando: la compatibilidad con Node.js mejora en cada versión, la documentación se ha vuelto más completa y el soporte de plataformas de despliegue (Fly.io, Railway, Render) ha aumentado.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Bun no es hype vacío. Resuelve frustraciones reales del ecosistema JavaScript: la lentitud de npm, la fricción para usar TypeScript en Node.js, la necesidad de configurar demasiadas herramientas para empezar un proyecto.&lt;/p&gt;
&lt;p&gt;Si lo pruebas en un proyecto personal o en un script, probablemente te sorprenderá lo fluido que resulta. Si estás evaluando adoptarlo en producción, la ecuación depende mucho de tu stack actual y de las dependencias que uses.&lt;/p&gt;
&lt;p&gt;Lo que sí parece claro es que Bun está aquí para quedarse, y su existencia ya ha empujado a Node.js y a npm a mejorar su propio rendimiento. La competencia, en este caso, beneficia a todos.&lt;/p&gt;
</content:encoded><category>Rendimiento</category><category>Backend</category><category>Herramientas</category><category>Node.js</category><category>Bun</category><category>JavaScript</category><author>Hugo Cayón Laso</author></item><item><title>Browser DevTools a fondo: la herramienta que tienes abierta y no aprovechas</title><link>http://localhost:4321/blog/browser-devtools-a-fondo/</link><guid isPermaLink="true">http://localhost:4321/blog/browser-devtools-a-fondo/</guid><description>Las DevTools del navegador son mucho más que un inspector de elementos. Aprende a usar los paneles de red, rendimiento, memoria y aplicación.</description><pubDate>Mon, 18 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Las DevTools del navegador son probablemente la herramienta que más tiempo tienes abierta como desarrollador web. También son probablemente la que menos aprovechas.&lt;/p&gt;
&lt;p&gt;La mayoría usamos el inspector de elementos para ver estilos CSS y la consola para hacer &lt;code&gt;console.log&lt;/code&gt;. Pero detrás de esas dos pestañas hay un conjunto de herramientas de análisis y depuración que pueden ahorrarte horas de trabajo.&lt;/p&gt;
&lt;p&gt;Este artículo cubre Chrome DevTools, aunque Firefox y Edge tienen equivalentes muy similares. Puedes abrirlas con &lt;code&gt;F12&lt;/code&gt; o &lt;code&gt;Cmd+Option+I&lt;/code&gt; en Mac.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Panel Elements: más allá de inspeccionar HTML&lt;/h2&gt;
&lt;p&gt;Todo el mundo conoce el inspector de elementos, pero hay detalles que pasan desapercibidos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Editar el DOM en directo.&lt;/strong&gt; Haz doble clic sobre cualquier nodo para editar su contenido o atributos. Puedes arrastrar nodos para cambiar su orden, eliminarlos con la tecla &lt;code&gt;Delete&lt;/code&gt; o copiar su HTML con clic derecho.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Forzar estados CSS.&lt;/strong&gt; En la pestaña &lt;strong&gt;Styles&lt;/strong&gt;, el botón &lt;code&gt;:hov&lt;/code&gt; te permite forzar estados como &lt;code&gt;:hover&lt;/code&gt;, &lt;code&gt;:focus&lt;/code&gt;, &lt;code&gt;:active&lt;/code&gt; o &lt;code&gt;:visited&lt;/code&gt; sin necesidad de activarlos con el ratón. Imprescindible para depurar estilos de hover.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ver qué estilos se están aplicando realmente.&lt;/strong&gt; La pestaña &lt;strong&gt;Computed&lt;/strong&gt; muestra el valor final calculado de cada propiedad CSS, ya resueltas las especificidades y las herencias. Cuando un estilo no se aplica como esperas, aquí ves por qué.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Buscar en el DOM.&lt;/strong&gt; &lt;code&gt;Ctrl+F&lt;/code&gt; dentro del panel Elements abre un buscador que acepta texto, selectores CSS y expresiones XPath.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Panel Console: más potente de lo que parece&lt;/h2&gt;
&lt;p&gt;La consola no es solo para &lt;code&gt;console.log&lt;/code&gt;. Tiene un conjunto completo de métodos y funciones útiles.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;// Mostrar datos tabulados (ideal para arrays de objetos)
console.table(usuarios);

// Medir tiempo de ejecución
console.time(&amp;#39;operacion&amp;#39;);
hacerAlgo();
console.timeEnd(&amp;#39;operacion&amp;#39;); // → operacion: 12.4ms

// Agrupar mensajes
console.group(&amp;#39;Petición API&amp;#39;);
console.log(&amp;#39;URL:&amp;#39;, url);
console.log(&amp;#39;Respuesta:&amp;#39;, data);
console.groupEnd();

// Mostrar traza de llamadas
console.trace(&amp;#39;desde aquí&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;$0&lt;/code&gt; es el elemento seleccionado.&lt;/strong&gt; Si tienes un elemento seleccionado en el panel Elements, puedes referenciarte a él desde la consola con &lt;code&gt;$0&lt;/code&gt;. &lt;code&gt;$1&lt;/code&gt; es el anterior, &lt;code&gt;$2&lt;/code&gt; el anterior al anterior, hasta &lt;code&gt;$4&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;$(selector)&lt;/code&gt; y &lt;code&gt;$$(selector)&lt;/code&gt;.&lt;/strong&gt; Son atajos de &lt;code&gt;document.querySelector&lt;/code&gt; y &lt;code&gt;document.querySelectorAll&lt;/code&gt; disponibles directamente en la consola.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;$$(&amp;#39;a[href^=&amp;quot;http&amp;quot;]&amp;#39;) // todos los enlaces externos
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;Panel Network: depurar peticiones HTTP&lt;/h2&gt;
&lt;p&gt;El panel Network es donde se ven todas las peticiones que hace tu página: HTML, CSS, JS, imágenes, llamadas a APIs...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Filtrar por tipo.&lt;/strong&gt; Los botones de la barra superior filtran por XHR/Fetch (llamadas a API), JS, CSS, Img, Media. Cuando depuras una llamada a API, activa solo XHR/Fetch para no perderte entre el ruido.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ver el detalle de una petición.&lt;/strong&gt; Haz clic en cualquier petición para ver:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Headers&lt;/strong&gt;: los headers de la request y la response.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Payload&lt;/strong&gt;: el cuerpo de la petición (para POST, PUT...).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Response&lt;/strong&gt;: la respuesta en texto o formateada.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Timing&lt;/strong&gt;: cuánto tiempo tardó cada fase (DNS, conexión, espera, descarga).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Simular conexión lenta.&lt;/strong&gt; El desplegable &amp;quot;No throttling&amp;quot; te permite simular 3G, 4G u otras velocidades. Fundamental para ver cómo se comporta tu app en condiciones reales.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Preserve log.&lt;/strong&gt; Activa esta opción para que el historial de peticiones no se borre al navegar a otra página. Muy útil para depurar flujos que implican redirecciones.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bloquear recursos.&lt;/strong&gt; Clic derecho sobre una petición → &amp;quot;Block request URL&amp;quot;. Puedes probar qué pasa si un script de terceros no carga, o si tu API falla.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Panel Sources: depuración con breakpoints&lt;/h2&gt;
&lt;p&gt;Sources es el depurador de JavaScript. Puedes pausar la ejecución, inspeccionar variables y ejecutar código paso a paso.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Poner un breakpoint.&lt;/strong&gt; Abre un archivo JS y haz clic en el número de línea. La ejecución se pausará cuando llegue a ese punto.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;debugger&lt;/code&gt; en el código.&lt;/strong&gt; Puedes escribir &lt;code&gt;debugger;&lt;/code&gt; directamente en tu JavaScript. El navegador pausará la ejecución ahí si las DevTools están abiertas.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;function calcularPrecio(items) {
  debugger; // el navegador pausará aquí
  return items.reduce((total, item) =&amp;gt; total + item.precio, 0);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Breakpoints condicionales.&lt;/strong&gt; Clic derecho sobre el número de línea → &amp;quot;Add conditional breakpoint&amp;quot;. Solo pausa si se cumple una condición. Perfecto cuando el bug solo ocurre con ciertos datos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Watch expressions.&lt;/strong&gt; En el panel lateral puedes añadir expresiones que se evalúan en tiempo real mientras la ejecución está pausada.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Panel Performance: encontrar por qué tu app va lenta&lt;/h2&gt;
&lt;p&gt;Performance te permite grabar lo que hace el navegador durante un periodo de tiempo y analizar cada milisegundo.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Cómo usarlo:&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Abre el panel Performance.&lt;/li&gt;
&lt;li&gt;Pulsa el botón de grabar (círculo rojo).&lt;/li&gt;
&lt;li&gt;Reproduce la acción que va lenta.&lt;/li&gt;
&lt;li&gt;Para la grabación.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Verás una línea de tiempo con frames por segundo (FPS), llamadas a JavaScript, renderizado, pintura...&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Lo que debes buscar:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Barras rojas en la línea de FPS: frames que tardaron demasiado (janky animation).&lt;/li&gt;
&lt;li&gt;Funciones JavaScript que ocupan demasiado tiempo en la flame chart.&lt;/li&gt;
&lt;li&gt;Recálculos de layout frecuentes (aparecen en morado).&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;Panel Application: storage, cookies y más&lt;/h2&gt;
&lt;p&gt;Este panel te da acceso a todos los datos que la página guarda en el navegador.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Local Storage y Session Storage&lt;/strong&gt;: ver, editar y borrar pares clave-valor.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cookies&lt;/strong&gt;: ver todas las cookies, sus atributos (&lt;code&gt;HttpOnly&lt;/code&gt;, &lt;code&gt;Secure&lt;/code&gt;, &lt;code&gt;SameSite&lt;/code&gt;) y su valor.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cache Storage&lt;/strong&gt;: archivos almacenados por Service Workers.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IndexedDB&lt;/strong&gt;: base de datos estructurada del navegador.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Desde aquí también puedes forzar la actualización de un Service Worker o limpiar todos los datos almacenados con el botón &amp;quot;Clear site data&amp;quot;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Atajos que vale la pena memorizar&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Atajo&lt;/th&gt;
&lt;th&gt;Acción&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F12&lt;/code&gt; / &lt;code&gt;Cmd+Option+I&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Abrir/cerrar DevTools&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl+Shift+P&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Paleta de comandos&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl+P&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Abrir archivo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Esc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Abrir/cerrar consola en cualquier panel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Ctrl+L&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Limpiar consola&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F8&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pausar/reanudar ejecución&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F10&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Siguiente línea (step over)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;F11&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Entrar en función (step into)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Las DevTools son un entorno de desarrollo completo integrado en el navegador. Cada panel está diseñado para resolver un tipo de problema concreto.&lt;/p&gt;
&lt;p&gt;La próxima vez que tengas un bug o un problema de rendimiento, antes de añadir otro &lt;code&gt;console.log&lt;/code&gt;, abre el panel correcto. Probablemente ya te está dando la respuesta.&lt;/p&gt;
</content:encoded><category>Depuración</category><category>Rendimiento</category><category>Desarrollo web</category><category>Frontend</category><category>Herramientas</category><author>Hugo Cayón Laso</author></item><item><title>CSS Grid vs Flexbox: cuándo usar cada uno de verdad</title><link>http://localhost:4321/blog/css-grid-vs-flexbox/</link><guid isPermaLink="true">http://localhost:4321/blog/css-grid-vs-flexbox/</guid><description>No es uno mejor que el otro. Grid y Flexbox resuelven problemas distintos. En este artículo aprenderás a identificar cuándo usar cada uno.</description><pubDate>Mon, 18 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Si llevas un tiempo escribiendo CSS, seguramente habrás tenido esta duda: ¿pongo un &lt;code&gt;display: flex&lt;/code&gt; o un &lt;code&gt;display: grid&lt;/code&gt;? Y si eres honesto, probablemente la mayoría de las veces hayas tirado de Flexbox por costumbre.&lt;/p&gt;
&lt;p&gt;No estás solo. Pero hay una forma mejor de tomar esa decisión, y no implica memorizar propiedades.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;La pregunta que lo cambia todo&lt;/h2&gt;
&lt;p&gt;Antes de pensar en la propiedad CSS, hazte esta pregunta:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;¿Estoy distribuyendo elementos en una dirección o en dos?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Una dirección&lt;/strong&gt; (fila o columna): Flexbox.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dos direcciones&lt;/strong&gt; (filas y columnas a la vez): Grid.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Eso es el 80% de la decisión. El otro 20% son matices que veremos ahora.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Flexbox: el maestro de una dimensión&lt;/h2&gt;
&lt;p&gt;Flexbox nació para distribuir elementos a lo largo de un eje. Es perfecto cuando tienes un contenedor y quieres organizar sus hijos en fila o en columna, con control sobre el espaciado, el alineamiento y el orden.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Casos donde Flexbox brilla:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Barra de navegación con enlaces&lt;/li&gt;
&lt;li&gt;Botones agrupados en una fila&lt;/li&gt;
&lt;li&gt;Centrar un elemento vertical y horizontalmente&lt;/li&gt;
&lt;li&gt;Tarjetas en una fila que se adaptan al espacio disponible&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;/* Barra de navegación clásica */
nav {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 1rem;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La clave de Flexbox es que &lt;strong&gt;el contenedor manda&lt;/strong&gt;. Tú le dices al padre cómo repartir a sus hijos, y los hijos se adaptan.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Grid: el maestro de dos dimensiones&lt;/h2&gt;
&lt;p&gt;Grid te permite definir filas &lt;strong&gt;y&lt;/strong&gt; columnas al mismo tiempo. Es el sistema más potente para construir layouts completos porque puedes controlar exactamente dónde va cada elemento en ambos ejes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Casos donde Grid brilla:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Layout completo de una página (header, sidebar, contenido, footer)&lt;/li&gt;
&lt;li&gt;Galería de imágenes con filas y columnas&lt;/li&gt;
&lt;li&gt;Cuadrícula de tarjetas con tamaños distintos&lt;/li&gt;
&lt;li&gt;Cualquier cosa donde necesites que los elementos se alineen en dos ejes&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;/* Layout completo de página */
body {
  display: grid;
  grid-template-columns: 240px 1fr;
  grid-template-rows: auto 1fr auto;
  grid-template-areas:
    &amp;quot;header  header&amp;quot;
    &amp;quot;sidebar content&amp;quot;
    &amp;quot;footer  footer&amp;quot;;
  min-height: 100vh;
}

header { grid-area: header; }
aside  { grid-area: sidebar; }
main   { grid-area: content; }
footer { grid-area: footer; }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con Grid no estás diciéndole a los hijos cómo comportarse entre ellos: estás definiendo una &lt;strong&gt;estructura&lt;/strong&gt; y luego colocas los elementos dentro de ella.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;La confusión más común&lt;/h2&gt;
&lt;p&gt;Muchos desarrolladores usan Flexbox para construir layouts de página completos porque lo conocen mejor. Funciona, pero se complica rápido: necesitas anidar contenedores, controlar el &lt;code&gt;flex-wrap&lt;/code&gt;, gestionar anchos manualmente...&lt;/p&gt;
&lt;p&gt;La señal de que deberías usar Grid es cuando empiezas a luchar contra Flexbox para que los elementos se alineen en más de una dirección.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;/* Esto con Flexbox require bastante malabarismo */
.card-grid {
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
}
.card {
  flex: 1 1 300px; /* Funciona, pero es frágil */
}

/* Con Grid es directo */
.card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  gap: 1rem;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;La versión Grid no solo es más corta: es más predecible. Los elementos siempre tendrán el mismo tamaño mínimo y se adaptarán solos al espacio disponible.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Pueden (y deben) usarse juntos&lt;/h2&gt;
&lt;p&gt;Grid y Flexbox no son rivales. Un layout real los combina constantemente:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Grid&lt;/strong&gt; para la estructura macro de la página.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Flexbox&lt;/strong&gt; para organizar los elementos dentro de cada celda de Grid.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;/* Grid para el layout general */
.page {
  display: grid;
  grid-template-columns: 1fr 3fr;
  gap: 2rem;
}

/* Flexbox dentro de la tarjeta */
.card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;Referencia rápida&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Situación&lt;/th&gt;
&lt;th&gt;Usa&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Centrar un elemento&lt;/td&gt;
&lt;td&gt;Flexbox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Barra de navegación&lt;/td&gt;
&lt;td&gt;Flexbox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Botones en línea&lt;/td&gt;
&lt;td&gt;Flexbox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Layout de página completa&lt;/td&gt;
&lt;td&gt;Grid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Galería de imágenes&lt;/td&gt;
&lt;td&gt;Grid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tarjetas con filas y columnas&lt;/td&gt;
&lt;td&gt;Grid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alinear en &lt;strong&gt;una&lt;/strong&gt; dirección&lt;/td&gt;
&lt;td&gt;Flexbox&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Alinear en &lt;strong&gt;dos&lt;/strong&gt; direcciones&lt;/td&gt;
&lt;td&gt;Grid&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Layout macro + componentes internos&lt;/td&gt;
&lt;td&gt;Ambos&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;h2&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;No existe una respuesta universal. Existe la pregunta correcta: ¿una dimensión o dos?&lt;/p&gt;
&lt;p&gt;Si te encuentras peleando contra tu CSS para que las cosas se alineen como quieres, probablemente estás usando la herramienta equivocada. Cambia de una a otra y verás cómo el problema se simplifica.&lt;/p&gt;
&lt;p&gt;El mejor CSS no es el que demuestra que sabes mucho. Es el que describe exactamente lo que quieres que pase.&lt;/p&gt;
</content:encoded><category>Desarrollo web</category><category>Diseño web</category><category>Frontend</category><category>CSS</category><author>Hugo Cayón Laso</author></item><item><title>Variables de entorno y secretos: cómo gestionar la configuración de tus proyectos</title><link>http://localhost:4321/blog/variables-de-entorno-y-secretos/</link><guid isPermaLink="true">http://localhost:4321/blog/variables-de-entorno-y-secretos/</guid><description>Las variables de entorno no son solo para ocultar contraseñas. Son la forma correcta de separar configuración de código.</description><pubDate>Mon, 18 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Alguna vez has visto una contraseña de base de datos escrita directamente en el código. Quizás incluso en el tuyo propio, al principio. No pasa nada, todos hemos pasado por ahí.&lt;/p&gt;
&lt;p&gt;Pero hay una forma mucho mejor de manejar esto, y no es solo por seguridad. Las variables de entorno hacen que tu código sea más flexible, más portable y más fácil de mantener.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Qué es una variable de entorno&lt;/h2&gt;
&lt;p&gt;Una variable de entorno es un valor de configuración que existe fuera del código, en el entorno donde se ejecuta la aplicación. El sistema operativo, el servidor o el proceso que arranca tu app se las inyecta al proceso en tiempo de ejecución.&lt;/p&gt;
&lt;p&gt;En lugar de esto:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$db = new PDO(&amp;#39;mysql:host=localhost;dbname=miapp&amp;#39;, &amp;#39;root&amp;#39;, &amp;#39;mi_contraseña_secreta&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Haces esto:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$db = new PDO(
    &amp;#39;mysql:host=&amp;#39; . $_ENV[&amp;#39;DB_HOST&amp;#39;] . &amp;#39;;dbname=&amp;#39; . $_ENV[&amp;#39;DB_NAME&amp;#39;],
    $_ENV[&amp;#39;DB_USER&amp;#39;],
    $_ENV[&amp;#39;DB_PASS&amp;#39;]
);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El código no sabe cuál es la contraseña. Solo sabe dónde buscarla. Eso es lo importante.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Por qué importa más allá de la seguridad&lt;/h2&gt;
&lt;p&gt;La seguridad es la razón más obvia, pero no la única:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Portabilidad.&lt;/strong&gt; El mismo código funciona en local, en staging y en producción sin modificar nada. Solo cambian los valores de las variables.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Colaboración.&lt;/strong&gt; Cada desarrollador puede tener su configuración local sin pisar la de los demás ni la de producción.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Sin secretos en Git.&lt;/strong&gt; Los repositorios son potencialmente públicos, incluso los privados pueden filtrarse. Los secretos no deben estar en el historial de commits nunca.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Separación de responsabilidades.&lt;/strong&gt; La configuración es responsabilidad del entorno, no del código.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;El archivo &lt;code&gt;.env&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;La forma más común de trabajar con variables de entorno en desarrollo local es el archivo &lt;code&gt;.env&lt;/code&gt;. Es un archivo de texto plano con pares clave-valor:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# .env
APP_NAME=MiAplicacion
APP_ENV=local
APP_DEBUG=true

DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=miapp
DB_USER=root
DB_PASS=supersecreta

MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USER=usuario
MAIL_PASS=contraseña
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Librerías como &lt;strong&gt;phpdotenv&lt;/strong&gt; (PHP), &lt;strong&gt;dotenv&lt;/strong&gt; (Node.js) o los frameworks modernos lo cargan automáticamente al arrancar la aplicación.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;La regla más importante: &lt;code&gt;.env&lt;/code&gt; nunca en Git&lt;/h2&gt;
&lt;p&gt;Añade &lt;code&gt;.env&lt;/code&gt; a tu &lt;code&gt;.gitignore&lt;/code&gt; desde el primer commit. Sin excepciones.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# .gitignore
.env
.env.local
.env.production
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lo que sí debe estar en Git es un &lt;code&gt;.env.example&lt;/code&gt; con las mismas claves pero sin los valores reales. Sirve como documentación para cualquiera que clone el proyecto:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# .env.example  ← este SÍ va en Git
APP_NAME=
APP_ENV=local
APP_DEBUG=true

DB_HOST=127.0.0.1
DB_PORT=3306
DB_NAME=
DB_USER=
DB_PASS=
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;Cómo acceder a las variables&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;En PHP:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;// Con phpdotenv instalado y cargado
$host = $_ENV[&amp;#39;DB_HOST&amp;#39;];
$host = getenv(&amp;#39;DB_HOST&amp;#39;); // alternativa
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;En JavaScript (Node.js):&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;// Con el paquete dotenv
const host = process.env.DB_HOST;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;En la terminal:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;export DB_HOST=localhost
echo $DB_HOST
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h2&gt;Niveles de entorno&lt;/h2&gt;
&lt;p&gt;Un proyecto suele tener varios entornos con configuraciones distintas:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Entorno&lt;/th&gt;
&lt;th&gt;Propósito&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;&lt;code&gt;local&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Tu máquina de desarrollo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;testing&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pruebas automatizadas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;staging&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Preproducción, copia de producción&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;production&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;El entorno real con usuarios&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Cada entorno tiene su propio conjunto de variables. La base de datos de producción nunca debe ser la misma que la de desarrollo.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Secretos en producción: más allá del &lt;code&gt;.env&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;En producción, copiar un archivo &lt;code&gt;.env&lt;/code&gt; al servidor es una opción, pero no la más robusta. Las alternativas más seguras:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Variables del sistema operativo.&lt;/strong&gt; El servidor tiene las variables configuradas directamente en su entorno. No hay archivo que pueda filtrarse.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Gestores de secretos.&lt;/strong&gt; Servicios como &lt;strong&gt;AWS Secrets Manager&lt;/strong&gt;, &lt;strong&gt;HashiCorp Vault&lt;/strong&gt; o &lt;strong&gt;Doppler&lt;/strong&gt; almacenan los secretos cifrados y los inyectan en tiempo de ejecución. Tu aplicación ni siquiera ve el valor en texto plano hasta que lo necesita.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Secrets de la plataforma.&lt;/strong&gt; Servicios como Vercel, Railway o Heroku tienen paneles para definir variables de entorno sin necesidad de archivos.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Errores comunes&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Subir el &lt;code&gt;.env&lt;/code&gt; a Git.&lt;/strong&gt; El más frecuente. Si ya ocurrió, no basta con borrar el archivo: el secreto está en el historial. Hay que rotar las credenciales (cambiar las contraseñas) y usar &lt;code&gt;git filter-repo&lt;/code&gt; para limpiar el historial.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Variables con nombres genéricos.&lt;/strong&gt; &lt;code&gt;PASSWORD&lt;/code&gt; o &lt;code&gt;KEY&lt;/code&gt; no dicen nada. Usa nombres descriptivos: &lt;code&gt;DB_PASS&lt;/code&gt;, &lt;code&gt;STRIPE_SECRET_KEY&lt;/code&gt;, &lt;code&gt;SMTP_PASSWORD&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;El mismo &lt;code&gt;.env&lt;/code&gt; para todos los entornos.&lt;/strong&gt; Cada entorno debe tener sus propios valores. Compartir la base de datos de producción con el entorno de desarrollo es una receta para el desastre.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Valores por defecto inseguros en código.&lt;/strong&gt; Esto es especialmente peligroso:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;// MAL: si la variable no existe, usa una contraseña por defecto
$pass = $_ENV[&amp;#39;DB_PASS&amp;#39;] ?? &amp;#39;admin123&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Si una variable crítica no existe, la aplicación debe fallar con un error claro, no continuar con un valor inseguro.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Las variables de entorno son una de esas cosas que parecen un detalle técnico menor pero tienen un impacto enorme en la seguridad y en la calidad del proyecto.&lt;/p&gt;
&lt;p&gt;La regla es simple: &lt;strong&gt;nada que cambie entre entornos, y nada que sea secreto, debe estar en el código.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Si lo aplicas desde el principio de cada proyecto, te ahorrarás más de un problema en el futuro.&lt;/p&gt;
</content:encoded><category>DevOps</category><category>Desarrollo web</category><category>Buenas prácticas</category><category>Backend</category><category>Seguridad</category><author>Hugo Cayón Laso</author></item><item><title>Un año como desarrollador web: lo que nadie te cuenta</title><link>http://localhost:4321/blog/un-ano-como-desarrollador-web/</link><guid isPermaLink="true">http://localhost:4321/blog/un-ano-como-desarrollador-web/</guid><description>El 28 de junio de 2025 firmé mi primer contrato como desarrollador web. Un año después, esto es lo que he aprendido, lo que me sorprendió y lo que le diría al Hugo de entonces.</description><pubDate>Mon, 18 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hace exactamente un año firmé mi primer contrato como desarrollador web.&lt;/p&gt;
&lt;p&gt;Recuerdo que ese día mezcló dos sensaciones que raramente van juntas: la ilusión de que por fin empezaba algo real, y la duda de si realmente estaba preparado para ello. Spoiler: las dos tenían razón a medias.&lt;/p&gt;
&lt;p&gt;Ahora que ha pasado un año, quiero escribir esto con honestidad. No el resumen de LinkedIn donde todo fue brillante, sino el relato de cómo fue de verdad: lo que me costó, lo que me sorprendió y lo que ojalá hubiera sabido antes.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;El primer día&lt;/h2&gt;
&lt;p&gt;Llegué con lo que en ese momento me parecían dudas puntuales. Sabía programar, tenía proyectos propios, había estudiado. Pero el primer día me di cuenta de que lo que no sabía no era código, sino &lt;em&gt;contexto&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;El contexto de cómo trabaja un equipo de verdad. El contexto de un proyecto con años de historia detrás. El contexto de por qué algo está hecho de cierta manera, aunque a primera vista parezca que podría hacerse mejor.&lt;/p&gt;
&lt;p&gt;El stack que encontré fue &lt;strong&gt;CakePHP&lt;/strong&gt;, &lt;strong&gt;JavaScript&lt;/strong&gt; y &lt;strong&gt;MySQL&lt;/strong&gt;. No era lo más moderno del mundo, pero eso me enseñó algo valioso muy pronto: en el trabajo real no eliges el stack, aprendes el que hay. Y eso, paradójicamente, te hace mejor programador que si siempre trabajaras con lo que ya conoces.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;La sorpresa que no me esperaba: el equipo&lt;/h2&gt;
&lt;p&gt;Si me hubieras preguntado antes de empezar qué iba a ser lo más difícil, habría dicho el código. Me habría equivocado.&lt;/p&gt;
&lt;p&gt;Lo más difícil, y también lo más importante, fue aprender a trabajar con otras personas.&lt;/p&gt;
&lt;p&gt;No me refiero a llevarse bien, que eso es otra cosa. Me refiero a cosas concretas que nadie te enseña en la universidad:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Cómo hacer una pregunta bien hecha.&lt;/strong&gt; No vale &amp;quot;esto no funciona&amp;quot;. Hay que explicar qué esperabas, qué pasa, qué ya has probado.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cómo revisar el código de otro.&lt;/strong&gt; Criticar un enfoque sin atacar a quien lo escribió.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cómo pedir ayuda sin parecer que te rindes.&lt;/strong&gt; Hay un punto entre bloquearse demasiado pronto y bloquearse demasiado tarde, y encontrarlo lleva tiempo.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cómo comunicar avance e impedimentos.&lt;/strong&gt; Que el equipo sepa en qué estás, aunque aún no hayas terminado.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Todo eso parece obvio escrito así. En la práctica cuesta mucho más de lo que parece.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;El momento en que algo cambió&lt;/h2&gt;
&lt;p&gt;No recuerdo una fecha exacta. Fue más un proceso gradual que un instante.&lt;/p&gt;
&lt;p&gt;Hubo un punto en el que dejé de mirar a mi alrededor para ver si alguien me estaba observando. Dejé de dudar si debía abrir la boca en una reunión. Empecé a proponer cosas en lugar de solo ejecutar lo que me asignaban.&lt;/p&gt;
&lt;p&gt;Me sentí parte del equipo.&lt;/p&gt;
&lt;p&gt;Eso no significa que de repente lo supiera todo. Significa que me sentí cómodo no sabiéndolo todo, que es algo completamente diferente.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Las dudas evolucionan&lt;/h2&gt;
&lt;p&gt;Una cosa que nadie me contó, y que ahora me parece uno de los indicadores más claros de progreso real, es que las dudas cambian.&lt;/p&gt;
&lt;p&gt;El primer mes tenía dudas sobre cosas que ahora resuelvo en minutos. Pero en lugar de tener &lt;em&gt;menos&lt;/em&gt; dudas, tengo dudas sobre cosas más complejas. Cuestiones de arquitectura, de rendimiento, de decisiones que afectan al largo plazo.&lt;/p&gt;
&lt;p&gt;Eso al principio puede confundirte: &amp;quot;¿Por qué sigo teniendo tantas dudas si ya llevo un año?&amp;quot; La respuesta es que las dudas no desaparecen, suben de nivel. Y subir de nivel es exactamente lo que quieres que pase.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Lo que le diría al Hugo de hace un año&lt;/h2&gt;
&lt;p&gt;Si pudiera hablar con el yo de hace exactamente un año, le diría tres cosas:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pregunta más.&lt;/strong&gt; Hay una tentación enorme, sobre todo al principio, de aparentar que ya lo sabes. Resistirla es una de las mejores inversiones que puedes hacer. Nadie espera que lo sepas todo. Sí esperan que seas honesto sobre lo que no sabes.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Toma notas desde el primer día.&lt;/strong&gt; Todo lo que aprendes en los primeros meses se olvida más rápido de lo que crees. Las decisiones que tomó el equipo hace dos años, el porqué de cierta estructura, ese truco que alguien te enseñó de pasada. Apúntalo todo. Tu yo de seis meses después te lo agradecerá.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disfruta del aprendizaje.&lt;/strong&gt; Hay una prisa por llegar a &amp;quot;saber suficiente&amp;quot; que hace que no valores el camino. Pero el camino es donde está casi todo. Los momentos en los que algo por fin encaja, en los que entiendes por qué algo funciona como funciona, en los que resuelves solo algo que hace tres semanas habría requerido ayuda. Esos momentos merecen ser disfrutados, no solo superados.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Un año después&lt;/h2&gt;
&lt;p&gt;Ha sido un año intenso. También ha sido un año gratificante.&lt;/p&gt;
&lt;p&gt;He aprendido más de lo que habría aprendido en cualquier otro contexto. He cometido errores que solo se cometen cuando el código va a producción de verdad. He visto cómo una decisión técnica afecta a personas reales.&lt;/p&gt;
&lt;p&gt;Y sobre todo, he comprobado que este es el trabajo que quería hacer.&lt;/p&gt;
&lt;p&gt;Queda mucho por aprender. Pero ya no me da miedo decirlo.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Si estás a punto de empezar tu primer trabajo como desarrollador, o llevas poco tiempo y te reconoces en algo de lo que he contado, escríbeme. Me alegra saber que este tipo de reflexiones le sirven a alguien.&lt;/em&gt;&lt;/p&gt;
</content:encoded><category>Aprendizaje</category><category>Junior</category><category>Reflexión</category><category>Desarrollo</category><category>Carrera</category><author>Hugo Cayón Laso</author></item><item><title>Mi primer experimento creando una app para iOS y macOS</title><link>http://localhost:4321/blog/primer-experimento-app-ios-macos/</link><guid isPermaLink="true">http://localhost:4321/blog/primer-experimento-app-ios-macos/</guid><description>Empiezo un pequeño proyecto personal para aprender Swift y desarrollar una aplicación de tareas sencilla para el ecosistema Apple.</description><pubDate>Thu, 07 May 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Desde hace tiempo tenía curiosidad por el desarrollo de aplicaciones para el ecosistema Apple, y finalmente he decidido empezar a aprender Swift creando un pequeño proyecto personal: una aplicación de tareas muy simple para iOS y macOS.&lt;/p&gt;
&lt;p&gt;La idea no es crear algo revolucionario ni competir con las aplicaciones que ya existen. De hecho, el objetivo principal de este proyecto es aprender. Nunca he trabajado seriamente con Swift, así que quiero usar esta app como una forma práctica de ir entendiendo cómo funciona el desarrollo nativo en Apple.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;¿Por qué una app de tareas?&lt;/h2&gt;
&lt;p&gt;Porque parece un proyecto perfecto para empezar.&lt;/p&gt;
&lt;p&gt;Una aplicación To-Do es algo relativamente sencillo, pero al mismo tiempo permite tocar muchos conceptos básicos del desarrollo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Crear interfaces,&lt;/li&gt;
&lt;li&gt;Guardar datos,&lt;/li&gt;
&lt;li&gt;Organizar pantallas,&lt;/li&gt;
&lt;li&gt;Entender cómo funciona una aplicación real.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Además, es un tipo de herramienta que utilizo todos los días, así que me parece una buena forma de construir algo útil mientras aprendo.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Qué quiero aprender&lt;/h2&gt;
&lt;p&gt;Ahora mismo estoy empezando prácticamente desde cero, así que mi enfoque es ir poco a poco y experimentar.&lt;/p&gt;
&lt;p&gt;Estas son algunas de las tecnologías que quiero explorar durante el proyecto:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SwiftUI&lt;/strong&gt;, para construir la interfaz de la aplicación.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SwiftData&lt;/strong&gt;, para guardar las tareas de forma sencilla.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CloudKit&lt;/strong&gt;, aunque probablemente lo deje para más adelante cuando tenga una base más estable.&lt;/li&gt;
&lt;li&gt;Integración básica con el ecosistema Apple, como widgets o atajos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Seguramente cometa errores y tenga que rehacer muchas cosas durante el proceso, pero precisamente esa es parte de la experiencia.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Una aplicación muy simple (de momento)&lt;/h2&gt;
&lt;p&gt;La primera versión será extremadamente básica:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Crear tareas,&lt;/li&gt;
&lt;li&gt;Marcarlas como completadas,&lt;/li&gt;
&lt;li&gt;Eliminarlas,&lt;/li&gt;
&lt;li&gt;Y poco más.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Quiero evitar intentar hacer demasiadas cosas desde el principio y centrarme primero en entender bien las bases.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Continuará...&lt;/h2&gt;
&lt;p&gt;Este es solo el inicio del proyecto. A medida que vaya avanzando, iré publicando nuevos posts compartiendo el progreso, las decisiones que vaya tomando y todo lo que vaya aprendiendo sobre Swift y desarrollo para el ecosistema Apple.&lt;/p&gt;
&lt;p&gt;No sé realmente hasta dónde llegará este experimento, pero precisamente esa es la gracia. Todo empezó simplemente por curiosidad, por aprender algo nuevo y por probar cómo es desarrollar aplicaciones dentro del ecosistema de Apple.&lt;/p&gt;
</content:encoded><category>Aprendizaje</category><category>Apple</category><category>macOS</category><category>iOS</category><category>SwiftUI</category><category>Swift</category><author>Hugo Cayón Laso</author></item><item><title>Buscador inteligente y estética renovada: La nueva experiencia DevLog</title><link>http://localhost:4321/blog/buscador-inteligente-estetica-renovada/</link><guid isPermaLink="true">http://localhost:4321/blog/buscador-inteligente-estetica-renovada/</guid><description>Nuevo buscador instantáneo con Pagefind y la evolución de nuestra identidad visual hacia un sistema más táctil, fluido y coherente.</description><pubDate>Sat, 18 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hoy es un día importante para la identidad visual de &lt;strong&gt;DevLog&lt;/strong&gt;. He completado una fase de renovación estética global que nos acerca a una interfaz mucho más moderna y actual, asegurando que la experiencia de usuario sea fluida, táctil y coherente en cada rincón de la plataforma.&lt;/p&gt;
&lt;p&gt;A continuación, detallo los cambios principales y la nueva herramienta de búsqueda que he implementado.&lt;/p&gt;
&lt;h2&gt;1. Buscador Inteligente: Estética y Velocidad&lt;/h2&gt;
&lt;p&gt;El buscador ha dejado de ser una simple funcionalidad para convertirse en una de las piezas centrales de la experiencia de usuario. El nuevo diseño se aleja de lo convencional para abrazar una estética más &amp;quot;pro&amp;quot;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Fase de Inmersión&lt;/strong&gt;: El modal de búsqueda ahora utiliza &lt;strong&gt;glassmorphism&lt;/strong&gt; con desenfoques de fondo, integrándose de forma orgánica con la interfaz.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diferenciación Visual&lt;/strong&gt;: Ahora es mucho más fácil distinguir entre posts y etiquetas gracias a iconos específicos y tarjetas con bordes reactivos que se iluminan al seleccionarlos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Navegación por Teclado&lt;/strong&gt;: He implementado el estándar &lt;code&gt;Cmd + K&lt;/code&gt; (Mac) o &lt;code&gt;Ctrl + K&lt;/code&gt; (Windows) para abrir el buscador y soporte completo para las flechas del teclado y &lt;code&gt;Enter&lt;/code&gt;, permitiendo una navegación fluida sin tocar el ratón.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Motor Estático&lt;/strong&gt;: Gracias a &lt;strong&gt;Pagefind&lt;/strong&gt;, la búsqueda es virtualmente instantánea, indexando el contenido en el lado del cliente para una respuesta sin latencia.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;2. Estandarización de la navegación e interactividad&lt;/h2&gt;
&lt;p&gt;El cambio más profundo no está en lo que ves, sino en lo que &lt;em&gt;sientes&lt;/em&gt; al interactuar. He tomado el diseño sutil y elegante de los botones del encabezado (&lt;code&gt;header&lt;/code&gt;) y lo he aplicado como estándar en todo el sitio.&lt;/p&gt;
&lt;h3&gt;El nuevo lenguaje &amp;quot;Flat &amp;amp; Reactive&amp;quot;&lt;/h3&gt;
&lt;p&gt;He eliminado los escalados agresivos y las traslaciones exageradas. El nuevo patrón se define por:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Shadow-LG Tintada&lt;/strong&gt;: Al pasar el ratón, los elementos reaccionan con una sombra suave teñida por el color primario, aportando profundidad sin ruido visual.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Acción Táctil&lt;/strong&gt;: Al hacer clic, los elementos se comprimen ligeramente (&lt;code&gt;scale-95&lt;/code&gt;), ofreciendo un feedback físico que imita la pulsación de un botón real.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Micro-transiciones&lt;/strong&gt;: Cada cambio de estado ocurre en 300 ms de forma suave, alineado con el sistema de transiciones del navegador.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Este lenguaje se ha aplicado a las tarjetas de posts, tarjetas de etiquetas, la navegación entre artículos y los controles del footer.&lt;/p&gt;
&lt;h2&gt;3. Nueva sección: Actualizaciones (Updates)&lt;/h2&gt;
&lt;p&gt;Para mantener una transparencia total sobre la evolución de este proyecto, he creado una nueva sección dedicada: &lt;strong&gt;Actualizaciones&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;A diferencia de los artículos de blog convencionales, la sección de &lt;strong&gt;Actualizaciones&lt;/strong&gt; servirá para comunicar:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Nuevas funcionalidades&lt;/strong&gt;: Implementación de herramientas de búsqueda, sistemas de idiomas, etc.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mejoras Estéticas&lt;/strong&gt;: Cambios en la paleta de colores, tipografía o micro-animaciones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cambios Internos&lt;/strong&gt;: Optimizaciones de rendimiento, mejoras en el SEO o actualizaciones de la arquitectura del código.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cada actualización cuenta con su propia navegación inteligente y está categorizada para que puedas ver rápidamente el historial de mejoras de DevLog.&lt;/p&gt;
&lt;h2&gt;4. Coherencia en cada página&lt;/h2&gt;
&lt;p&gt;Desde la página de &lt;strong&gt;Inicio&lt;/strong&gt; hasta los apartados &lt;strong&gt;Legal&lt;/strong&gt; y de &lt;strong&gt;Contacto&lt;/strong&gt;, cada botón e icono ahora comparte el mismo ADN visual. Los botones sociales ahora son circulares, consistentes y reactivos. Además, he añadido un &lt;strong&gt;acceso directo al feed RSS&lt;/strong&gt; en el pie de página (&lt;code&gt;footer&lt;/code&gt;)  para que puedas seguir las novedades desde tu lector favorito, eliminando cualquier discrepancia estética que pudiera haber quedado de versiones anteriores.&lt;/p&gt;
&lt;p&gt;Te invito a explorar la nueva sección de &lt;a href=&quot;/updates&quot;&gt;Actualizaciones&lt;/a&gt; y a probar el nuevo buscador presionando &lt;code&gt;Cmd + K&lt;/code&gt; o &lt;code&gt;Ctrl + K&lt;/code&gt;.&lt;/p&gt;
</content:encoded><category>Actualizaciones</category><category>Diseño</category><category>Buscador</category><category>UI/UX</category><category>Astro</category><author>Hugo Cayón Laso</author></item><item><title>Cómo construí mi blog con Astro: arquitectura, componentes y trucos</title><link>http://localhost:4321/blog/como-construi-mi-blog-con-astro/</link><guid isPermaLink="true">http://localhost:4321/blog/como-construi-mi-blog-con-astro/</guid><description>Explicación técnica y ejemplos de código de mi blog en Astro.</description><pubDate>Mon, 09 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Crear este blog con Astro ha sido una de las mejores decisiones que he tomado como desarrollador. En este artículo quiero compartir cómo lo construí, qué decisiones tomé a nivel técnico y partes del código que se utiliza en mi estructura actual. Mi objetivo es que cualquier persona pueda replicarlo o inspirarse para crear el suyo.&lt;/p&gt;
&lt;h2&gt;¿Por qué Astro?&lt;/h2&gt;
&lt;p&gt;Elegí Astro por varias razones:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generación estática ultra rápida.&lt;/li&gt;
&lt;li&gt;Soporte integrado de Markdown + MDX.&lt;/li&gt;
&lt;li&gt;Posibilidad de usar componentes de React, Svelte, Vue… solo donde hace falta.&lt;/li&gt;
&lt;li&gt;Su arquitectura de islas, que optimiza la carga y el rendimiento.&lt;/li&gt;
&lt;li&gt;Un sistema de contenido: astro:content.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Estructura general del proyecto&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;src/
  components/
  layouts/
  pages/
    blog/
    tags/
  content/
    posts/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A continuación explico qué papel juega cada carpeta y por qué la organicé así:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;src/components/&lt;/strong&gt;
Aquí guardo todos los componentes reutilizables que voy creando para el blog: tarjetas de posts, botones, navegación, componentes UI, etc. Mi objetivo es que cualquier pieza visual que se repita en varias páginas esté centralizada en este directorio.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;src/layouts/&lt;/strong&gt;
Esta carpeta contiene los layouts del blog. Un layout define la estructura general de una página (cabecera, pie, estilos base, tipografía…), así que tenerlos separados me permite reutilizar la misma estructura en todas las publicaciones sin duplicar código.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;src/pages/&lt;/strong&gt;
Astro utiliza un sistema de enrutado basado en archivos, así que todo lo que esté aquí se convierte automáticamente en una ruta pública.&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;pages/blog/&lt;/strong&gt;
Incluye el listado de posts, la paginación y la lógica que genera las páginas individuales del blog.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pages/tags/&lt;/strong&gt;
Las páginas de etiquetas se generan desde aquí. Me interesa tenerlas separadas para mejorar la navegación del blog y permitir al lector filtrar contenido por temas.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;src/content/&lt;/strong&gt;
Esta es la parte donde vive todo el contenido del blog.&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;content/posts/&lt;/strong&gt;
Aquí es donde guardo cada post como un archivo Markdown independiente.
Cada post está escrito en Markdown y validado con Content Collections de Astro, lo que me asegura tipado, metadatos coherentes y un sistema más ordenado para gestionar las publicaciones.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Gracias a esta estructura, el proyecto se mantiene limpio y escalable. Cada pieza tiene su lugar y puedo añadir nuevas funciones o componentes sin complicar la organización general.&lt;/p&gt;
&lt;h2&gt;1. Arquitectura de Datos: Content Collections&lt;/h2&gt;
&lt;p&gt;El corazón del blog es el sistema de &lt;strong&gt;Content Collections&lt;/strong&gt;. No solo guardamos archivos Markdown, sino que definimos un contrato estricto mediante un esquema de &lt;strong&gt;Zod&lt;/strong&gt;. Esto nos permite validar que cada post tenga título, fecha y etiquetas antes de que el sitio se construya, evitando errores en producción.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;// src/content/config.ts
import { defineCollection, z } from &amp;quot;astro:content&amp;quot;;

const posts = defineCollection({
  type: &amp;quot;content&amp;quot;,
  schema: ({ image }) =&amp;gt;
    z.object({
      title: z.string(),
      description: z.string(),
      date: z.date(),
      author: z.string(),
      tags: z.array(z.string()).optional(),
      cover: image().optional(),
      draft: z.boolean().default(false),
    }),
});

export const collections = { posts };
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;2. Flujo de Generación y Rutado Dinámico&lt;/h2&gt;
&lt;p&gt;Astro genera el blog de forma estática (SSG) para un rendimiento imbatible. Para las páginas de cada post (&lt;code&gt;src/pages/blog/[slug].astro&lt;/code&gt;), utilizamos &lt;code&gt;getStaticPaths&lt;/code&gt; para mapear cada archivo de la colección a una URL única.&lt;/p&gt;
&lt;p&gt;Este es un ejemplo real de cómo gestionamos la lógica de &lt;strong&gt;Navegación Relativa&lt;/strong&gt; (Anterior/Siguiente) y el cálculo del &lt;strong&gt;Tiempo de Lectura&lt;/strong&gt; in-situ:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-astro&quot;&gt;// src/pages/blog/[slug].astro
---
import { getCollection } from &amp;quot;astro:content&amp;quot;;
import PostLayout from &amp;quot;@/layouts/PostLayout.astro&amp;quot;;
import { calculateReadingTime } from &amp;quot;@/utils/readingTime&amp;quot;;

export async function getStaticPaths() {
  const posts = (await getCollection(&amp;quot;posts&amp;quot;))
    .filter((post) =&amp;gt; !post.data.draft)
    .sort((a, b) =&amp;gt; a.data.date.getTime() - b.data.date.getTime());

  return posts.map((post, index) =&amp;gt; ({
    params: { slug: post.slug },
    props: {
      post,
      prev: posts[index - 1] ?? null,
      next: posts[index + 1] ?? null,
    },
  }));
}

const { post, prev, next } = Astro.props;
const { Content } = await post.render();
---
&amp;lt;PostLayout
  {...post.data}
  prev={prev}
  next={next}
  readingTime={post.body ? calculateReadingTime(post.body) : undefined}
&amp;gt;
  &amp;lt;Content /&amp;gt;
&amp;lt;/PostLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;3. Jerarquía de Layouts y Herencia de Metadatos&lt;/h2&gt;
&lt;p&gt;La estructura visual sigue una jerarquía de composición clara:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;main.astro&lt;/code&gt;&lt;/strong&gt;: El layout &amp;quot;Shell&amp;quot;. Configura el HTML base, fuentes, &lt;code&gt;ClientRouter&lt;/code&gt; y los metadatos globales (OpenGraph, Twitter).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;BlogLayout.astro&lt;/code&gt;&lt;/strong&gt;: Layout intermedio para listados y categorías.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;PostLayout.astro&lt;/code&gt;&lt;/strong&gt;: El layout especializado. Gestiona la lógica de artículos, inyecta &lt;strong&gt;JSON-LD&lt;/strong&gt; para SEO semántico y maneja componentes complejos como la galería de imágenes con &lt;code&gt;astro:assets&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;3. Jerarquía de Layouts: La estructura del Blog&lt;/h2&gt;
&lt;p&gt;La arquitectura visual se divide en tres niveles de responsabilidad, utilizando la composición de Astro para maximizar la reutilización y el rendimiento.&lt;/p&gt;
&lt;h3&gt;3.1. El Layout &amp;quot;Shell&amp;quot; (&lt;code&gt;main.astro&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;Este es el punto de entrada de todas las páginas. Gestiona el &lt;code&gt;document&lt;/code&gt; HTML, el SEO global, las fuentes y el sistema de transiciones.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-astro&quot;&gt;// src/layouts/main.astro
---
import &amp;quot;../styles/global.css&amp;quot;;
import Header from &amp;quot;../components/Header.astro&amp;quot;;
import Footer from &amp;quot;../components/Footer.astro&amp;quot;;
import { ClientRouter } from &amp;quot;astro:transitions&amp;quot;;

const { title, description, image = &amp;quot;/og-image.png&amp;quot;, type = &amp;quot;website&amp;quot; } = Astro.props;
const imageUrl = new URL(image, Astro.site).toString();
---

&amp;lt;html lang=&amp;quot;es&amp;quot; class=&amp;quot;scroll-smooth&amp;quot;&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset=&amp;quot;utf-8&amp;quot; /&amp;gt;
    &amp;lt;meta name=&amp;quot;viewport&amp;quot; content=&amp;quot;width=device-width, initial-scale=1&amp;quot; /&amp;gt;
    &amp;lt;meta name=&amp;quot;description&amp;quot; content={description} /&amp;gt;
    &amp;lt;meta name=&amp;quot;robots&amp;quot; content=&amp;quot;index, follow&amp;quot; /&amp;gt;
    &amp;lt;link rel=&amp;quot;canonical&amp;quot; href={Astro.url} /&amp;gt;

    &amp;lt;!-- Open Graph --&amp;gt;
    &amp;lt;meta property=&amp;quot;og:title&amp;quot; content={title} /&amp;gt;
    &amp;lt;meta property=&amp;quot;og:description&amp;quot; content={description} /&amp;gt;
    &amp;lt;meta property=&amp;quot;og:type&amp;quot; content={type} /&amp;gt;
    &amp;lt;meta property=&amp;quot;og:url&amp;quot; content={Astro.url} /&amp;gt;
    &amp;lt;meta property=&amp;quot;og:image&amp;quot; content={imageUrl} /&amp;gt;
    &amp;lt;meta property=&amp;quot;og:image:alt&amp;quot; content={title} /&amp;gt;
    &amp;lt;meta property=&amp;quot;og:locale&amp;quot; content=&amp;quot;es_ES&amp;quot; /&amp;gt;
    &amp;lt;meta property=&amp;quot;og:site_name&amp;quot; content=&amp;quot;DevLog&amp;quot; /&amp;gt;

    &amp;lt;!-- Twitter Card --&amp;gt;
    &amp;lt;meta name=&amp;quot;twitter:card&amp;quot; content=&amp;quot;summary_large_image&amp;quot; /&amp;gt;
    &amp;lt;meta name=&amp;quot;twitter:title&amp;quot; content={title} /&amp;gt;
    &amp;lt;meta name=&amp;quot;twitter:description&amp;quot; content={description} /&amp;gt;
    &amp;lt;meta name=&amp;quot;twitter:image&amp;quot; content={imageUrl} /&amp;gt;

    &amp;lt;!-- Favicons --&amp;gt;
    &amp;lt;link rel=&amp;quot;icon&amp;quot; type=&amp;quot;image/svg+xml&amp;quot; href=&amp;quot;/favicon.svg&amp;quot; /&amp;gt;
    &amp;lt;link rel=&amp;quot;icon&amp;quot; type=&amp;quot;image/png&amp;quot; href=&amp;quot;/favicon.png&amp;quot; /&amp;gt;

    &amp;lt;!-- RSS Feed Discovery --&amp;gt;
    &amp;lt;link rel=&amp;quot;alternate&amp;quot; type=&amp;quot;application/rss+xml&amp;quot; title=&amp;quot;DevLog RSS Feed&amp;quot; href=&amp;quot;/rss.xml&amp;quot; /&amp;gt;

    &amp;lt;title&amp;gt;{title}&amp;lt;/title&amp;gt;

    &amp;lt;slot name=&amp;quot;head&amp;quot; /&amp;gt;
    &amp;lt;ClientRouter /&amp;gt;
  &amp;lt;/head&amp;gt;

  &amp;lt;body class=&amp;quot;min-h-screen grid grid-rows-[auto_1fr_auto] bg-background text-foreground antialiased font-sans&amp;quot;&amp;gt;
    &amp;lt;Header /&amp;gt;
    &amp;lt;main transition:animate=&amp;quot;fade&amp;quot;&amp;gt;
      &amp;lt;slot /&amp;gt;
    &amp;lt;/main&amp;gt;
    &amp;lt;Footer /&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.2. El Layout de Listado (&lt;code&gt;BlogLayout.astro&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;Un pequeño wrapper que simplifica la creación de páginas de índice y etiquetas, heredando del Shell.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-astro&quot;&gt;// src/layouts/BlogLayout.astro
---
import BaseLayout from &amp;quot;@/layouts/main.astro&amp;quot;;

const { title = &amp;quot;Blog&amp;quot;, description = &amp;quot;Últimos artículos&amp;quot;, image, type = &amp;quot;website&amp;quot; } = Astro.props;
---

&amp;lt;BaseLayout title={title} description={description} image={image} type={type}&amp;gt;
  &amp;lt;slot /&amp;gt;
&amp;lt;/BaseLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;3.3. El Layout de Artículo (&lt;code&gt;PostLayout.astro&lt;/code&gt;)&lt;/h3&gt;
&lt;p&gt;Este es el componente más rico. Gestiona el SEO semántico, la portada optimizada, la barra de lectura y la navegación entre artículos.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-astro&quot;&gt;// src/layouts/PostLayout.astro
---
import BaseLayout from &amp;quot;@/layouts/main.astro&amp;quot;;
import type { CollectionEntry } from &amp;quot;astro:content&amp;quot;;
import { Badge } from &amp;quot;@/components/ui/badge&amp;quot;;
import { ChevronLeft, ChevronRight, Link2, Check } from &amp;quot;@lucide/astro&amp;quot;;
import { Image } from &amp;quot;astro:assets&amp;quot;;
import { tagUrl } from &amp;quot;@/utils/tag&amp;quot;;

const { title, description, date, author, tags, cover, prev, next, readingTime } = Astro.props;

const formattedDate = date
  ? new Date(date).toLocaleDateString(&amp;quot;es-ES&amp;quot;, { dateStyle: &amp;quot;long&amp;quot; })
  : &amp;quot;Fecha desconocida&amp;quot;;
const coverImage = typeof cover === &amp;quot;string&amp;quot; ? cover : cover?.src;
---

&amp;lt;BaseLayout title={title} description={description} type=&amp;quot;article&amp;quot; image={coverImage}&amp;gt;
  &amp;lt;Fragment slot=&amp;quot;head&amp;quot;&amp;gt;
    &amp;lt;script type=&amp;quot;application/ld+json&amp;quot; set:html={JSON.stringify({
      &amp;quot;@context&amp;quot;: &amp;quot;https://schema.org&amp;quot;,
      &amp;quot;@type&amp;quot;: &amp;quot;BlogPosting&amp;quot;,
      &amp;quot;headline&amp;quot;: title,
      &amp;quot;description&amp;quot;: description,
      &amp;quot;datePublished&amp;quot;: date ? new Date(date).toISOString() : undefined,
      &amp;quot;url&amp;quot;: Astro.url.toString(),
      ...(author &amp;amp;&amp;amp; { &amp;quot;author&amp;quot;: { &amp;quot;@type&amp;quot;: &amp;quot;Person&amp;quot;, &amp;quot;name&amp;quot;: author } }),
    })} /&amp;gt;
  &amp;lt;/Fragment&amp;gt;

  &amp;lt;article class=&amp;quot;max-w-4xl mx-auto px-4 py-20 reveal&amp;quot;&amp;gt;
    {cover &amp;amp;&amp;amp; (
      &amp;lt;figure class=&amp;quot;mb-12 max-h-[400px] overflow-hidden rounded-xl&amp;quot;&amp;gt;
        &amp;lt;Image
          src={coverImage as any}
          alt={`Imagen de portada: ${title}`}
          width={1200}
          height={630}
          class=&amp;quot;w-full object-cover&amp;quot;
        /&amp;gt;
      &amp;lt;/figure&amp;gt;
    )}

    &amp;lt;header class=&amp;quot;max-w-3xl mx-auto mb-12 pb-6 border-b border-gray-200/50 dark:border-gray-700/50&amp;quot;&amp;gt;
      &amp;lt;div class=&amp;quot;flex flex-col sm:flex-row sm:items-center sm:justify-between gap-2 text-sm text-muted-foreground mb-4&amp;quot;&amp;gt;
        &amp;lt;time class=&amp;quot;tabular-nums&amp;quot;&amp;gt;Publicado el {formattedDate} {readingTime &amp;amp;&amp;amp; `• ${readingTime} min de lectura`}&amp;lt;/time&amp;gt;
        {author &amp;amp;&amp;amp; &amp;lt;p class=&amp;quot;font-medium&amp;quot;&amp;gt;Por &amp;lt;strong&amp;gt;{author}&amp;lt;/strong&amp;gt;&amp;lt;/p&amp;gt;}
      &amp;lt;/div&amp;gt;
      &amp;lt;h1 class=&amp;quot;text-4xl sm:text-5xl font-extrabold tracking-tight mb-4&amp;quot;&amp;gt;{title}&amp;lt;/h1&amp;gt;
      &amp;lt;div class=&amp;quot;flex flex-wrap gap-2&amp;quot;&amp;gt;
        {(tags ?? []).map((tag) =&amp;gt; (
          &amp;lt;a
            href={`/tags/${tagUrl(tag)}`}
            class=&amp;quot;relative z-20 hover:opacity-80 transition-all duration-300 hover:scale-105 active:scale-95&amp;quot;
          &amp;gt;
            &amp;lt;Badge variant=&amp;quot;secondary&amp;quot;&amp;gt;{tag}&amp;lt;/Badge&amp;gt;
          &amp;lt;/a&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
    &amp;lt;/header&amp;gt;

    &amp;lt;div class=&amp;quot;max-w-3xl mx-auto prose prose-lg dark:prose-invert&amp;quot;&amp;gt;
      &amp;lt;slot /&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;!-- Compartir --&amp;gt;
    &amp;lt;div class=&amp;quot;max-w-3xl mx-auto mt-8 py-5 border-t border-gray-200/50 dark:border-gray-700/50 flex flex-col sm:flex-row items-center justify-between gap-4&amp;quot;&amp;gt;
      &amp;lt;p class=&amp;quot;font-medium text-foreground&amp;quot;&amp;gt;¿Te ha gustado? ¡Compártelo!&amp;lt;/p&amp;gt;
      &amp;lt;div class=&amp;quot;flex gap-2&amp;quot;&amp;gt;
        &amp;lt;a href={`https://www.linkedin.com/shareArticle?mini=true&amp;amp;url=${encodeURIComponent(Astro.url.toString())}&amp;amp;title=${encodeURIComponent(title)}`} target=&amp;quot;_blank&amp;quot; rel=&amp;quot;noopener noreferrer&amp;quot; class=&amp;quot;inline-flex h-9 w-9 items-center justify-center rounded-md border border-input bg-background hover:bg-accent transition-colors group&amp;quot;&amp;gt;
          &amp;lt;svg class=&amp;quot;h-4 w-4 transition-transform group-hover:scale-110&amp;quot; fill=&amp;quot;currentColor&amp;quot; viewBox=&amp;quot;0 0 24 24&amp;quot;&amp;gt;
            &amp;lt;path d=&amp;quot;M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z&amp;quot;&amp;gt;&amp;lt;/path&amp;gt;
          &amp;lt;/svg&amp;gt;
        &amp;lt;/a&amp;gt;
        &amp;lt;button id=&amp;quot;copy-link-btn&amp;quot; data-url={Astro.url.toString()} class=&amp;quot;inline-flex h-9 w-9 items-center justify-center rounded-md border border-input bg-background hover:bg-accent transition-colors&amp;quot;&amp;gt;
          &amp;lt;Link2 class=&amp;quot;h-4 w-4&amp;quot; id=&amp;quot;copy-icon-link&amp;quot; /&amp;gt;
          &amp;lt;Check class=&amp;quot;h-4 w-4 text-green-500 hidden&amp;quot; id=&amp;quot;copy-icon-check&amp;quot; /&amp;gt;
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;

    &amp;lt;!-- Navegación --&amp;gt;
    &amp;lt;nav class=&amp;quot;max-w-3xl mx-auto mt-8 pt-8 border-t border-gray-200/50 dark:border-gray-700/50 flex justify-between gap-4&amp;quot;&amp;gt;
      {prev &amp;amp;&amp;amp; (
        &amp;lt;a href={`/blog/${prev.slug}`} class=&amp;quot;group block flex-1 rounded-lg border border-border bg-card p-5 transition-all duration-500 ease-premium hover:shadow-premium hover:border-primary/30 hover:-translate-y-1 hover:scale-[1.05] max-w-sm&amp;quot;&amp;gt;
          &amp;lt;span class=&amp;quot;text-xs text-muted-foreground&amp;quot;&amp;gt;Anterior&amp;lt;/span&amp;gt;
          &amp;lt;h3 class=&amp;quot;text-lg font-semibold group-hover:text-primary&amp;quot;&amp;gt;{prev.data.title}&amp;lt;/h3&amp;gt;
        &amp;lt;/a&amp;gt;
      )}
      {next &amp;amp;&amp;amp; (
        &amp;lt;a href={`/blog/${next.slug}`} class=&amp;quot;group block flex-1 rounded-lg border border-border bg-card p-5 transition-all duration-500 ease-premium hover:shadow-premium hover:border-primary/30 hover:-translate-y-1 hover:scale-[1.05] text-right max-w-sm&amp;quot;&amp;gt;
          &amp;lt;span class=&amp;quot;text-xs text-muted-foreground&amp;quot;&amp;gt;Siguiente&amp;lt;/span&amp;gt;
          &amp;lt;h3 class=&amp;quot;text-lg font-semibold group-hover:text-primary&amp;quot;&amp;gt;{next.data.title}&amp;lt;/h3&amp;gt;
        &amp;lt;/a&amp;gt;
      )}
    &amp;lt;/nav&amp;gt;
  &amp;lt;/article&amp;gt;
&amp;lt;/BaseLayout&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;4. Componentes e Islas de Interactividad&lt;/h2&gt;
&lt;p&gt;El blog es casi 100% estático, lo que garantiza una puntuación de 100 en Lighthouse. Cargamos JavaScript solo mediante &lt;strong&gt;Islas de Interactividad&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Interactividad Reactiva&lt;/strong&gt;: El &lt;code&gt;HeaderMenu.tsx&lt;/code&gt; usa React para un menú móvil fluido, activado con &lt;code&gt;client:load&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Scripts Nativos&lt;/strong&gt;: Para funciones como &amp;quot;Copiar Enlace&amp;quot;, usamos scripts ligeros que se reinicializan con el evento &lt;code&gt;astro:page-load&lt;/code&gt;, asegurando compatibilidad con los &lt;strong&gt;View Transitions&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;5. El Corazón de la Estética: Tailwind v4s&lt;/h2&gt;
&lt;p&gt;El diseño visual no es solo &amp;quot;cosmético&amp;quot;; es una parte integral de la arquitectura. Utilizamos &lt;strong&gt;Tailwind CSS v4&lt;/strong&gt; con el espacio de color &lt;strong&gt;OKLCH&lt;/strong&gt;, lo que permite una gestión del Modo Oscuro basada en la percepción real de la luz:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-css&quot;&gt;/* src/styles/global.css */
@theme inline {
  --ease-premium: cubic-bezier(0.16, 1, 0.3, 1);
  --animate-slide-up: slide-up 0.8s var(--ease-premium) forwards;
  --shadow-premium: 0 20px 25px -5px var(--shadow-color), 0 8px 10px -6px var(--shadow-color);
}

:root {
  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --primary: oklch(0.205 0 0);
  --shadow-color: oklch(from var(--primary) l c h / 0.1);
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --primary: oklch(0.922 0 0);
  --shadow-color: oklch(from var(--primary) l c h / 0.25);
}

@layer utilities {
  .reveal {
    opacity: 0;
    animation: var(--animate-slide-up);
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;script&gt;
  const setupCopyBtn = () =&gt; {
    const copyBtn = document.getElementById(&quot;copy-link-btn&quot;);
    if (!copyBtn || copyBtn.dataset.listener) return;
    copyBtn.dataset.listener = &quot;true&quot;;

    copyBtn.addEventListener(&quot;click&quot;, async () =&gt; {
      const url = copyBtn.getAttribute(&quot;data-url&quot;);
      if (!url) return;
      try {
        await navigator.clipboard.writeText(url);
        const iconLink = document.getElementById(&quot;copy-icon-link&quot;);
        const iconCheck = document.getElementById(&quot;copy-icon-check&quot;);
        if (iconLink &amp;&amp; iconCheck) {
          iconLink.classList.add(&quot;hidden&quot;);
          iconCheck.classList.remove(&quot;hidden&quot;);
          setTimeout(() =&gt; {
            iconLink.classList.remove(&quot;hidden&quot;);
            iconCheck.classList.add(&quot;hidden&quot;);
          }, 2000);
        }
      } catch (e) { console.error(e); }
    });
  };
  setupCopyBtn();
  document.addEventListener(&quot;astro:page-load&quot;, setupCopyBtn);
&lt;/script&gt;&lt;h2&gt;6. Automatización y Build&lt;/h2&gt;
&lt;p&gt;Para que el blog sea mantenible, automatizamos las tareas repetitivas:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;RSS Feed&lt;/strong&gt;: Generado automáticamente en &lt;code&gt;src/pages/rss.xml.ts&lt;/code&gt; incluyendo el contenido completo de los posts.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Imágenes&lt;/strong&gt;: El componente &lt;code&gt;&amp;lt;Image /&amp;gt;&lt;/code&gt; de Astro redimensiona y convierte las imágenes de portada a formatos modernos como WebP/AVIF en tiempo de construcción.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sitemap&lt;/strong&gt;: Generado automáticamente para mejorar el rastreo de Google.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Este blog esta diseñado para ser rápido, accesible y fácil de mantener. Aprovechamos lo mejor de &lt;strong&gt;Astro&lt;/strong&gt; para el rendimiento y la flexibilidad de &lt;strong&gt;React&lt;/strong&gt; y &lt;strong&gt;Tailwind v4&lt;/strong&gt; para una experiencia de usuario premium.&lt;/p&gt;
</content:encoded><category>Desarrollo web</category><category>Proyectos</category><category>Astro</category><author>Hugo Cayón Laso</author></item><item><title>¿Qué es Docker y por qué todo desarrollador debería entenderlo?</title><link>http://localhost:4321/blog/que-es-docker-y-por-que-aprenderlo/</link><guid isPermaLink="true">http://localhost:4321/blog/que-es-docker-y-por-que-aprenderlo/</guid><description>Descubre qué es Docker, cómo funcionan los contenedores y por qué entender esta tecnología es fundamental para cualquier desarrollador moderno.</description><pubDate>Sun, 08 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Introducción&lt;/h2&gt;
&lt;p&gt;Si llevas tiempo desarrollando software, seguro que has vivido esta situación:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;En tu máquina funciona.&lt;/li&gt;
&lt;li&gt;En la de tu compañero no.&lt;/li&gt;
&lt;li&gt;En producción falla.&lt;/li&gt;
&lt;li&gt;En staging se comporta distinto.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Durante años, la configuración de entornos ha sido uno de los mayores puntos de fricción en el desarrollo. Versiones distintas, conflictos con dependencias, diferencias entre sistemas operativos, bases de datos mal configuradas…&lt;/p&gt;
&lt;p&gt;Aquí es donde aparece Docker.&lt;/p&gt;
&lt;p&gt;Docker no es simplemente otra herramienta del ecosistema DevOps. Es una tecnología que cambió radicalmente la forma en la que construimos, distribuimos y ejecutamos aplicaciones.&lt;/p&gt;
&lt;p&gt;En este artículo vamos a ver qué es Docker realmente, qué problema resuelve y por qué entenderlo ya no es opcional para un desarrollador moderno.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;¿Qué es Docker?&lt;/h2&gt;
&lt;p&gt;Docker es una plataforma que permite crear, empaquetar y ejecutar aplicaciones dentro de contenedores.&lt;/p&gt;
&lt;p&gt;Un contenedor es un entorno aislado que incluye:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El código de tu aplicación&lt;/li&gt;
&lt;li&gt;El runtime (Node, Python, PHP, etc.)&lt;/li&gt;
&lt;li&gt;Las dependencias&lt;/li&gt;
&lt;li&gt;Librerías del sistema&lt;/li&gt;
&lt;li&gt;Variables de entorno&lt;/li&gt;
&lt;li&gt;Configuración necesaria&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Todo empaquetado de forma que puede ejecutarse exactamente igual en cualquier máquina que tenga Docker instalado.&lt;/p&gt;
&lt;p&gt;La idea central es simple pero poderosa:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Si funciona dentro del contenedor, funcionará en cualquier entorno.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2&gt;El problema que existía antes de Docker&lt;/h2&gt;
&lt;p&gt;Antes de Docker, el flujo típico era algo así:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Instalar el lenguaje necesario (Node, Java, Python, PHP…).&lt;/li&gt;
&lt;li&gt;Configurar la versión correcta.&lt;/li&gt;
&lt;li&gt;Instalar dependencias.&lt;/li&gt;
&lt;li&gt;Instalar y configurar la base de datos.&lt;/li&gt;
&lt;li&gt;Ajustar variables de entorno.&lt;/li&gt;
&lt;li&gt;Resolver conflictos con otros proyectos.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Y si el proyecto cambiaba de servidor o de equipo… comenzaban los problemas.&lt;/p&gt;
&lt;p&gt;Los errores más comunes eran:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Diferencias de versión.&lt;/li&gt;
&lt;li&gt;Dependencias que no estaban instaladas.&lt;/li&gt;
&lt;li&gt;Configuraciones inconsistentes.&lt;/li&gt;
&lt;li&gt;&amp;quot;Funciona en mi máquina&amp;quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Docker nace precisamente para eliminar esa fricción.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;¿Qué es exactamente un contenedor?&lt;/h2&gt;
&lt;p&gt;Un contenedor no es una máquina virtual.&lt;/p&gt;
&lt;p&gt;Esta es una confusión muy común.&lt;/p&gt;
&lt;h3&gt;Máquina virtual&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Virtualiza un sistema operativo completo.&lt;/li&gt;
&lt;li&gt;Necesita un hipervisor.&lt;/li&gt;
&lt;li&gt;Consume más recursos.&lt;/li&gt;
&lt;li&gt;Es más pesada.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Contenedor&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Comparte el kernel del sistema operativo.&lt;/li&gt;
&lt;li&gt;Solo aísla procesos y dependencias.&lt;/li&gt;
&lt;li&gt;Es mucho más ligero.&lt;/li&gt;
&lt;li&gt;Arranca en segundos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Por eso Docker revolucionó la infraestructura: permitió ejecutar aplicaciones aisladas sin el coste de virtualizar sistemas completos.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Conceptos clave de Docker&lt;/h2&gt;
&lt;p&gt;Para entender Docker necesitas dominar tres conceptos fundamentales.&lt;/p&gt;
&lt;h3&gt;1. Imagen&lt;/h3&gt;
&lt;p&gt;Una imagen es una plantilla inmutable que contiene todo lo necesario para ejecutar una aplicación.&lt;/p&gt;
&lt;p&gt;Se construye a partir de un archivo llamado &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;La imagen no se ejecuta directamente; sirve como base para crear contenedores.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;2. Contenedor&lt;/h3&gt;
&lt;p&gt;Un contenedor es una instancia en ejecución de una imagen.&lt;/p&gt;
&lt;p&gt;Puedes crear múltiples contenedores a partir de la misma imagen.&lt;/p&gt;
&lt;p&gt;Es el equivalente a decir:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Imagen → Clase&lt;/li&gt;
&lt;li&gt;Contenedor → Objeto&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3&gt;3. Dockerfile&lt;/h3&gt;
&lt;p&gt;Es el archivo donde defines cómo se construye tu imagen.&lt;/p&gt;
&lt;p&gt;Ejemplo básico para una aplicación Node.js:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-dockerfile&quot;&gt;FROM node:20

WORKDIR /app

COPY package*.json ./
RUN npm install

COPY . .

EXPOSE 3000

CMD [&amp;quot;npm&amp;quot;, &amp;quot;start&amp;quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Con este archivo puedes generar una imagen reproducible y ejecutarla en cualquier máquina.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;¿Qué es Docker Compose?&lt;/h3&gt;
&lt;p&gt;En proyectos reales rara vez tienes un solo servicio.&lt;/p&gt;
&lt;p&gt;Normalmente necesitas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backend&lt;/li&gt;
&lt;li&gt;Base de datos&lt;/li&gt;
&lt;li&gt;Servicio de colas&lt;/li&gt;
&lt;li&gt;Frontend&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Aquí entra Docker Compose.&lt;/p&gt;
&lt;p&gt;Docker Compose permite definir múltiples servicios en un solo archivo &lt;code&gt;docker-compose.yml&lt;/code&gt; y levantarlos con un único comando:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker compose up
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esto simplifica enormemente el desarrollo local y el onboarding de nuevos desarrolladores.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;¿Qué problemas resuelve Docker en el día a día?&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Entornos idénticos&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Desarrollo, testing y producción pueden ser prácticamente iguales.&lt;/p&gt;
&lt;ol start=&quot;2&quot;&gt;
&lt;li&gt;Aislamiento de dependencias&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Cada proyecto puede tener su propia versión de:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Node&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sin conflictos entre ellos.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Onboarding rápido&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Un nuevo miembro del equipo puede levantar el proyecto en minutos.&lt;/p&gt;
&lt;ol start=&quot;4&quot;&gt;
&lt;li&gt;Portabilidad&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Puedes mover tu aplicación a:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Un VPS&lt;/li&gt;
&lt;li&gt;Un servidor físico&lt;/li&gt;
&lt;li&gt;Un proveedor cloud&lt;/li&gt;
&lt;li&gt;Un entorno de CI/CD&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sin modificar la configuración interna.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;¿Por qué todo desarrollador debería entender Docker?&lt;/h3&gt;
&lt;p&gt;Aquí es donde la parte técnica se convierte en estratégica.&lt;/p&gt;
&lt;p&gt;Es un estándar de la industria&lt;/p&gt;
&lt;p&gt;Hoy en día, la mayoría de empresas medianas y grandes trabajan con contenedores.&lt;/p&gt;
&lt;p&gt;No entender Docker limita tu crecimiento profesional.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Es la base de arquitecturas modernas&lt;/h3&gt;
&lt;p&gt;Microservicios, CI/CD, despliegues automatizados, escalabilidad horizontal…&lt;/p&gt;
&lt;p&gt;Todo esto parte de contenedores.&lt;/p&gt;
&lt;p&gt;Si en el futuro quieres trabajar con orquestadores o infraestructura más avanzada, Docker es el primer paso.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Mejora tu mentalidad como desarrollador&lt;/h3&gt;
&lt;p&gt;Trabajar con Docker te obliga a:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Separar responsabilidades.&lt;/li&gt;
&lt;li&gt;Pensar en servicios independientes.&lt;/li&gt;
&lt;li&gt;Diseñar aplicaciones más limpias.&lt;/li&gt;
&lt;li&gt;Tener entornos reproducibles.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Te profesionaliza.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Aumenta tu valor en el mercado laboral&lt;/h3&gt;
&lt;p&gt;Saber programar está bien.&lt;/p&gt;
&lt;p&gt;Saber programar y además entender cómo se despliega y ejecuta tu aplicación en producción es otro nivel.&lt;/p&gt;
&lt;p&gt;Muchas empresas valoran más a desarrolladores que entienden infraestructura básica que a perfiles puramente centrados en código.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;¿Debe aprender Docker un desarrollador junior?&lt;/h3&gt;
&lt;p&gt;Sí, pero con enfoque correcto.&lt;/p&gt;
&lt;p&gt;No necesitas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dominar Kubernetes.&lt;/li&gt;
&lt;li&gt;Saber optimización avanzada de imágenes.&lt;/li&gt;
&lt;li&gt;Diseñar clusters complejos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sí necesitas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Entender qué es una imagen.&lt;/li&gt;
&lt;li&gt;Crear un Dockerfile básico.&lt;/li&gt;
&lt;li&gt;Mapear puertos.&lt;/li&gt;
&lt;li&gt;Usar volúmenes.&lt;/li&gt;
&lt;li&gt;Levantar servicios con Docker Compose.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Eso ya te diferencia bastante.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;¿Docker es solo para backend?&lt;/h3&gt;
&lt;p&gt;No.&lt;/p&gt;
&lt;p&gt;Se usa en:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Frontend (control de versiones de Node).&lt;/li&gt;
&lt;li&gt;Testing automatizado.&lt;/li&gt;
&lt;li&gt;Data engineering.&lt;/li&gt;
&lt;li&gt;Machine learning.&lt;/li&gt;
&lt;li&gt;DevOps.&lt;/li&gt;
&lt;li&gt;Microservicios.&lt;/li&gt;
&lt;li&gt;Entornos para demos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Docker no pertenece a un stack concreto. Es una herramienta transversal.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;¿Tiene sentido aprender Docker en 2026?&lt;/h3&gt;
&lt;p&gt;Absolutamente.&lt;/p&gt;
&lt;p&gt;Mientras existan:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Entornos distintos.&lt;/li&gt;
&lt;li&gt;Equipos distribuidos.&lt;/li&gt;
&lt;li&gt;Aplicaciones complejas.&lt;/li&gt;
&lt;li&gt;Despliegues automatizados.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Docker seguirá siendo relevante.&lt;/p&gt;
&lt;p&gt;Puede que las herramientas evolucionen, pero el concepto de contenedores ya forma parte estructural del desarrollo moderno.&lt;/p&gt;
&lt;p&gt;Entender Docker no es solo aprender una herramienta más, es dar un paso hacia una forma más profesional de desarrollar software. Si quieres crecer como desarrollador, empieza por dominar las bases que realmente utiliza la industria.&lt;/p&gt;
</content:encoded><category>Infraestructura</category><category>Contenedores</category><category>Backend</category><category>DevOps</category><category>Docker</category><author>Hugo Cayón Laso</author></item><item><title>Tendencias de lenguajes de programación en 2026</title><link>http://localhost:4321/blog/tendencias-lenguajes-programacion-2026/</link><guid isPermaLink="true">http://localhost:4321/blog/tendencias-lenguajes-programacion-2026/</guid><description>Análisis actualizado de los 15 lenguajes de programación más populares según el índice TIOBE de febrero de 2026, con sectores y usos comunes.</description><pubDate>Sat, 14 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Introducción&lt;/h2&gt;
&lt;p&gt;Elegir qué lenguaje de programación aprender o usar en un proyecto es una decisión estratégica que debe basarse en tendencias globales, sectores de aplicación y perspectivas de crecimiento. El &lt;strong&gt;TIOBE Programming Community Index&lt;/strong&gt; es uno de los indicadores más seguidos para medir la &lt;strong&gt;popularidad de los lenguajes de programación&lt;/strong&gt; a partir de búsquedas y referencias en motores de búsqueda y recursos en línea.&lt;/p&gt;
&lt;p&gt;En este artículo analizamos el &lt;strong&gt;top 15 del índice TIOBE de febrero de 2026&lt;/strong&gt;, lo que significa que no solo cubrimos los clásicos del top 10, sino también lenguajes relevantes que están ganando tracción o manteniendo nichos sólidos.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Tabla: Ranking de lenguajes de programación (TIOBE Index, febrero 2026)&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Posición&lt;/th&gt;
&lt;th&gt;Lenguaje&lt;/th&gt;
&lt;th&gt;Popularidad (%)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Python&lt;/td&gt;
&lt;td&gt;21.81%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;C&lt;/td&gt;
&lt;td&gt;11.05%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;3&lt;/td&gt;
&lt;td&gt;C++&lt;/td&gt;
&lt;td&gt;8.55%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;td&gt;8.12%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;C#&lt;/td&gt;
&lt;td&gt;6.83%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;td&gt;JavaScript&lt;/td&gt;
&lt;td&gt;2.92%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;td&gt;Visual Basic&lt;/td&gt;
&lt;td&gt;2.85%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;8&lt;/td&gt;
&lt;td&gt;R&lt;/td&gt;
&lt;td&gt;2.19%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;9&lt;/td&gt;
&lt;td&gt;SQL&lt;/td&gt;
&lt;td&gt;1.93%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Delphi / Object Pascal&lt;/td&gt;
&lt;td&gt;1.88%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;11&lt;/td&gt;
&lt;td&gt;Perl&lt;/td&gt;
&lt;td&gt;1.67%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;12&lt;/td&gt;
&lt;td&gt;Fortran&lt;/td&gt;
&lt;td&gt;1.64%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;13&lt;/td&gt;
&lt;td&gt;PHP&lt;/td&gt;
&lt;td&gt;1.34%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;14&lt;/td&gt;
&lt;td&gt;Rust&lt;/td&gt;
&lt;td&gt;1.32%&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;15&lt;/td&gt;
&lt;td&gt;Scratch&lt;/td&gt;
&lt;td&gt;1.30%&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Fuente: &lt;a href=&quot;https://www.tiobe.com/tiobe-index/&quot;&gt;TIOBE Programming Community Index, febrero 2026&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Lenguajes más usados y sus sectores&lt;/h2&gt;
&lt;h3&gt;Python&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; backend web, ciencia de datos, machine learning e inteligencia artificial, automatización, scripting.
&lt;strong&gt;Sectores:&lt;/strong&gt; startups tecnológicas, fintech, consultoras TI, investigación científica, educación.&lt;/p&gt;
&lt;p&gt;Python mantiene una amplia ventaja en popularidad, liderando el ranking con más del doble de participación que el siguiente competidor. Su sintaxis clara y su ecosistema lo hacen ideal para proyectos de análisis de datos o prototipos rápidos.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;C&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; sistemas operativos, firmware, drivers, programación embebida.
&lt;strong&gt;Sectores:&lt;/strong&gt; electrónica, automoción, telecomunicaciones industriales, sistemas embebidos.&lt;/p&gt;
&lt;p&gt;C ocupa una posición firme en segundo lugar gracias a su eficiencia y control sobre hardware, lo que lo hace imprescindible en entornos donde el rendimiento y la cercanía al sistema son cruciales.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;C++&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; motores de videojuegos, aplicaciones de alto rendimiento, simulación, realidad virtual.
&lt;strong&gt;Sectores:&lt;/strong&gt; entretenimiento digital, fintech de alta frecuencia, simulación avanzada.&lt;/p&gt;
&lt;p&gt;C++ añade abstracción orientada a objetos sin comprometer el rendimiento, lo que lo mantiene relevante para aplicaciones exigentes en tiempo real.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Java&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; backend empresarial, aplicaciones Android, sistemas distribuidos.
&lt;strong&gt;Sectores:&lt;/strong&gt; banca, seguros, telecomunicaciones, grandes corporativos.&lt;/p&gt;
&lt;p&gt;Java sigue siendo una pieza clave en software de misión crítica para empresas grandes debido a su estabilidad, escalabilidad y portabilidad.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;C#&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; aplicaciones de escritorio y web con .NET, desarrollo de videojuegos con Unity.
&lt;strong&gt;Sectores:&lt;/strong&gt; entretenimiento digital, corporativo, desarrollo de software multiplataforma.&lt;/p&gt;
&lt;p&gt;C# continúa su ascenso como lenguaje versátil para backend, aplicaciones empresariales y juegos, y fue destacado como &lt;em&gt;Language of the Year&lt;/em&gt; por su crecimiento reciente.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;JavaScript&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; desarrollo web frontend, aplicaciones full‑stack con Node.js, SPA.
&lt;strong&gt;Sectores:&lt;/strong&gt; desarrollo web, ecommerce, SaaS, startups tecnológicas.&lt;/p&gt;
&lt;p&gt;JavaScript sigue siendo el estándar para la web por su uso universal en navegadores y soporte en frameworks modernos.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Visual Basic&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; aplicaciones empresariales de escritorio, herramientas internas.
&lt;strong&gt;Sectores:&lt;/strong&gt; empresas con software legacy, automatización de procesos internos.&lt;/p&gt;
&lt;p&gt;Aunque antiguo, Visual Basic aún se mantiene en el top debido a su base instalada en aplicaciones corporativas tradicionales.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;R&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; análisis estadístico, visualización de datos, investigación académica.
&lt;strong&gt;Sectores:&lt;/strong&gt; ciencia de datos, biotecnología, investigación científica y análisis avanzado.&lt;/p&gt;
&lt;p&gt;R ha recuperado relevancia gracias a su especialización en estadísticas complejas y análisis de datos intensivo.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;SQL&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; gestión y consulta de bases de datos relacionales.
&lt;strong&gt;Sectores:&lt;/strong&gt; prácticamente todos los sectores basados en datos (retail, banca, logística).&lt;/p&gt;
&lt;p&gt;SQL sigue siendo indispensable para cualquier proyecto que requiera interacción con bases de datos.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Delphi / Object Pascal&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; desarrollo de aplicaciones de escritorio y software legado.
&lt;strong&gt;Sectores:&lt;/strong&gt; empresas con aplicaciones históricas que requieren mantenimiento.&lt;/p&gt;
&lt;p&gt;Este lenguaje tradicional aún aparece en el top debido a su presencia continua en sistemas corporativos y aplicaciones especializadas.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Perl&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; scripting, administración de sistemas, procesamiento de texto.
&lt;strong&gt;Sectores:&lt;/strong&gt; infraestructura de TI, bioinformática, administración de servidores.&lt;/p&gt;
&lt;p&gt;Perl ha vuelto a aparecer en posiciones medias del ranking, probablemente vinculado a su uso histórico en scripts y herramientas de automatización.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Fortran&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; cómputo científico, simulaciones numéricas, ingeniería.
&lt;strong&gt;Sectores:&lt;/strong&gt; investigación científica, ingeniería aeroespacial, modelado numérico.&lt;/p&gt;
&lt;p&gt;Aunque antiguo, Fortran sigue presente en entornos científicos de alto rendimiento que dependen de su eficiencia en cálculos numéricos.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;PHP&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; desarrollo web backend, sistemas de gestión de contenido (CMS).
&lt;strong&gt;Sectores:&lt;/strong&gt; agencias web, sitios de contenido dinámico, ecommerce.&lt;/p&gt;
&lt;p&gt;A pesar de no estar en el top 10, PHP sigue siendo ampliamente utilizado en desarrollo web tradicional, especialmente en sistemas como WordPress y frameworks como Laravel.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Rust&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; desarrollo de sistemas seguros, concurrencia, software de backend.
&lt;strong&gt;Sectores:&lt;/strong&gt; software de infraestructura, seguridad, servicios de alto rendimiento.&lt;/p&gt;
&lt;p&gt;Rust ha ganado visibilidad por su enfoque en seguridad y control de memoria sin sacrificar rendimiento, aunque su porcentaje aún es moderado.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Scratch&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Usos comunes:&lt;/strong&gt; educación y enseñanza de programación básica.
&lt;strong&gt;Sectores:&lt;/strong&gt; educación primaria y secundaria, introducción a la programación para principiantes.&lt;/p&gt;
&lt;p&gt;Scratch no destaca por uso profesional, pero sigue siendo popular en la educación para introducir conceptos de lógica y programación.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;El ranking de &lt;strong&gt;15 lenguajes de programación en 2026&lt;/strong&gt; muestra un equilibrio entre &lt;strong&gt;clasicos bien establecidos&lt;/strong&gt; y &lt;strong&gt;lenguajes especializados con nichos fuertes&lt;/strong&gt;. Lenguajes como Python, C, Java y C# dominan por su versatilidad y adopción en múltiples sectores, mientras que otros como R o Rust se destacan en áreas más específicas como ciencia de datos o sistemas seguros.&lt;/p&gt;
&lt;p&gt;Este tipo de tendencias ayudan no solo a decidir qué aprender, sino también a entender &lt;strong&gt;qué tecnologías son más relevantes según el tipo de proyecto o sector en el que te mueves&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Nos vemos en el próximo post, y mientras tanto, sigue experimentando y aprendiendo con los lenguajes que más te interesen.&lt;/p&gt;
</content:encoded><category>Desarrollo de software</category><category>TIOBE Index</category><category>Lenguajes de programación</category><category>Programación</category><author>Hugo Cayón Laso</author></item><item><title>Mi sistema de apuntes como desarrollador</title><link>http://localhost:4321/blog/mi-sistema-de-apuntes/</link><guid isPermaLink="true">http://localhost:4321/blog/mi-sistema-de-apuntes/</guid><description>Cómo organizo mis apuntes técnicos combinando papel y Obsidian para aprender mejor, recordar más y tomar mejores decisiones como desarrollador.</description><pubDate>Fri, 06 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;El desarrollo web no solo avanza rápido, también genera una cantidad abrumadora de información. Documentación, tutoriales, vídeos, posts técnicos… el contenido nunca se acaba. El problema no es encontrar qué aprender, sino &lt;strong&gt;qué hacer con todo lo que aprendes y cómo lo procesas&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Durante mucho tiempo tomé apuntes sin un criterio claro. Guardaba enlaces &amp;quot;por si acaso&amp;quot;, copiaba fragmentos de documentación y escribía notas que parecían útiles en el momento, pero que rara vez volvía a leer. Cuando necesitaba consultar algo, encontrar la nota concreta era tedioso. Tenía muchas notas, pero poco conocimiento realmente consolidado.&lt;/p&gt;
&lt;p&gt;Con el tiempo empecé a notar un patrón frustrante: volvía a investigar cosas que ya había aprendido antes, repetía errores y dudaba sobre decisiones técnicas que ya había tomado en el pasado. Mis apuntes no me estaban ayudando a pensar mejor, solo a almacenar información.&lt;/p&gt;
&lt;p&gt;Ahí entendí que el problema no era la herramienta, sino &lt;strong&gt;la falta de un sistema&lt;/strong&gt;. Necesitaba una forma de tomar apuntes que me ayudara a entender, filtrar y conectar ideas para tomar mejores decisiones como desarrollador.&lt;/p&gt;
&lt;p&gt;Este post explica cómo funciona mi sistema de apuntes usando Obsidian, qué principios sigo y cómo lo aplico en el día a día.&lt;/p&gt;
&lt;h2&gt;1. Por qué uso Obsidian para mis apuntes&lt;/h2&gt;
&lt;p&gt;Obsidian no es una herramienta mágica, pero encaja muy bien con cómo me gusta trabajar.&lt;/p&gt;
&lt;p&gt;Lo que más valoro es que:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Mis notas son archivos Markdown normales&lt;/li&gt;
&lt;li&gt;No dependo de una plataforma externa&lt;/li&gt;
&lt;li&gt;Puedo enlazar ideas fácilmente&lt;/li&gt;
&lt;li&gt;Es rápido y no me distrae&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Obsidian no impone una estructura concreta. Eso significa que &lt;strong&gt;el sistema lo defines tú&lt;/strong&gt;, y eso es justo lo que buscaba.&lt;/p&gt;
&lt;h2&gt;2. Los principios de mi sistema de apuntes&lt;/h2&gt;
&lt;p&gt;Antes de hablar de carpetas o notas, hay algunas ideas clave que guían todo el sistema.&lt;/p&gt;
&lt;h3&gt;Escribo para entender, no para guardar&lt;/h3&gt;
&lt;p&gt;Si una nota es solo un copia y pega de documentación, no me sirve. Escribir es parte del proceso de comprensión.&lt;/p&gt;
&lt;h3&gt;Menos notas, mejor pensadas&lt;/h3&gt;
&lt;p&gt;Prefiero pocas notas útiles que muchas notas mediocres que nunca volveré a abrir.&lt;/p&gt;
&lt;h3&gt;Escribo para mi yo del futuro&lt;/h3&gt;
&lt;p&gt;Mis notas no están pensadas para ser formales, sino claras. Las escribo como si me explicara algo a mí mismo dentro de seis meses.&lt;/p&gt;
&lt;h3&gt;Las notas deben ayudarme a decidir&lt;/h3&gt;
&lt;p&gt;Una buena nota me ahorra tiempo en el futuro: evita que vuelva a investigar lo mismo o que dude sobre decisiones ya tomadas.&lt;/p&gt;
&lt;h2&gt;3. Cómo organizo mis apuntes en Obsidian&lt;/h2&gt;
&lt;p&gt;Mi estructura es sencilla a propósito. No quiero perder tiempo decidiendo dónde va cada cosa.&lt;/p&gt;
&lt;p&gt;Las carpetas principales que uso son:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;conceptos&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;herramientas&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;snippets&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;decisiones&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ideas&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;proyectos&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Las carpetas solo aportan contexto general. La verdadera organización viene de los &lt;strong&gt;enlaces entre notas&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;4. Tipos de notas que utilizo&lt;/h2&gt;
&lt;h3&gt;Notas de conceptos&lt;/h3&gt;
&lt;p&gt;Aquí explico ideas clave con mis propias palabras.&lt;/p&gt;
&lt;p&gt;Por ejemplo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qué es un concepto&lt;/li&gt;
&lt;li&gt;Cuándo tiene sentido usarlo&lt;/li&gt;
&lt;li&gt;Cuándo no&lt;/li&gt;
&lt;li&gt;Con qué otros conceptos se relaciona&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No busco definiciones perfectas, sino comprensión real.&lt;/p&gt;
&lt;h3&gt;Notas de herramientas&lt;/h3&gt;
&lt;p&gt;Cada herramienta que uso tiene su propia nota.&lt;/p&gt;
&lt;p&gt;Incluyen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Para qué la uso&lt;/li&gt;
&lt;li&gt;Cosas que suelo olvidar&lt;/li&gt;
&lt;li&gt;Problemas comunes&lt;/li&gt;
&lt;li&gt;Decisiones que he tomado al usarla&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Estas notas evolucionan con el tiempo, igual que mi experiencia.&lt;/p&gt;
&lt;h3&gt;Snippets con contexto&lt;/h3&gt;
&lt;p&gt;No guardo código suelto sin más.&lt;/p&gt;
&lt;p&gt;Cada snippet va acompañado de:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Qué problema resuelve&lt;/li&gt;
&lt;li&gt;Cuándo usarlo&lt;/li&gt;
&lt;li&gt;Por qué existe&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El código sin contexto pierde valor muy rápido.&lt;/p&gt;
&lt;h3&gt;Decisiones técnicas&lt;/h3&gt;
&lt;p&gt;Este tipo de nota es de las más valiosas.&lt;/p&gt;
&lt;p&gt;Aquí dejo constancia de decisiones como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Por qué elegí una tecnología frente a otra&lt;/li&gt;
&lt;li&gt;Qué alternativas descarté&lt;/li&gt;
&lt;li&gt;Qué compromisos acepté&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Meses después, estas notas evitan muchas dudas.&lt;/p&gt;
&lt;h3&gt;Ideas&lt;/h3&gt;
&lt;p&gt;Aquí guardo pensamientos sueltos, ideas de posts, mejoras o proyectos futuros.&lt;/p&gt;
&lt;p&gt;Muchas no llegan a nada, pero algunas conectan con otras notas y acaban creciendo.&lt;/p&gt;
&lt;h2&gt;5. Cómo tomo apuntes en la práctica (mi flujo actual)&lt;/h2&gt;
&lt;p&gt;Con el tiempo me di cuenta de que escribir directamente en Obsidian no siempre era la mejor forma de pensar. Ahora mi proceso tiene &lt;strong&gt;dos fases claras&lt;/strong&gt;: primero escribo a mano y después consolido en Obsidian.&lt;/p&gt;
&lt;h3&gt;Primera fase: cuaderno y papel&lt;/h3&gt;
&lt;p&gt;Cuando estoy aprendiendo algo nuevo —leyendo documentación, viendo un vídeo o resolviendo un problema— anoto a mano lo que considero importante:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ideas clave&lt;/li&gt;
&lt;li&gt;Dudas&lt;/li&gt;
&lt;li&gt;Conceptos que no termino de entender&lt;/li&gt;
&lt;li&gt;Frases que me ayudan a hacer clic&amp;quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El cuaderno es rápido, imperfecto y sin estructura. No busco orden, solo &lt;strong&gt;pensar y entender&lt;/strong&gt;. Muchas de esas notas nunca llegarán a Obsidian, y está bien así.&lt;/p&gt;
&lt;h3&gt;Segunda fase: Obsidian como apunte definitivo&lt;/h3&gt;
&lt;p&gt;Más tarde, normalmente con algo de distancia, reviso esas notas y hago un filtro consciente:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;¿Esto merece la pena conservarlo?&lt;/li&gt;
&lt;li&gt;¿Es algo que quiero recordar en el futuro?&lt;/li&gt;
&lt;li&gt;¿Me ayudará a tomar mejores decisiones?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Solo entonces creo la nota en Obsidian.
Ahí sí escribo con calma, con mis propias palabras y conectando la idea con otros conceptos o notas existentes.&lt;/p&gt;
&lt;p&gt;Obsidian no es donde pienso por primera vez, sino donde &lt;strong&gt;dejo el conocimiento ya procesado&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Qué ventaja tiene este enfoque&lt;/h3&gt;
&lt;p&gt;Este flujo me obliga a:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No guardar información innecesaria&lt;/li&gt;
&lt;li&gt;Entender antes de documentar&lt;/li&gt;
&lt;li&gt;Quedarme solo con lo realmente importante&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mis notas en Obsidian son menos, pero mucho más valiosas. No son apuntes en bruto, sino conocimiento destilado.&lt;/p&gt;
&lt;h2&gt;6. Errores que cometí al principio&lt;/h2&gt;
&lt;p&gt;Como casi todo el mundo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Creé demasiadas carpetas&lt;/li&gt;
&lt;li&gt;Escribí notas demasiado largas&lt;/li&gt;
&lt;li&gt;Copié información sin procesarla&lt;/li&gt;
&lt;li&gt;Busqué el sistema perfecto&lt;/li&gt;
&lt;li&gt;Perdí tiempo ajustando plugins&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;El sistema mejoró cuando dejé de optimizarlo y empecé a &lt;strong&gt;usarlo de verdad&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;7. Qué me aporta este sistema&lt;/h2&gt;
&lt;p&gt;Gracias a este enfoque:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Aprendo con menos fricción&lt;/li&gt;
&lt;li&gt;Recuerdo mejor lo importante&lt;/li&gt;
&lt;li&gt;Tomo decisiones técnicas con más claridad&lt;/li&gt;
&lt;li&gt;Evito repetir errores&lt;/li&gt;
&lt;li&gt;Escribir posts técnicos me resulta más natural&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mis apuntes no son un archivo muerto, son una extensión de cómo pienso.&lt;/p&gt;
&lt;h2&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Tomar apuntes no va de capturar toda la información que consumes, sino de &lt;strong&gt;transformarla en conocimiento propio&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Obsidian es solo la herramienta. El verdadero valor está en escribir para entender, filtrar lo importante y dejar rastro de tu proceso mental como desarrollador.&lt;/p&gt;
&lt;p&gt;No existe un sistema universal. Este es el mío, y funciona porque evoluciona conmigo.&lt;/p&gt;
&lt;p&gt;Si tienes tu propio sistema de apuntes o estás intentando construir uno, seguro que ya vas por buen camino.&lt;/p&gt;
&lt;p&gt;Sigue tomando notas, experimentando y adaptando tu sistema: al final, tus apuntes no son solo información, son la forma en que piensas y creces como desarrollador.&lt;/p&gt;
</content:encoded><category>Productividad</category><category>Desarrollo web</category><category>Aprendizaje</category><category>Obsidian</category><author>Hugo Cayón Laso</author></item><item><title>La IA en el flujo de desarrollo: ¿herramienta imprescindible o fuente de incertidumbre?</title><link>http://localhost:4321/blog/ia-en-el-flujo-de-desarrollo/</link><guid isPermaLink="true">http://localhost:4321/blog/ia-en-el-flujo-de-desarrollo/</guid><description>Analizo cómo la inteligencia artificial está transformando el proceso de desarrollo de software en 2026, sus beneficios, riesgos y cómo puedes sacar provecho sin perder calidad.</description><pubDate>Sat, 31 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;La IA en el flujo de desarrollo: ¿herramienta imprescindible o fuente de incertidumbre?&lt;/h2&gt;
&lt;p&gt;La llegada de &lt;strong&gt;herramientas de inteligencia artificial al flujo de desarrollo&lt;/strong&gt; es, posiblemente, la transformación más importante del software en los últimos años. Ya no hablamos de asistentes que completan líneas de código: hablamos de sistemas que &lt;strong&gt;proponen soluciones completas, generan tests, sugieren arquitectura, corrigen errores e incluso planean tareas&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Pero no todo es color de rosa: aunque el uso ha crecido de forma espectacular, &lt;strong&gt;la confianza en lo que producen estas herramientas está bajando&lt;/strong&gt; entre la comunidad de desarrolladores.&lt;/p&gt;
&lt;p&gt;En este post veremos &lt;strong&gt;qué significa realmente esta era de IA integrada en el desarrollo&lt;/strong&gt;, cómo influye en el workflow, y cómo aprovecharla de forma responsable y productiva en 2026.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;1. IA como asistente integral en el ciclo de vida del software&lt;/h2&gt;
&lt;p&gt;Según datos de encuestas y estudios recientes, &lt;strong&gt;hasta el 84 % de los desarrolladores ya usan o planean usar IA en su workflow&lt;/strong&gt;, y más de la mitad la utiliza a diario.&lt;/p&gt;
&lt;p&gt;Herramientas como &lt;strong&gt;GitHub Copilot, Claude Code o CodeWhisperer&lt;/strong&gt; ya no se limitan a completar líneas de código:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Generan funciones completas&lt;/strong&gt;, basadas en descripciones de alto nivel.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ayudan a detectar y corregir errores automáticamente.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pueden sugerir pruebas unitarias, documentación o refactorizaciones.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Algunos sistemas incluso analizan patrones de arquitectura y recomiendan estructura de proyecto.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;¿Qué aporta esto a tu día a día?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mayor productividad&lt;/strong&gt;: tareas que antes llevaban horas pueden completarse en minutos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Automatización de rutinas&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mejor calidad de código&lt;/strong&gt; cuando se usa sabiamente.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Onboarding acelerado&lt;/strong&gt; de nuevos miembros en proyectos complejos.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;2. El lado oscuro: confianza en las respuestas de IA&lt;/h2&gt;
&lt;p&gt;Aunque la adopción es alta, también hay un fenómeno curioso: &lt;strong&gt;la confianza en lo que generan estas herramientas está cayendo&lt;/strong&gt;. En una encuesta reciente, menos de la mitad de los desarrolladores confiaba plenamente en el código sugerido por IA, y muchos reportaron que el resultado a menudo estaba &amp;quot;casi bien, pero con errores sutiles&amp;quot;.&lt;/p&gt;
&lt;h3&gt;Problemas habituales&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Código &amp;quot;casi correcto&amp;quot;&lt;/strong&gt; que compila pero falla en casos límite.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sugerencias con bugs no evidentes al principio.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Respuestas que dependen de contexto parcial o mal interpretado.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dependencia de prompts mal formulados.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto ha generado un debate interesante: &lt;strong&gt;¿la IA está realmente elevando la calidad del software o solo la velocidad con la que se produce código mediocre?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Por el momento es innegable que la IA sirve como soporte y ayuda, dando solución a pequeños problemas o dudas al desarrollador. De esta manera, se agiliza el trabajo y se es más productivo.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;3. La IA cambia tu rol como desarrollador&lt;/h2&gt;
&lt;p&gt;Entonces, si la IA puede escribir código por ti… ¿qué papel queda para el desarrollador?&lt;/p&gt;
&lt;p&gt;La respuesta que ha surgido en la industria es &lt;strong&gt;que el rol del desarrollador está evolucionando&lt;/strong&gt;: ya no se trata solo de &lt;em&gt;escribir código manualmente&lt;/em&gt;, sino de &lt;strong&gt;diseñar, supervisar, orquestar y corregir el output que generan las IA&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Habilidades que están creciendo en importancia&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Arquitectura de sistemas&lt;/strong&gt;: diseñar cómo encajan los módulos y dependencias.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Pensamiento crítico&lt;/strong&gt;: evaluar si la solución propuesta por IA es adecuada.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Testing exhaustivo&lt;/strong&gt;: validar que el código funciona en todos los casos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CI/CD y DevOps automatizado&lt;/strong&gt;: la infraestructura se despliega sola, pero &lt;strong&gt;debes validarla y optimizarla&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Seguridad DevSecOps&lt;/strong&gt;: incorporar pruebas y controles de seguridad desde la primera línea.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En otras palabras, &lt;strong&gt;la IA está subiendo el listón de lo que se espera de un buen desarrollador&lt;/strong&gt;: no es solo &lt;em&gt;saber un lenguaje&lt;/em&gt;, sino &lt;em&gt;saber cómo usar la IA para planear, validar y entregar software robusto&lt;/em&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;4. Nuevas metodologías: AI-First y Agentic Workflows&lt;/h2&gt;
&lt;p&gt;En 2026 está emergiendo un nuevo concepto: &lt;strong&gt;AI-First development&lt;/strong&gt; — donde se considera que los flujos de trabajo comienzan con IA y se construyen alrededor de ella.&lt;/p&gt;
&lt;p&gt;Esto incluye:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AI agents&lt;/strong&gt; que no solo sugieren código, sino que &lt;strong&gt;ejecutan tareas completas&lt;/strong&gt;, como crear tests, abrir PRs o analizar dependencias.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Workflow orientado a prompts&lt;/strong&gt; en lugar de tareas manuales secuenciales.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generación automática de documentación y diagramas arquitectónicos&lt;/strong&gt; a medida que se actualiza el código.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto redefine &lt;em&gt;cómo&lt;/em&gt; y &lt;em&gt;dónde&lt;/em&gt; las personas y máquinas colaboran: tú ya no eres &amp;quot;la fuente de todo código&amp;quot;, sino el &lt;strong&gt;director de la orquesta&lt;/strong&gt;, mientras la IA asume tareas de ejecución.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;5. Recomendaciones para usar IA responsablemente&lt;/h2&gt;
&lt;p&gt;Si vas a integrar IA en tu flujo de trabajo —y hoy practicamente todo equipo lo hace— esta es una guía breve para hacerlo bien:&lt;/p&gt;
&lt;h3&gt;Siempre revisa y prueba&lt;/h3&gt;
&lt;p&gt;No aceptes sugerencias sin &lt;em&gt;code review&lt;/em&gt; y validación, porque los entornos reales exigen &lt;em&gt;robustez, no velocidad pura&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;Integra con testing automatizado&lt;/h3&gt;
&lt;p&gt;Haz que la IA genere pruebas unitarias, pero &lt;strong&gt;ejecuta tú mismo pruebas integrales&lt;/strong&gt;, mocks y casos extremos.&lt;/p&gt;
&lt;h3&gt;Entrena tu propio modelo o afinación&lt;/h3&gt;
&lt;p&gt;Si usas IA en el stack de tu empresa, considera afinar modelos con tu propio código para mejorar precisión y seguridad.&lt;/p&gt;
&lt;h3&gt;Usa IA como colaborador, no reemplazo&lt;/h3&gt;
&lt;p&gt;La IA &lt;strong&gt;acelera tareas repetitivas y tediosas&lt;/strong&gt;, pero &lt;strong&gt;no sustituye tu juicio profesional&lt;/strong&gt;; úsala para potenciarte, no para delegar todo.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Como apunte final, la IA ha dejado de ser &lt;em&gt;una herramienta extra&lt;/em&gt; y se ha convertido en &lt;strong&gt;una parte central del desarrollo&lt;/strong&gt;. Está redefiniendo la productividad, la forma de escribir código y el rol del desarrollador, y aunque &lt;strong&gt;la confianza en su output todavía está en debate&lt;/strong&gt;, su impacto es innegable.&lt;/p&gt;
</content:encoded><category>Herramientas</category><category>Productividad</category><category>Desarrollo web</category><category>IA</category><author>Hugo Cayón Laso</author></item><item><title>Las principales tendencias tecnológicas que están marcando 2026 en desarrollo web</title><link>http://localhost:4321/blog/tendencias-tecnologicas-2026/</link><guid isPermaLink="true">http://localhost:4321/blog/tendencias-tecnologicas-2026/</guid><description>Un análisis de las tendencias tecnológicas actuales que están transformando el desarrollo web en 2026 y qué deberías dominar como desarrollador.</description><pubDate>Fri, 23 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Las principales tendencias tecnológicas que están marcando 2026 en desarrollo web&lt;/h2&gt;
&lt;p&gt;El desarrollo web sigue evolucionando a un ritmo acelerado, y &lt;strong&gt;2026 viene cargado de tendencias que están redefiniendo cómo trabajamos y construimos productos digitales&lt;/strong&gt;. Desde la integración profunda de IA hasta nuevas formas de desplegar aplicaciones, entender estas tendencias te puede dar una ventaja competitiva como desarrollador.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;1. IA integrada en el flujo de desarrollo&lt;/h2&gt;
&lt;p&gt;Este año, la &lt;strong&gt;inteligencia artificial deja de ser una herramienta de ayuda y se convierte en parte integral del proceso de desarrollo&lt;/strong&gt;. Las tendencias recientes apuntan a que:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AI-driven coding ya no es futurista&lt;/strong&gt;: herramientas como Copilot, Gemini y asistentes de IA generan código, ayudan con pruebas y automatizan tareas repetitivas.&lt;/li&gt;
&lt;li&gt;Se deja de ver la IA como un &amp;quot;extra&amp;quot; y se adopta como una parte esencial del stack de desarrollo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Esto implica que &lt;strong&gt;saber colaborar con IA, entender sus limitaciones y generar flujos de trabajo responsables&lt;/strong&gt; es cada vez más importante.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;2. Innovación tecnológica acelerada&lt;/h2&gt;
&lt;p&gt;Expertos de la industria coinciden en que &lt;strong&gt;2026 será un año de innovación intensa&lt;/strong&gt;, donde las tecnologías se adoptan y evolucionan más rápido que nunca. Esto no solo afecta frameworks o herramientas, sino &lt;strong&gt;cómo pensamos la arquitectura del software, la seguridad y la escalabilidad de nuestros proyectos web&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;3. Edge computing y arquitecturas distribuidas&lt;/h2&gt;
&lt;p&gt;Aunque no es una &amp;quot;noticia de última hora&amp;quot;, las &lt;strong&gt;arquitecturas edge y serverless&lt;/strong&gt; siguen consolidándose como tendencias centrales en 2026. El concepto de mover lógica cerca del usuario por medio de servicios como Cloudflare Workers o AWS Lambda@Edge &lt;strong&gt;reduce latencias y mejora rendimiento a nivel global&lt;/strong&gt;, algo crítico en aplicaciones web modernas.&lt;/p&gt;
&lt;p&gt;Este tipo de arquitectura está transformando la forma en que pensamos el &lt;strong&gt;renderizado de frontend, APIs y despliegues&lt;/strong&gt; (especialmente para aplicaciones con experiencia en tiempo real).&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;4. TypeScript y desarrollo tipado como estándar&lt;/h2&gt;
&lt;p&gt;La práctica de usar tipado estático con TypeScript no es solo una moda, sino una &lt;strong&gt;verdad consolidada&lt;/strong&gt;. Al añadir seguridad de tipos al código JavaScript tradicional, &lt;strong&gt;los equipos reducen bugs, mejoran mantenibilidad y permiten flujos más predecibles en proyectos grandes&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Esto ha resultado en que muchos frameworks y herramientas modernas lo usen como opción por defecto, y que sea una competencia esperada en roles profesionales.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;5. PWAs, headless CMS y API‑driven&lt;/h2&gt;
&lt;p&gt;Las &lt;strong&gt;Progressive Web Apps (PWAs)&lt;/strong&gt; siguen ganando terreno como una forma eficiente de ofrecer experiencias nativas sin todas las limitaciones de las tiendas de apps. Combinadas con &lt;strong&gt;Headless CMS y arquitecturas API‑driven&lt;/strong&gt;, estas tendencias permiten:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Entregas de contenido escalables y multiplataforma&lt;/li&gt;
&lt;li&gt;Integración sencilla con SPAs o sitios estáticos&lt;/li&gt;
&lt;li&gt;Mejor experiencia offline y performance constante&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;6. No‑code y low‑code democratizando el desarrollo&lt;/h2&gt;
&lt;p&gt;Aunque actualmente no reemplazan al desarrollo tradicional, las herramientas &lt;strong&gt;No‑code/Low‑code&lt;/strong&gt; se están volviendo parte del stack &lt;strong&gt;para prototipado rápido, MVPs y soluciones internas&lt;/strong&gt;. Estas herramientas están facilitando la creación de experiencias complejas a equipos más allá de los devs puros, lo cual tiene impacto en:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Entrega de proyectos&lt;/li&gt;
&lt;li&gt;Colaboración entre equipos&lt;/li&gt;
&lt;li&gt;Integración de soluciones sin código personalizado&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2&gt;7. El mercado de desarrolladores y cómo adaptarse&lt;/h2&gt;
&lt;p&gt;Más allá de las tendencias tecnológicas, la &lt;strong&gt;percepción del mercado de desarrolladores también está cambiando&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AI no reemplaza devs, pero redefine habilidades prioritarias&lt;/strong&gt;, saber usar IA y adaptarse a flujos simulados por herramientas inteligentes es crucial.&lt;/li&gt;
&lt;li&gt;El valor real ya no es solo conocer un lenguaje/framework, sino &lt;strong&gt;resolver problemas, entender arquitectura y construir productos confiables&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La conversación en comunidades técnicas indica que aunque hay ruido, la &lt;strong&gt;demanda de devs con capacidades amplias y fundamentos sólidos sigue fuerte&lt;/strong&gt; — especialmente para quien puede diseñar y construir soluciones completas.&lt;/p&gt;
&lt;p&gt;!Nos vemos en el próximo artículo!&lt;/p&gt;
</content:encoded><category>Edge computing</category><category>Productividad</category><category>Inteligencia artificial</category><category>IA</category><category>Desarrollo web</category><author>Hugo Cayón Laso</author></item><item><title>Cloudflare adquiere al equipo de Astro: qué significa para el desarrollo web</title><link>http://localhost:4321/blog/cloudflare-adquiere-equipo-astro/</link><guid isPermaLink="true">http://localhost:4321/blog/cloudflare-adquiere-equipo-astro/</guid><description>Analizo la reciente compra del equipo de Astro por Cloudflare y por qué puede ser un punto de inflexión en frameworks web y edge computing en 2026.</description><pubDate>Thu, 22 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Cloudflare adquiere al equipo de Astro: ¿un antes y un después para el desarrollo web?&lt;/h2&gt;
&lt;p&gt;En una &lt;strong&gt;movida estratégica que ha sorprendido a muchos en el ecosistema web&lt;/strong&gt;, Cloudflare —la empresa líder en servicios de CDN, seguridad y edge computing— ha anunciado la &lt;strong&gt;adquisición del equipo detrás de Astro&lt;/strong&gt;, uno de los frameworks más populares para construir sitios web rápidos y centrados en contenido.&lt;/p&gt;
&lt;p&gt;Astro ha ganado tracción rápidamente entre desarrolladores por su &lt;strong&gt;arquitectura &amp;quot;content-first&amp;quot;&lt;/strong&gt; y por permitir &lt;strong&gt;enviar cero JavaScript al cliente por defecto&lt;/strong&gt;, lo que mejora radicalmente el rendimiento de proyectos estáticos o JAMstack.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;¿Por qué es importante esta adquisición?&lt;/h2&gt;
&lt;p&gt;La compra del equipo de Astro por parte de Cloudflare &lt;strong&gt;no es solo un movimiento corporativo más&lt;/strong&gt;; implica &lt;strong&gt;señales importantes sobre hacia dónde va la web en 2026&lt;/strong&gt;:&lt;/p&gt;
&lt;h3&gt;Refuerzo del edge computing&lt;/h3&gt;
&lt;p&gt;Cloudflare ya ofrece funciones de computación en el edge que permiten ejecutar lógica en servidores distribuidos globalmente, cerca del usuario y con Astro en su órbita, es probable que &lt;strong&gt;la integración entre frameworks y edge workflows sea cada vez más profunda&lt;/strong&gt;. Esto puede cambiar cómo pensemos en la renderización y despliegue de aplicaciones web.&lt;/p&gt;
&lt;h3&gt;Prioridad al rendimiento y experiencias optimizadas&lt;/h3&gt;
&lt;p&gt;Astro nació con un objetivo: &lt;strong&gt;mejorar el rendimiento real de los sitios web&lt;/strong&gt; enviando lo mínimo posible al navegador. Esta filosofía encaja perfectamente con lo que hoy exigen Core Web Vitals y las mejores prácticas de rendimiento web en 2026.&lt;/p&gt;
&lt;h3&gt;Competencia con stacks &amp;quot;tradicionales&amp;quot;&lt;/h3&gt;
&lt;p&gt;Si frameworks como React, Vue o Angular han dominado el espacio de aplicaciones interactivas, Astro representa una visión alternativa centrada en &lt;strong&gt;contenido y performance&lt;/strong&gt;. La entrada de un gigante como Cloudflare podría impulsar esta tendencia hacia &lt;strong&gt;mayores niveles de adopción&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Qué puedes esperar como desarrollador&lt;/h2&gt;
&lt;p&gt;Esta adquisición abre varias posibilidades para tu workflow:&lt;/p&gt;
&lt;h3&gt;Integraciones nativas con productos de Cloudflare&lt;/h3&gt;
&lt;p&gt;Es probable que en el futuro veamos &lt;strong&gt;mejor integración de Astro con servicios como Workers, Pages o R2&lt;/strong&gt;, lo que facilitaría crear sitios ultra‑rápidos, escalables y con funciones avanzadas sin complicaciones.&lt;/p&gt;
&lt;h3&gt;Mejor soporte para Páginas Estáticas y Jamstack&lt;/h3&gt;
&lt;p&gt;Astro ya hacía esto bien; con Cloudflare detrás, podríamos ver &lt;strong&gt;mejoras en build pipelines, plugins y despliegue continuo&lt;/strong&gt; integrado con la red global del proveedor.&lt;/p&gt;
&lt;h3&gt;Comunidad e innovación&lt;/h3&gt;
&lt;p&gt;Astro tiene una comunidad vibrante. Con recursos adicionales detrás, es posible que se acelere la &lt;strong&gt;creación de nuevas funciones, doc mejorada y herramientas complementarias&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;Conclusión: ¿deberías usar Astro en tus próximos proyectos?&lt;/h2&gt;
&lt;p&gt;Si buscas:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Rendimiento por defecto sin sacrificar experiencia de desarrollo.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sitios content first o estáticos ultra rápidos&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integración con edge computing moderno.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Actualmente Astro (ahora con respaldo de Cloudflare) es definitivamente una opción que &lt;strong&gt;vale la pena explorar&lt;/strong&gt; en 2026.&lt;/p&gt;
&lt;p&gt;Esta compra no solo valida la &lt;strong&gt;visión de Astro como framework moderno&lt;/strong&gt;, sino que también indica un &lt;strong&gt;movimiento importante hacia arquitecturas más rápidas, distribuidas y optimizadas para experiencias reales del usuario&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Hasta la próxima.&lt;/p&gt;
</content:encoded><category>Desarrollo web</category><category>Frameworks</category><category>Cloudflare</category><category>Astro</category><author>Hugo Cayón Laso</author></item><item><title>Ahora tenemos RSS: qué es, cómo funciona y por qué te interesa</title><link>http://localhost:4321/blog/ahora-tenemos-rss/</link><guid isPermaLink="true">http://localhost:4321/blog/ahora-tenemos-rss/</guid><description>Te explico qué es un RSS feed, cómo funciona y por qué deberías suscribirte al feed de este blog para no perderte nada.</description><pubDate>Fri, 16 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Este blog ahora tiene RSS&lt;/h2&gt;
&lt;p&gt;Quiero contarte una mejora importante: este blog ya dispone de un &lt;a href=&quot;/rss.xml&quot;&gt;RSS feed&lt;/a&gt;. En este artículo te explico en detalle qué significa esto, cómo funciona y por qué puede ser una herramienta útil para mantenerte al día con el contenido sin necesidad de visitar el sitio de forma manual.&lt;/p&gt;
&lt;p&gt;RSS es un formato estandarizado que permite &lt;strong&gt;distribuir actualizaciones de contenido de forma automática&lt;/strong&gt;, de modo que aplicaciones o lectores especializados pueden detectar y organizar esas actualizaciones sin que tú tengas que visitar manualmente cada sitio que sigues.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;¿Qué es un RSS?&lt;/h2&gt;
&lt;p&gt;RSS son las siglas de &lt;em&gt;Really Simple Syndication&lt;/em&gt;, que en español se traduce como &amp;quot;sindicación realmente simple&amp;quot;. Se trata de un &lt;strong&gt;formato estándar basado en XML que se utiliza para distribuir contenido actualizado de forma automática&lt;/strong&gt; desde sitios web que publican con frecuencia, como blogs, medios de noticias o canales de podcast.&lt;/p&gt;
&lt;p&gt;Un archivo RSS contiene, estructurado en formato XML, una lista de publicaciones recientes de un sitio web junto con metadatos importantes como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;El título de la publicación.&lt;/li&gt;
&lt;li&gt;La descripción o un resumen.&lt;/li&gt;
&lt;li&gt;Autor o fuente del contenido.&lt;/li&gt;
&lt;li&gt;La fecha en la que se publicó.&lt;/li&gt;
&lt;li&gt;La dirección web (URL) para acceder al contenido completo.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Este formato permite que &lt;strong&gt;cualquier lector de RSS pueda interpretar y mostrar estas actualizaciones de manera sistemática&lt;/strong&gt;, independientemente de la tecnología usada para generar el contenido original.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;¿Cómo funciona un RSS?&lt;/h2&gt;
&lt;p&gt;El funcionamiento de un RSS se basa en la periodicidad y la estandarización:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Cada vez que publicamos un nuevo artículo en este blog, nuestro sistema genera entradas en el feed RSS correspondientes a esa publicación.&lt;/li&gt;
&lt;li&gt;Un lector de RSS es una herramienta que &lt;strong&gt;consulta periódicamente este archivo&lt;/strong&gt;, descargándolo y analizando su contenido para detectar cambios o nuevas entradas.&lt;/li&gt;
&lt;li&gt;Siempre que hay contenido nuevo, el lector te lo muestra organizado cronológicamente, sin que tengas que visitar el blog manualmente para comprobar si hay novedades.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Este proceso se realiza de forma automatizada y continua, de modo que tu lector siempre puede mostrarte las actualizaciones más recientes de todas las fuentes a las que estés suscrito.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;¿Qué necesito para usar RSS?&lt;/h2&gt;
&lt;p&gt;Para consumir contenido a través de un RSS necesitas un &lt;strong&gt;lector de feeds&lt;/strong&gt;. Un lector de RSS es un programa o servicio que descarga, organiza y muestra los contenidos de uno o varios feeds a los que te hayas suscrito. Existen distintos tipos de lectores:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Lectores basados en la web, que funcionan desde un navegador o con aplicaciones móviles.&lt;/li&gt;
&lt;li&gt;Aplicaciones de escritorio, que funcionan localmente en tu equipo.&lt;/li&gt;
&lt;li&gt;Extensiones de navegador, que detectan automáticamente los feeds disponibles en los sitios que visitas.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Algunos ejemplos populares de lectores de RSS incluyen Feedly, Inoreader, y Reeder.&lt;/p&gt;
&lt;p&gt;El uso de un lector es muy sencillo: copias la URL del feed RSS del blog, la añades en tu lector y este empezará a revisar el feed de forma periódica para mostrarte las entradas nuevas.&lt;/p&gt;
&lt;hr&gt;
&lt;h2&gt;¿Por qué seguir un RSS en 2026?&lt;/h2&gt;
&lt;p&gt;Aunque RSS es una tecnología con décadas de existencia, mantiene una serie de ventajas que la hacen relevante en contextos donde se valora la &lt;strong&gt;organización, la independencia y el control sobre el contenido&lt;/strong&gt; que se consume.&lt;/p&gt;
&lt;h3&gt;Control directo de lo que lees&lt;/h3&gt;
&lt;p&gt;Con RSS tú decides exactamente &lt;strong&gt;qué fuentes seguir&lt;/strong&gt;, sin depender de algoritmos que filtren o prioricen contenido en función de criterios distintos a la simple cronología o relevancia directa. Esto evita que contenidos importantes queden ocultos por decisiones automatizadas de plataformas.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Privacidad&lt;/h3&gt;
&lt;p&gt;Los lectores de RSS no requieren que proporciones datos personales ni que te registres en servicios de terceros para consumir contenidos. Simplemente consultas el feed y recibes las publicaciones, sin seguimiento de comportamiento o registros de actividad.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Ahorro de tiempo&lt;/h3&gt;
&lt;p&gt;Con un lector de RSS puedes &lt;strong&gt;agrupar múltiples fuentes de información en un solo lugar&lt;/strong&gt;. En vez de revisar manualmente si hay contenido nuevo en cada sitio que sigues, tu lector te muestra automáticamente las actualizaciones de todos ellos en una sola interfaz, lo que supone una mejora considerable en eficiencia a la hora de consumir contenidos.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Organización limpia&lt;/h3&gt;
&lt;p&gt;Los lectores de RSS presentan las actualizaciones de forma ordenada y libre de distracciones, lo que facilita la lectura y revisión de novedades sin banners ni elementos ajenos al contenido.&lt;/p&gt;
&lt;hr&gt;
&lt;h3&gt;Uso extendido en múltiples contextos&lt;/h3&gt;
&lt;p&gt;Además de blogs, los RSS feeds se utilizan para distribuir actualizaciones de noticias, contenidos de podcasting y otros tipos de información que se actualiza con frecuencia. La estandarización del formato XML permite que estos contenidos sean consumidos por una amplia variedad de herramientas de lectura automática.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Un RSS feed es un &lt;strong&gt;formato estándar para distribuir contenido actualizado de forma automática&lt;/strong&gt;. Utilizar un lector de RSS te permite:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Agrupar en un solo lugar todas tus fuentes de interés.&lt;/li&gt;
&lt;li&gt;Evitar algoritmos de plataformas que deciden por ti qué contenidos mostrar.&lt;/li&gt;
&lt;li&gt;Mantener el control total sobre tu experiencia de lectura.&lt;/li&gt;
&lt;li&gt;Ahorrar tiempo al concentrar las publicaciones nuevas en una sola vista.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Este blog ahora cuenta con un RSS feed. Suscribirte a él te permitirá estar siempre informado de las publicaciones nuevas sin necesidad de visitar el sitio manualmente.&lt;/p&gt;
&lt;p&gt;¡Gracias por leer y nos vemos en el próximo artículo!&lt;/p&gt;
</content:encoded><category>Tecnología</category><category>XML</category><category>RSS</category><author>Hugo Cayón Laso</author></item><item><title>Composer en PHP: guía completa para empezar</title><link>http://localhost:4321/blog/composer-en-php-guia-completa/</link><guid isPermaLink="true">http://localhost:4321/blog/composer-en-php-guia-completa/</guid><description>Aprende qué es Composer, cómo instalarlo y cómo gestionar dependencias en proyectos PHP de forma profesional.</description><pubDate>Sun, 11 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;¿Qué es Composer y para qué sirve?&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Composer&lt;/strong&gt; es el &lt;strong&gt;gestor de dependencias de PHP&lt;/strong&gt;.
Permite instalar, actualizar y gestionar librerías externas de forma sencilla y controlada, similar a &lt;code&gt;npm&lt;/code&gt; en JavaScript o &lt;code&gt;pip&lt;/code&gt; en Python.&lt;/p&gt;
&lt;p&gt;Composer se basa en un archivo llamado &lt;strong&gt;&lt;code&gt;composer.json&lt;/code&gt;&lt;/strong&gt;, donde se definen las dependencias y la configuración del proyecto.&lt;/p&gt;
&lt;p&gt;Esto facilita la integración de librerías de terceros, asegurando que las versiones sean compatibles y que el proyecto se mantenga organizado.&lt;/p&gt;
&lt;h2&gt;Instalación de Composer&lt;/h2&gt;
&lt;h3&gt;macOS y Linux&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;php -r &amp;quot;copy(&amp;#39;https://getcomposer.org/installer&amp;#39;, &amp;#39;composer-setup.php&amp;#39;);&amp;quot;
php composer-setup.php
php -r &amp;quot;unlink(&amp;#39;composer-setup.php&amp;#39;);&amp;quot;
mv composer.phar /usr/local/bin/composer
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Windows&lt;/h3&gt;
&lt;p&gt;Descarga el instalador desde &lt;a href=&quot;https://getcomposer.org&quot;&gt;getcomposer.org&lt;/a&gt; y sigue las instrucciones del asistente.&lt;/p&gt;
&lt;h2&gt;Verificar la instalación&lt;/h2&gt;
&lt;p&gt;Para verificar que Composer se ha instalado correctamente, ejecuta:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;composer --version
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Deberías ver la versión de Composer instalada.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;Composer version 2.x.x 2024-01-01 12:00:00
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Estructura básica de un proyecto con Composer&lt;/h2&gt;
&lt;p&gt;Un proyecto típico con Composer tiene la siguiente estructura:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;├── composer.json
├── composer.lock
├── vendor/
    └── autoload.php
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;composer.json&lt;/code&gt;: Define las dependencias y la configuración del proyecto.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer.lock&lt;/code&gt;: Registra las versiones exactas de las dependencias instaladas.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;vendor/&lt;/code&gt;: Carpeta donde se instalan las dependencias.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;autoload.php&lt;/code&gt;: Archivo generado automáticamente para cargar las clases de las dependencias.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Crear un archivo composer.json&lt;/h2&gt;
&lt;p&gt;Puedes crear un archivo &lt;code&gt;composer.json&lt;/code&gt; manualmente o utilizando el comando:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;composer init
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Este comando te guiará a través de una serie de preguntas para configurar tu proyecto.&lt;/p&gt;
&lt;p&gt;Un ejemplo básico de &lt;code&gt;composer.json&lt;/code&gt; podría ser:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
    &amp;quot;name&amp;quot;: &amp;quot;mi-proyecto/ejemplo&amp;quot;,
    &amp;quot;description&amp;quot;: &amp;quot;Un proyecto de ejemplo usando Composer&amp;quot;,
    &amp;quot;require&amp;quot;: {
        &amp;quot;monolog/monolog&amp;quot;: &amp;quot;^2.0&amp;quot;,
        &amp;quot;guzzlehttp/guzzle&amp;quot;: &amp;quot;^7.0&amp;quot;,
    },
    &amp;quot;autoload&amp;quot;: {
        &amp;quot;psr-4&amp;quot;: {
            &amp;quot;App\\&amp;quot;: &amp;quot;src/&amp;quot;
        }
    },
    &amp;quot;minimum-stability&amp;quot;: &amp;quot;stable&amp;quot;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Instalar dependencias&lt;/h2&gt;
&lt;p&gt;Para instalar las dependencias definidas en &lt;code&gt;composer.json&lt;/code&gt;, ejecuta:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;composer install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esto creará la carpeta &lt;code&gt;vendor/&lt;/code&gt; y descargará las librerías necesarias.&lt;/p&gt;
&lt;h2&gt;Instalar una nueva dependencia&lt;/h2&gt;
&lt;p&gt;Para agregar una nueva dependencia a tu proyecto, usa el comando:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;composer require nombre/dependencia
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Actualizar dependencias&lt;/h2&gt;
&lt;p&gt;Para actualizar las dependencias a las últimas versiones permitidas por las restricciones en &lt;code&gt;composer.json&lt;/code&gt;, usa:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;composer update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Este comando actualizará las librerías y modificará el archivo &lt;code&gt;composer.lock&lt;/code&gt; en consecuencia. Hay que tener cuidado al usarlo en proyectos en producción, ya que puede introducir cambios inesperados.&lt;/p&gt;
&lt;h2&gt;Autoloading&lt;/h2&gt;
&lt;p&gt;Una de las características más útiles de Composer es el autoloading automático. Composer genera automáticamente un archivo que puedes incluir en tu proyecto para cargar las clases de las dependencias instaladas.&lt;/p&gt;
&lt;p&gt;Para usar el autoloading, simplemente incluye el siguiente código al inicio de tu script PHP:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;require &amp;#39;vendor/autoload.php&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Autoloading de las clases propias (PSR-4)&lt;/h2&gt;
&lt;p&gt;Si has configurado el autoloading en &lt;code&gt;composer.json&lt;/code&gt;, también se cargarán tus propias clases automáticamente, puedes usar el siguiente ejemplo:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;&amp;quot;autoload&amp;quot;: {
    &amp;quot;psr-4&amp;quot;: {
        &amp;quot;App\\&amp;quot;: &amp;quot;src/&amp;quot;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esto te permite utilizar las clases de las librerías instaladas sin necesidad de cargarlas manualmente.&lt;/p&gt;
&lt;p&gt;Después de modificar el &lt;code&gt;composer.json&lt;/code&gt; para agregar nuevas rutas de autoloading, asegúrate de ejecutar:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;composer dump-autoload
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Estructura de carpetas recomendada:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;├── src/
│   └── MiClase.php
├── composer.json
├── composer.lock
├── vendor/
    └── autoload.php
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ejemplo de uso:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;// src/MiClase.php
&amp;lt;?php
namespace App;

class MiClase {
    public function saludar() {
        return &amp;quot;¡Hola desde MiClase!&amp;quot;;
    }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;// index.php
&amp;lt;?php
require &amp;#39;vendor/autoload.php&amp;#39;;

use App\MiClase;

$miClase = new MiClase();
echo $miClase-&amp;gt;saludar(); // Salida: ¡Hola desde MiClase!
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Comandos útiles de Composer&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;composer install&lt;/code&gt;: Instala las dependencias del proyecto.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer update&lt;/code&gt;: Actualiza las dependencias a las últimas versiones permitidas.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer require nombre/dependencia&lt;/code&gt;: Agrega una nueva dependencia al proyecto.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer remove nombre/dependencia&lt;/code&gt;: Elimina una dependencia del proyecto.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer dump-autoload&lt;/code&gt;: Regenera el archivo de autoloading.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer show&lt;/code&gt;: Muestra las dependencias instaladas y sus versiones.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer outdated&lt;/code&gt;: Muestra las dependencias que tienen actualizaciones disponibles.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer validate&lt;/code&gt;: Valida el archivo &lt;code&gt;composer.json&lt;/code&gt; para asegurarse de que esté correctamente formateado.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer why nombre/dependencia&lt;/code&gt;: Muestra por qué una dependencia está instalada (qué otra dependencia la requiere).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer global require nombre/dependencia&lt;/code&gt;: Instala una dependencia de forma global en el sistema.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer global update&lt;/code&gt;: Actualiza las dependencias instaladas globalmente.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer licenses&lt;/code&gt;: Muestra las licencias de las dependencias instaladas.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer config&lt;/code&gt;: Permite ver y modificar la configuración de Composer.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer clear-cache&lt;/code&gt;: Limpia la caché de Composer para liberar espacio o solucionar problemas de instalación.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer clear-cache --all&lt;/code&gt;: Limpia toda la caché de Composer, incluyendo cachés de paquetes y metadatos.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer run-script nombre-script&lt;/code&gt;: Ejecuta un script definido en la sección &lt;code&gt;scripts&lt;/code&gt; del archivo &lt;code&gt;composer.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer help [comando]&lt;/code&gt;: Muestra la ayuda detallada para un comando específico de Composer.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer diagnose&lt;/code&gt;: Realiza un diagnóstico del entorno de Composer para identificar posibles problemas de configuración o instalación.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer init&lt;/code&gt;: Inicia un asistente para crear un nuevo archivo &lt;code&gt;composer.json&lt;/code&gt; desde cero.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer lock&lt;/code&gt;: Bloquea las versiones de las dependencias instaladas para garantizar la consistencia en diferentes entornos.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer require --dev nombre/dependencia&lt;/code&gt;: Agrega una dependencia solo para el entorno de desarrollo.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer remove --dev nombre/dependencia&lt;/code&gt;: Elimina una dependencia del entorno de desarrollo.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer update --lock&lt;/code&gt;: Actualiza solo el archivo &lt;code&gt;composer.lock&lt;/code&gt; sin modificar las dependencias instaladas.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer global show&lt;/code&gt;: Muestra las dependencias instaladas globalmente en el sistema.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer global outdated&lt;/code&gt;: Muestra las dependencias globales que tienen actualizaciones disponibles.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer global remove nombre/dependencia&lt;/code&gt;: Elimina una dependencia instalada globalmente.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;composer global dump-autoload&lt;/code&gt;: Regenera el archivo de autoloading para las dependencias instaladas globalmente.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Apuntes finales&lt;/h2&gt;
&lt;p&gt;Para acabar, Composer es una herramienta esencial para cualquier desarrollador PHP que busque gestionar dependencias de manera eficiente y profesional. Su uso adecuado mejora la organización del proyecto, facilita la integración de librerías externas y asegura la compatibilidad entre diferentes versiones de paquetes. Adoptar Composer en tus proyectos PHP es un paso fundamental hacia un desarrollo más estructurado y mantenible. ¡No dudes en explorar más sobre sus funcionalidades y sacarle el máximo provecho!&lt;/p&gt;
&lt;p&gt;Hasta la próxima.&lt;/p&gt;
</content:encoded><category>Backend</category><category>Composer</category><category>PHP</category><author>Hugo Cayón Laso</author></item><item><title>Git desde cero: guía básica de control de versiones para desarrolladores</title><link>http://localhost:4321/blog/git-desde-cero-guia-basica/</link><guid isPermaLink="true">http://localhost:4321/blog/git-desde-cero-guia-basica/</guid><description>Aprende Git desde cero: qué es, para qué sirve y cómo usar los comandos básicos para gestionar versiones de tu código.</description><pubDate>Tue, 16 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;¿Qué es Git y para qué sirve?&lt;/h2&gt;
&lt;p&gt;Git es un &lt;strong&gt;sistema de control de versiones distribuido&lt;/strong&gt; que permite registrar cambios en el código, colaborar con otros desarrolladores y volver atrás cuando algo falla.&lt;/p&gt;
&lt;p&gt;Git sirve para resolver problemas muy comunes en el desarrollo de software:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Guardar el historial del proyecto&lt;/strong&gt;
Permite volver a versiones anteriores si algo se rompe o deja de funcionar.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Trabajar sin miedo a equivocarte&lt;/strong&gt;
Puedes experimentar con el código sabiendo que siempre podrás deshacer los cambios.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Colaborar con otros desarrolladores&lt;/strong&gt;
Varias personas pueden trabajar en el mismo proyecto sin sobrescribir el trabajo de los demás.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Controlar quién hizo cada cambio&lt;/strong&gt;
Cada modificación queda asociada a una persona y a un momento concreto.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Organizar el desarrollo con ramas&lt;/strong&gt;
Facilita trabajar en nuevas funcionalidades, correcciones o pruebas sin afectar al código principal.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integrarse con plataformas como GitHub o GitLab&lt;/strong&gt;
Permite compartir el código, revisar cambios y automatizar despliegues.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;En resumen, Git es &lt;strong&gt;imprescindible en cualquier proyecto profesional&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Instalación de Git&lt;/h2&gt;
&lt;p&gt;Para instalar Git, sigue estos pasos según tu sistema operativo:&lt;/p&gt;
&lt;h3&gt;Windows:&lt;/h3&gt;
&lt;p&gt;Descarga el instalador desde &lt;a href=&quot;https://git-scm.com/download/win&quot;&gt;git-scm.com&lt;/a&gt; y sigue las instrucciones.&lt;/p&gt;
&lt;h3&gt;macOS:&lt;/h3&gt;
&lt;p&gt;Usa Homebrew: &lt;code&gt;brew install git&lt;/code&gt; o descarga el instalador desde &lt;a href=&quot;https://git-scm.com/download/mac&quot;&gt;git-scm.com&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Linux:&lt;/h3&gt;
&lt;p&gt;Usa el gestor de paquetes de tu distribución, por ejemplo en Ubuntu: &lt;code&gt;sudo apt-get install git&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;Configuración inicial&lt;/h2&gt;
&lt;p&gt;Git necesita saber quién eres para poder asociar los cambios a una persona concreta. Esta información se guarda en cada commit.&lt;/p&gt;
&lt;p&gt;Configura tu nombre y correo electrónico:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git config --global user.name &amp;quot;Tu Nombre&amp;quot;
git config --global user.email &amp;quot;tu@email.com&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esta configuración se hace una sola vez por equipo.&lt;/p&gt;
&lt;p&gt;Para verificar la configuración, usa:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git config --list
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Creación de un repositorio Git&lt;/h2&gt;
&lt;p&gt;Para iniciar un nuevo repositorio Git en tu proyecto, navega a la carpeta del proyecto y ejecuta:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git init
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Esto crea una carpeta oculta &lt;code&gt;.git&lt;/code&gt; donde Git almacenará toda la información del repositorio.&lt;/p&gt;
&lt;p&gt;Clonar un repositorio existente:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone url-del-repositorio
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Estados de Git&lt;/h2&gt;
&lt;p&gt;Git tiene cuatro estados principales para los archivos:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Untracked&lt;/strong&gt;: Archivos nuevos no rastreados por Git.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Modified&lt;/strong&gt;: Archivos que han sido modificados pero no preparados para commit.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Staged&lt;/strong&gt;: Archivos preparados para el próximo commit.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Committed&lt;/strong&gt;: Cambios guardados en el historial de Git.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Añadir archivos al área de preparación (staging area)&lt;/h2&gt;
&lt;p&gt;Para preparar archivos para el próximo commit, usa:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git add nombre-del-archivo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Para añadir todos los archivos modificados:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git add .
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Hacer un commit&lt;/h2&gt;
&lt;p&gt;Para guardar los cambios preparados en el historial de Git, usa:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git commit -m &amp;quot;Mensaje descriptivo del commit&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;El mensaje debe ser claro y describir los cambios realizados.&lt;/p&gt;
&lt;h2&gt;Ver el estado del repositorio&lt;/h2&gt;
&lt;p&gt;Para ver el estado actual del repositorio y los archivos, usa:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;git status
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Historial de commits:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git log
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ver un historial más compacto:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git log --oneline
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Trabajar con ramas&lt;/h2&gt;
&lt;p&gt;Las ramas permiten desarrollar nuevas funcionalidades o corregir errores sin afectar al código principal.&lt;/p&gt;
&lt;p&gt;Crear una nueva rama:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git branch nombre-de-la-rama
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cambiar a una rama existente:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git checkout nombre-de-la-rama
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Crear y cambiar a una nueva rama en un solo comando:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git checkout -b nombre-de-la-rama
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Listar todas las ramas:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git branch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Fusionar una rama en la rama actual:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git merge nombre-de-la-rama
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Eliminar una rama:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git branch -d nombre-de-la-rama
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Trabajar con repositorios remotos&lt;/h2&gt;
&lt;p&gt;Para conectar tu repositorio local con un repositorio remoto (por ejemplo, en GitHub), usa:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git remote add origin url-del-repositorio
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enviar cambios al repositorio remoto:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git push origin nombre-de-la-rama
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Obtener cambios del repositorio remoto:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git pull origin nombre-de-la-rama
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Uso de .gitignore&lt;/h2&gt;
&lt;p&gt;El archivo &lt;code&gt;.gitignore&lt;/code&gt; permite evitar subir archivos innecesarios como:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;node_modules&lt;/li&gt;
&lt;li&gt;archivos de entorno (.env)&lt;/li&gt;
&lt;li&gt;builds&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ejemplo:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;# build output
dist/
# generated types
.astro/

# dependencies
node_modules/

# logs
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*


# environment variables
.env
.env.production
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Buenas prácticas con Git&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Realiza commits frecuentes con mensajes claros, que describan los cambios realizados.&lt;/li&gt;
&lt;li&gt;Usa ramas para desarrollar nuevas funcionalidades.&lt;/li&gt;
&lt;li&gt;Revisa los cambios antes de hacer un commit.&lt;/li&gt;
&lt;li&gt;Mantén tu repositorio remoto actualizado.&lt;/li&gt;
&lt;li&gt;Evita subir archivos innecesarios (usa un archivo &lt;code&gt;.gitignore&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Colabora y revisa el código de otros desarrolladores.&lt;/li&gt;
&lt;li&gt;Aprende a resolver conflictos de fusión (merge conflicts).&lt;/li&gt;
&lt;/ul&gt;
</content:encoded><category>Mantenimiento</category><category>DevOps</category><category>Buenas prácticas</category><category>Versionado</category><category>Git</category><author>Hugo Cayón Laso</author></item><item><title>Mi configuración para desarrollar aplicaciones</title><link>http://localhost:4321/blog/mi-configuracion-para-desarrollar/</link><guid isPermaLink="true">http://localhost:4321/blog/mi-configuracion-para-desarrollar/</guid><description>Así es el entorno que utilizo para desarrollar aplicaciones web: hardware, software, extensiones, herramientas y ajustes de productividad.</description><pubDate>Sun, 07 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;A lo largo de los últimos años he ido refinando mi manera de trabajar hasta llegar a un entorno de desarrollo &lt;strong&gt;rápido, estable y muy enfocado a la productividad&lt;/strong&gt;.
En este post quiero compartir &lt;strong&gt;todo lo que uso&lt;/strong&gt;, desde el hardware hasta las herramientas, extensiones, terminales y configuraciones que me acompañan cada día al desarrollar proyectos con &lt;strong&gt;JavaScript, React, PHP y Laravel&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Hardware que utilizo&lt;/h2&gt;
&lt;p&gt;He probado equipos muy distintos, pero hace un mes mi pareja me regaló un &lt;strong&gt;MacBook Air M4&lt;/strong&gt;, un equipo que llevaba tiempo queriendo probar. Después de varias semanas de uso intensivo, se ha convertido en mi herramienta principal.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;MacBook Air M4&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Mi equipo principal para la mayoría del desarrollo web.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Chip:&lt;/strong&gt; Apple Silicon M4 (10 núcleos CPU, 8 núcleos GPU, 16GB RAM y 256GB SSD)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ventajas:&lt;/strong&gt; rendimiento increíble, silencioso, ligero y autonomía enorme.&lt;/li&gt;
&lt;li&gt;Ideal para: Cualquier desarrollador web que busque un equipo potente, portátil y con buena autonomía.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;¿Por qué lo uso para desarrollo?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;El ecosistema UNIX muy sólido y estable, macOS facilita la instalación y gestión de herramientas de desarrollo.&lt;/li&gt;
&lt;li&gt;Gran rendimiento con aplicaciones de desarrollo y multitarea.&lt;/li&gt;
&lt;li&gt;Excelente duración de batería para largas sesiones de trabajo sin necesidad de estar conectado a la corriente.&lt;/li&gt;
&lt;li&gt;Portabilidad y ligereza, ideal para trabajar desde cualquier lugar.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A pesar de haber aprendido a usar Windows y Linux en el pasado, hoy en día macOS me ofrece un entorno más fluido.&lt;/p&gt;
&lt;h2&gt;Herramientas y software principal&lt;/h2&gt;
&lt;h3&gt;&lt;strong&gt;Visual Studio Code como editor principal&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;VS Code es mi editor de código, he probado otros como (Antigravity, TRAE, Cursor o Xcode), pero siempre vuelvo a &lt;strong&gt;VS Code&lt;/strong&gt; es con el que me siento más cómodo.&lt;/p&gt;
&lt;p&gt;Estas son las extensiones que considero imprescindibles:&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;Para JavaScript / Node / Astro / React&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Astro&lt;/strong&gt; – soporte oficial para el framework&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ESLint&lt;/strong&gt; – análisis estático del código&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Prettier&lt;/strong&gt; – formateo automático&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tailwind CSS IntelliSense&lt;/strong&gt; – autocompletado inteligente (cuando lo uso)&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;&lt;strong&gt;Para PHP y Laravel&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;PHP Debug&lt;/strong&gt; – depuración paso a paso&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PHP Intelephense&lt;/strong&gt; – análisis avanzado para PHP&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DotENV&lt;/strong&gt; – resaltado para archivos &lt;code&gt;.env&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;&lt;strong&gt;Otras extensiones útiles&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Error Lens&lt;/strong&gt; – muestra errores directamente en el editor&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Better Comments&lt;/strong&gt; – comentarios más organizados&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Image Preview&lt;/strong&gt; – vista previa de imágenes en el código&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Material Icon Theme&lt;/strong&gt; y &lt;strong&gt;Fluent Icons&lt;/strong&gt; – iconos más agradables y rápidos de identificar&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Houston&lt;/strong&gt; - tema oficial de Astro, mi tema favorito&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Trailing Spaces&lt;/strong&gt; – resalta espacios sobrantes&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;Terminal&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Utilizo la terminal integrada de macOS.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Git y GitHub&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Trabajo con &lt;strong&gt;Git&lt;/strong&gt; para control de versiones y utilizo &lt;strong&gt;GitHub&lt;/strong&gt; para alojar mis repositorios&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Bases de datos y entornos backend&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Como trabajo tanto con MySQL como con PHP + Laravel, tengo una pequeña colección de herramientas que utilizo siempre:&lt;/p&gt;
&lt;h4&gt;&lt;strong&gt;MySQL Workbench&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Utilizo MySQL Workbench para gestionar mis bases de datos MySQL de manera visual.&lt;/p&gt;
&lt;h4&gt;PHP y Laravel&lt;/h4&gt;
&lt;p&gt;Son las tecnologías backend que más utilizo. Para gestionar proyectos Laravel, uso Composer y Artisan desde la terminal.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PHP 8.4&lt;/li&gt;
&lt;li&gt;Laravel 12&lt;/li&gt;
&lt;li&gt;Composer&lt;/li&gt;
&lt;li&gt;Artisan CLI&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;strong&gt;Navegadores web&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Utilizo principalmente &lt;strong&gt;Google Chrome&lt;/strong&gt;, &lt;strong&gt;Firefox&lt;/strong&gt; y &lt;strong&gt;Safari&lt;/strong&gt; para probar y depurar aplicaciones.&lt;/p&gt;
&lt;h3&gt;&lt;strong&gt;Otras herramientas&lt;/strong&gt;&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Postman&lt;/strong&gt; para probar APIs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Homebrew&lt;/strong&gt; para gestionar paquetes y software en macOS.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ChatGPT&lt;/strong&gt; para consultar dudas y obtener ayuda rápida.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Gracias por llegar hasta aquí.
Espero que este repaso a mi entorno de desarrollo te haya servido para descubrir nuevas herramientas o simplemente para inspirarte a optimizar el tuyo.&lt;/p&gt;
</content:encoded><category>Software</category><category>Productividad</category><category>Herramientas</category><category>Desarrollo web</category><author>Hugo Cayón Laso</author></item><item><title>Cómo organizo mi aprendizaje como desarrollador web</title><link>http://localhost:4321/blog/como-organizo-mi-aprendizaje/</link><guid isPermaLink="true">http://localhost:4321/blog/como-organizo-mi-aprendizaje/</guid><description>Mi sistema personal para aprender nuevas tecnologías de forma constante, sin perder el rumbo ni la motivación.</description><pubDate>Mon, 01 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;El desarrollo web avanza tan rápido que es fácil sentirse desbordado. Cada semana aparece un nuevo framework, una librería revolucionaria o una forma más eficiente de resolver un problema ya resuelto. Durante mucho tiempo esto me generaba frustración: &lt;strong&gt;¿cómo organizo lo que aprendo sin sentir que siempre llego tarde?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Con los años desarrollé un sistema flexible centrado en tres pilares: &lt;strong&gt;claridad, constancia y práctica&lt;/strong&gt;. No es perfecto, pero me ha permitido avanzar sin ansiedad, mantener el foco y seguir disfrutando del aprendizaje.&lt;/p&gt;
&lt;p&gt;En este post comparto mi sistema, las herramientas que uso y cómo lo aplico día a día en mi ruta como desarrollador.&lt;/p&gt;
&lt;h2&gt;1. Crear un roadmap flexible (pero con dirección)&lt;/h2&gt;
&lt;p&gt;No hablo del típico roadmap gigante que te deja paralizado.
El mío tiene &lt;strong&gt;tres niveles&lt;/strong&gt; claros:&lt;/p&gt;
&lt;h3&gt;Ahora (aprendizaje activo)&lt;/h3&gt;
&lt;p&gt;Lo que estoy estudiando en este momento y quiero dominar.&lt;/p&gt;
&lt;p&gt;Ejemplo real de mis últimos meses:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Astro → para mi blog y proyectos personales&lt;/li&gt;
&lt;li&gt;Shadcn UI → para interfaces coherentes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Estas tecnologías están en mi radar diario.&lt;/p&gt;
&lt;h3&gt;Después (aprendizaje programado)&lt;/h3&gt;
&lt;p&gt;Tecnologías o conceptos que sé que estudiaré más adelante, pero &lt;strong&gt;no ahora&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Ejemplos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Next.js&lt;/li&gt;
&lt;li&gt;Docker básico&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tener este bloque me evita caer en la tentación de &amp;quot;aprender todo a la vez&amp;quot;.&lt;/p&gt;
&lt;h3&gt;Cuando pueda (aprendizaje opcional)&lt;/h3&gt;
&lt;p&gt;Cosas que me interesan, pero no impactan directamente mi trabajo inmediato.&lt;/p&gt;
&lt;p&gt;Ejemplos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;Rust&lt;/li&gt;
&lt;li&gt;MonogDB&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Son ideas interesantes… pero no urgentes.&lt;/p&gt;
&lt;h2&gt;2. Aprender haciendo: mini-proyectos intencionados&lt;/h2&gt;
&lt;p&gt;Hacer un curso sin crear nada es absorber teoría sin convertirla en experiencia.
Por eso mi aprendizaje está orientado a &lt;strong&gt;mini-proyectos concretos&lt;/strong&gt; que resuelven una necesidad real o cumplen un objetivo muy específico.&lt;/p&gt;
&lt;h3&gt;Ejemplos de mini-proyectos que me han ayudado:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Un blog con Astro&lt;/strong&gt; con tags, paginación y búsqueda&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Un dashboard React + Tailwind&lt;/strong&gt; con charts dinámicos&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cada mini-proyecto dura entre &lt;strong&gt;1 y 3 semanas&lt;/strong&gt;, máximo.
Esto es clave: lo termino, lo documento y paso al siguiente.&lt;/p&gt;
&lt;h2&gt;3. Documentar lo que aprendo (mi sistema completo)&lt;/h2&gt;
&lt;p&gt;Documentar no es solo escribir notas: es crear tu propia &amp;quot;base de conocimiento&amp;quot;.&lt;/p&gt;
&lt;h3&gt;Notas estructuradas&lt;/h3&gt;
&lt;p&gt;Aquí guardo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cada proyecto lleva un README con:&lt;ul&gt;
&lt;li&gt;qué intentaba aprender&lt;/li&gt;
&lt;li&gt;qué problema resolví&lt;/li&gt;
&lt;li&gt;qué entendí realmente&lt;/li&gt;
&lt;li&gt;qué debo repasar&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Explicaciones con mis propias palabras&lt;/li&gt;
&lt;li&gt;Resúmenes de conceptos complejos&lt;/li&gt;
&lt;li&gt;Ejemplos de código&lt;/li&gt;
&lt;li&gt;Enlaces útiles&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Con el tiempo, esta documentación se transforma en un mapa personal de lo que ya domino y lo que necesito reforzar.&lt;/p&gt;
&lt;h2&gt;4. Revisar y reajustar cada semana&lt;/h2&gt;
&lt;p&gt;Este es el hábito más importante de todo mi sistema:
&lt;strong&gt;la revisión semanal&lt;/strong&gt;, normalmente los fines de semana.&lt;/p&gt;
&lt;h3&gt;En mi revisión miro:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Qué aprendí esta semana&lt;/li&gt;
&lt;li&gt;Qué conceptos siguen confusos&lt;/li&gt;
&lt;li&gt;Qué podría practicar mejor&lt;/li&gt;
&lt;li&gt;Si sigue teniendo sentido el roadmap&lt;/li&gt;
&lt;li&gt;Si debo cambiar prioridades&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Gracias a esto evito estancarme y mantengo un ritmo constante.&lt;/p&gt;
&lt;p&gt;A veces la revisión me hace mover tecnologías del bloque &amp;quot;Ahora&amp;quot; al bloque &amp;quot;Después&amp;quot;.
Otras veces me doy cuenta de que una tecnología ya la domino más de lo que pensaba.&lt;/p&gt;
&lt;p&gt;Esta revisión es lo que realmente me mantiene avanzando.&lt;/p&gt;
&lt;h2&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Organizar el aprendizaje no va de estudiar más, sino de estudiar mejor.
Mi sistema se basa en:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Un roadmap flexible&lt;/li&gt;
&lt;li&gt;Mini-proyectos enfocados&lt;/li&gt;
&lt;li&gt;Documentación constante&lt;/li&gt;
&lt;li&gt;Revisiones semanales&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Gracias a esto siento que avanzo sin saturarme y disfruto mucho más del proceso.&lt;/p&gt;
&lt;p&gt;¡Feliz aprendizaje a tod@s!&lt;/p&gt;
</content:encoded><category>Crecimiento</category><category>Estudio</category><category>Productividad</category><category>Desarrollo web</category><category>Aprendizaje</category><author>Hugo Cayón Laso</author></item><item><title>La Razón de Ser de JSON y TOON: Soluciones a Problemas de Época</title><link>http://localhost:4321/blog/json-y-toon-soluciones-de-su-epoca/</link><guid isPermaLink="true">http://localhost:4321/blog/json-y-toon-soluciones-de-su-epoca/</guid><description>Descubre por qué JSON reemplazó a XML y por qué el nuevo formato TOON está desafiando a JSON en el mundo de la Inteligencia Artificial.</description><pubDate>Sun, 30 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Cuando observamos la historia de los formatos de datos, vemos una tendencia clara: la &lt;strong&gt;serialización&lt;/strong&gt; siempre evoluciona para resolver el cuello de botella del momento. Para JSON, el cuello de botella era &lt;strong&gt;la complejidad de XML&lt;/strong&gt;; para TOON, es &lt;strong&gt;el costo del token&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;1. El Nacimiento de JSON: El Cansancio de XML (Inicios de los 2000)&lt;/h2&gt;
&lt;p&gt;La razón por la que &lt;strong&gt;JSON (JavaScript Object Notation)&lt;/strong&gt; surgió a principios de la década de 2000 se resume en una palabra: &lt;strong&gt;XML&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;El Problema a Resolver: La Carga Pesada de XML&lt;/h3&gt;
&lt;p&gt;A principios de siglo, la tecnología dominante para la transferencia de datos entre servidores y navegadores era &lt;strong&gt;XML (eXtensible Markup Language)&lt;/strong&gt;. El proceso de AJAX (Asynchronous JavaScript and XML) era el estándar, pero presentaba grandes desafíos:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Verbosiadad:&lt;/strong&gt; XML es muy repetitivo. Cada dato requiere una etiqueta de apertura y otra de cierre. Esto significaba que la transferencia de datos triviales resultaba en paquetes muy grandes y lentos.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Complejidad del Parsing:&lt;/strong&gt; Para que JavaScript pudiera leer datos de XML, era necesario manipular el DOM (Document Object Model) y recorrer la estructura de etiquetas, lo cual era lento y propenso a errores en los diferentes navegadores.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;La Solución de JSON: Simplicidad Nativa&lt;/h3&gt;
&lt;p&gt;El desarrollador &lt;strong&gt;Douglas Crockford&lt;/strong&gt; (junto con State Software) propuso un formato que eliminaba toda la complejidad:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Es Nativo de JavaScript:&lt;/strong&gt; JSON es, literalmente, la notación que JavaScript ya utiliza para sus objetos. Esto significó que los navegadores podían analizarlo (&lt;em&gt;parsearlo&lt;/em&gt;) instantáneamente, sin necesidad de librerías complejas.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ligero y Conciso:&lt;/strong&gt; Eliminó las etiquetas repetidas, resultando en paquetes de datos mucho más pequeños.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;JSON nació para hacer que las aplicaciones web fueran &lt;strong&gt;más rápidas y fáciles de programar&lt;/strong&gt; al reemplazar el pesado y complejo &lt;strong&gt;XML&lt;/strong&gt; con una sintaxis simple y nativa de JavaScript.&lt;/p&gt;
&lt;h2&gt;2. El Origen de TOON: El Costo Oculto de los Tokens&lt;/h2&gt;
&lt;p&gt;Casi 25 años después, la necesidad de optimización ha vuelto, pero esta vez no es por la velocidad de la red o la complejidad del código, sino por la &lt;strong&gt;eficiencia en el consumo de IA&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;El Problema a Resolver: El Impuesto de Tokens de JSON&lt;/h3&gt;
&lt;p&gt;Con el auge de los LLMs, el nuevo recurso más valioso y limitado es el &lt;strong&gt;token&lt;/strong&gt; dentro de la ventana de contexto del modelo. JSON, a pesar de su concisión frente a XML, es increíblemente redundante en este nuevo contexto:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Consumo de Contexto:&lt;/strong&gt; Las estructuras repetitivas de JSON (comillas, llaves, comas y, sobre todo, la &lt;strong&gt;repetición de claves&lt;/strong&gt;) consumen tokens vitales que podrían usarse para transferir más información semántica.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Costo Directo:&lt;/strong&gt; Cada token consumido tiene un costo económico asociado. Usar JSON para grandes &lt;em&gt;arrays&lt;/em&gt; (por ejemplo, resultados de una base de datos) es pagar de más por la sintaxis.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;La Solución de TOON: Eficiencia en el Lenguaje de la IA&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;TOON (Token-Oriented Object Notation)&lt;/strong&gt; nació en &lt;strong&gt;2025&lt;/strong&gt; con el propósito claro de ser el formato más eficiente para transferir datos estructurados a los LLMs, maximizando el uso de cada token:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Eliminación de Redundancia:&lt;/strong&gt; Mediante sus &lt;strong&gt;Arrays Tabulares&lt;/strong&gt;, TOON declara las claves una sola vez y luego lista solo los valores, logrando una reducción de tokens de hasta el &lt;strong&gt;60%&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Limpieza Sintáctica:&lt;/strong&gt; Minimiza el uso de comillas y llaves, limpiando el ruido del &lt;em&gt;prompt&lt;/em&gt; y haciendo que la &lt;strong&gt;IA cometa menos errores&lt;/strong&gt; al analizar la estructura.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;TOON nació para optimizar los &lt;strong&gt;costos y el rendimiento&lt;/strong&gt; de las aplicaciones de Inteligencia Artificial, corrigiendo la principal deficiencia de JSON en el mundo del &lt;em&gt;prompting&lt;/em&gt;: su excesiva verbosidad.&lt;/p&gt;
&lt;h3&gt;Una Evolución Constante&lt;/h3&gt;
&lt;p&gt;Ambos formatos representan puntos clave en la historia del desarrollo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;JSON&lt;/strong&gt; liberó al desarrollador de la complejidad de la web.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TOON&lt;/strong&gt; busca liberar al agente de IA de las limitaciones y los costos del token.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;La historia de la serialización de datos es, en última instancia, la historia de cómo los desarrolladores buscamos la &lt;strong&gt;máxima eficiencia&lt;/strong&gt; con las herramientas que tenemos a nuestra disposición.&lt;/p&gt;
&lt;p&gt;Hasta la próxima.&lt;/p&gt;
</content:encoded><category>XML</category><category>LLMs</category><category>Inteligencia artificial</category><category>IA</category><category>TOON</category><category>JSON</category><category>Historia</category><author>Hugo Cayón Laso</author></item><item><title>De la Teoría a la Práctica: Mis 4 Meses Como Junior</title><link>http://localhost:4321/blog/de-la-teoria-a-la-practica-junior/</link><guid isPermaLink="true">http://localhost:4321/blog/de-la-teoria-a-la-practica-junior/</guid><description>Un relato honesto sobre lo que realmente significa empezar en el mundo profesional del desarrollo web: dudas, logros, aprendizajes y crecimiento.</description><pubDate>Sat, 15 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hola, soy &lt;strong&gt;Hugo&lt;/strong&gt;, y hace apenas unos meses di el salto al mundo profesional del desarrollo web. Lo que comenzó como emoción absoluta se transformó rápidamente en una mezcla de vértigo, orgullo, frustración, dudas y muchas ganas de aprender.&lt;/p&gt;
&lt;p&gt;Quería compartir cómo ha sido este inicio, sin filtros y sin adornos, porque &lt;em&gt;lo que te cuentan en los cursos no es lo que te encuentras cuando empiezas a trabajar de verdad&lt;/em&gt;.&lt;/p&gt;
&lt;h2&gt;El Primer Golpe: El Código Real No Se Parece a Tus Proyectos&lt;/h2&gt;
&lt;p&gt;Lo primero que descubrí fue que mis proyectos personales, por bonitos que fueran, no me preparaban para una base de código viva, grande y usada por miles de usuarios.&lt;/p&gt;
&lt;p&gt;De repente me encontré con:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;patrones que nunca había visto,&lt;/li&gt;
&lt;li&gt;archivos que parecían escritos por distintas personas,&lt;/li&gt;
&lt;li&gt;dependencias antiguas,&lt;/li&gt;
&lt;li&gt;abstracciones que tomaban tiempo entender.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No tenía que &amp;quot;crear cosas nuevas&amp;quot;: tenía que &lt;strong&gt;entender&lt;/strong&gt;.
Y entender es más difícil que escribir.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Aprendizaje:&lt;/strong&gt;
Saber programar no significa saber moverte en un proyecto real. La habilidad más valiosa al principio es leer código, seguir pistas y no desesperarte.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;El Primer Logro: Aportar Aunque Sea Poco&lt;/h2&gt;
&lt;p&gt;Después de sentirme perdido, empezaron a llegar pequeñas victorias: corregir pequeños fallos de logica, mejorar una función, resolver un bug. Cosas aparentemente insignificantes, pero que aportaban valor real al equipo.&lt;/p&gt;
&lt;p&gt;El día que complete mi primer desarrollo grande sentí un orgullo ridículo… y totalmente válido.
Esas pequeñas victorias son las que empujan a seguir.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Aprendizaje:&lt;/strong&gt;
No subestimes las tareas simples. Te construyen criterio, confianza y te convierten en alguien útil para el equipo.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;El Enemigo Invisible: El Síndrome del Impostor&lt;/h2&gt;
&lt;p&gt;Lo más difícil no fue aprender una librería o entender una arquitectura.
Fue lidiar con mi cabeza.&lt;/p&gt;
&lt;p&gt;Hubo días en los que creí que no estaba a la altura, en los que un error tonto hacía que me cuestionara si era &amp;quot;lo suficientemente bueno&amp;quot; para el trabajo. Es algo de lo que casi nadie habla, pero todos enfrentamos.&lt;/p&gt;
&lt;p&gt;Una de las cosas que más me ayudó fue entender que pedir ayuda &lt;strong&gt;no es un fracaso&lt;/strong&gt;, sino parte del proceso. Preguntar bien, explicar tu contexto, mostrar lo que intentaste… eso demuestra profesionalismo, no debilidad.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Aprendizaje:&lt;/strong&gt;
No eres menos desarrollador por no saber algo. Lo importante es tu capacidad de aprender, comunicar y avanzar.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;El Gran Cambio: Ver el Proyecto Como Un Todo&lt;/h2&gt;
&lt;p&gt;En algún momento, las piezas empezaron a encajar.
Dejé de ver tareas sueltas y comencé a comprender cómo las diferentes partes del proyecto se conectaban entre sí:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;por qué usamos ciertas tecnologías,&lt;/li&gt;
&lt;li&gt;qué decisiones afectan el rendimiento,&lt;/li&gt;
&lt;li&gt;cómo un pequeño cambio puede romper una funcionalidad inesperada,&lt;/li&gt;
&lt;li&gt;y por qué la arquitectura existe como existe.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ya no me sentía un turista dentro del repositorio.
Empecé a sentirme parte del proyecto.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Aprendizaje:&lt;/strong&gt;
El crecimiento no llega de golpe. Llega un día en el que te das cuenta de que entiendes más de lo que entendías ayer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Consejo Final Para Otros Juniors&lt;/h2&gt;
&lt;p&gt;Si tú también estás empezando:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ten paciencia contigo mismo.&lt;/strong&gt;
No te compares con personas que llevan años en esto.
No busques ser rápido: busca ser consistente.&lt;/p&gt;
&lt;p&gt;Aprenderás más de un pull request rechazado que de un tutorial de 10 horas.
Crecerás más resolviendo un bug pequeño que rehaciendo un clon de cualquier video de YouTube.
Y te harás mejor desarrollador cada vez que te atrevas a preguntar sin miedo.&lt;/p&gt;
&lt;p&gt;Aún estoy lejos de donde quiero llegar, pero estos primeros meses fueron suficientes para convencerme de algo:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Estoy exactamente donde tengo que estar.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Nos leemos en el próximo artículo.&lt;/p&gt;
</content:encoded><category>Crecimiento</category><category>Experiencia</category><category>Junior</category><category>Desarrollo web</category><author>Hugo Cayón Laso</author></item><item><title>Bienvenido a mi blog</title><link>http://localhost:4321/blog/bienvenido-a-mi-blog/</link><guid isPermaLink="true">http://localhost:4321/blog/bienvenido-a-mi-blog/</guid><description>Un espacio donde comparto mis experiencias como desarrollador web, mis proyectos personales y curiosidades sobre tecnología.</description><pubDate>Thu, 13 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;¿Quién soy?&lt;/h2&gt;
&lt;p&gt;Hola, soy &lt;strong&gt;Hugo&lt;/strong&gt;, desarrollador web apasionado por la tecnología, el código limpio y todo lo que tenga que ver con crear cosas útiles (y a veces solo divertidas) en Internet.&lt;/p&gt;
&lt;h2&gt;¿De qué trata este blog?&lt;/h2&gt;
&lt;p&gt;He decidido abrir este espacio para compartir mi experiencia como desarrollador: los &lt;strong&gt;proyectos personales&lt;/strong&gt; en los que trabajo, los &lt;strong&gt;retos que enfrento&lt;/strong&gt; en el día a día y lo que voy &lt;strong&gt;aprendiendo en el camino&lt;/strong&gt;. También encontrarás &lt;strong&gt;curiosidades del mundo tech&lt;/strong&gt;, reflexiones sobre herramientas y lenguajes, y mi opinión sobre las &lt;strong&gt;tendencias que están dando forma al futuro del desarrollo web&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;Código y proyectos&lt;/h3&gt;
&lt;p&gt;Hablaré de lo que construyo: herramientas, experimentos, side projects y todo lo que salga de mis ratos libres frente al editor.&lt;/p&gt;
&lt;h3&gt;La parte humana&lt;/h3&gt;
&lt;p&gt;La idea no es solo hablar de código, sino también de la &lt;strong&gt;parte humana detrás del teclado&lt;/strong&gt;: la motivación, la frustración cuando algo no compila, la alegría de ver un proyecto terminado… y todo lo que hay entre medio.&lt;/p&gt;
&lt;h2&gt;¿A quién va dirigido?&lt;/h2&gt;
&lt;p&gt;Si te interesa el &lt;strong&gt;desarrollo web&lt;/strong&gt;, la &lt;strong&gt;innovación tecnológica&lt;/strong&gt; o simplemente te gusta leer sobre cómo otros viven este apasionante mundo digital, &lt;strong&gt;estás en el lugar correcto&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;Hasta pronto&lt;/h2&gt;
&lt;p&gt;Gracias por pasarte por aquí.
Espero que disfrutes los artículos y que juntos aprendamos algo nuevo en cada publicación.&lt;/p&gt;
&lt;p&gt;Nos leemos pronto.&lt;/p&gt;
</content:encoded><category>Proyectos</category><category>Tecnología</category><category>Desarrollo web</category><author>Hugo Cayón Laso</author></item></channel></rss>