← Volver al blog

Stack tecnológico de un programador web moderno en 2026

Descubre las tecnologías, frameworks y herramientas que todo programador web profesional debe dominar en 2026. Análisis completo de frontend, backend, databases, DevOps e IA.

Jordi Morillo·5 de marzo de 2026·11 min lectura

Stack tecnológico de un programador web moderno en 2026

El programador web de 2026 debe dominar un ecosistema tecnológico mucho más amplio y sofisticado que hace una década. Ya no basta con HTML, CSS y jQuery.

En este artículo, exploraré el stack completo que un programador web profesional debe conocer, desde el frontend hasta DevOps e inteligencia artificial, explicando por qué cada tecnología es relevante y cómo se integran en proyectos reales.

Principios antes de herramientas

Antes de listar tecnologías, recordemos los principios que guían al programador web moderno:

1. Full-stack capability

El desarrollador moderno debe entender toda la stack:

  • No necesitas ser experto en todo
  • Pero sí competente en frontend, backend y deployment
  • Permite tomar mejores decisiones arquitectónicas
  • Facilita debugging de problemas end-to-end

2. TypeScript first

JavaScript dinámico está obsoleto:

  • Tipos previenen bugs en desarrollo
  • IDEs con autocompletado inteligente
  • Refactoring seguro
  • Documentación implícita

3. Testing obligatorio

El código sin tests es código legacy desde día 1:

  • TDD (Test-Driven Development) no negociable
  • Cobertura >80% mínima
  • Tests unitarios, integración y E2E
  • CI/CD ejecutando tests automáticamente

4. Developer Experience (DX)

Productividad depende de buenas herramientas:

  • Hot reload para feedback inmediato
  • Linting y formatting automático
  • Type checking en tiempo real
  • Debug tools sofisticados

Ahora sí, veamos el stack tecnológico actual.

Frontend: La cara visible de la aplicación

El frontend ha evolucionado de páginas estáticas a aplicaciones complejas.

React: El estándar de facto

Por qué React sigue dominando en 2026:

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment">// Component moderno con TypeScript y hooks&lt;/span&gt;</span>
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>import<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> { useState, useEffect } &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">from</span>&lt;<span class="hljs-regexp">/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;react&amp;#x27;&lt;/</span>span&gt;

<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>interface<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>User<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> {
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>id<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>number<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>name<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>string<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>email<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>string<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
}

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">function</span>&lt;<span class="hljs-regexp">/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;UserProfile&lt;/</span>span&gt;(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-params&quot;</span>&gt;</span>{ userId }: { userId: <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>number<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> }<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>) {
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>const<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> [user, setUser] = useState&amp;lt;<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>User<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> | <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-literal&quot;</span>&gt;</span>null<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>&amp;gt;(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-literal&quot;</span>&gt;</span>null<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>)
  &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">const</span>&lt;<span class="hljs-regexp">/span&gt; [loading, setLoading] = &lt;span class=&quot;hljs-title function_&quot;&gt;useState&lt;/</span>span&gt;(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-literal&quot;</span>&gt;</span>true<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>)

  &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;useEffect&lt;<span class="hljs-regexp">/span&gt;(&lt;span class=&quot;hljs-function&quot;&gt;() =&amp;gt;&lt;/</span>span&gt; {
    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;</span>fetch<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;</span>`/api/users/<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-subst&quot;</span>&gt;</span>${userId}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>`<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>)
      .&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;then&lt;<span class="hljs-regexp">/span&gt;(&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-params&quot;&gt;res&lt;/</span>span&gt; =&amp;gt;&lt;<span class="hljs-regexp">/span&gt; res.&lt;span class=&quot;hljs-title function_&quot;&gt;json&lt;/</span>span&gt;())
      .&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;then&lt;<span class="hljs-regexp">/span&gt;(&lt;span class=&quot;hljs-function&quot;&gt;&lt;span class=&quot;hljs-params&quot;&gt;data&lt;/</span>span&gt; =&amp;gt;&lt;/span&gt; {
        <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;</span>setUser<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>(data)
        &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;setLoading&lt;<span class="hljs-regexp">/span&gt;(&lt;span class=&quot;hljs-literal&quot;&gt;false&lt;/</span>span&gt;)
      })
  }, [userId])

  &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">if</span>&lt;<span class="hljs-regexp">/span&gt; (loading) &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/</span>span&gt; <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;language-xml&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>div<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>Cargando...<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span>/<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>div<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>if<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> (!user) &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">return</span>&lt;<span class="hljs-regexp">/span&gt; &lt;span class=&quot;language-xml&quot;&gt;&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;&lt;span class=&quot;hljs-name&quot;&gt;div&lt;/</span>span&gt;&amp;gt;&lt;<span class="hljs-regexp">/span&gt;Usuario no encontrado&lt;span class=&quot;hljs-tag&quot;&gt;&amp;lt;/</span><span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>div<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>&amp;gt;&lt;<span class="hljs-regexp">/span&gt;&lt;/</span>span&gt;

  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>return<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> (
    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;language-xml&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>div<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>className<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>=<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;</span><span class="hljs-symbol">&amp;quot;</span>user-profile<span class="hljs-symbol">&amp;quot;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>h1<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>{user.name}<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span>/<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>h1<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>p<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>{user.email}<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span>/<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>p<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span>/<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>div<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  )
}

Ventajas:

  • Ecosistema maduro y estable
  • Componentes reutilizables
  • Virtual DOM para rendimiento
  • Hooks para lógica compartida
  • Compatibilidad con Next.js

Next.js: React para producción

El framework que todo programador web debe dominar:

Next.js transforma React en una plataforma completa:

  • SSR (Server-Side Rendering): SEO perfecto
  • SSG (Static Site Generation): Rendimiento óptimo
  • API Routes: Backend integrado
  • Image Optimization: Imágenes automáticamente optimizadas
  • File-based routing: Estructura clara
&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment">// app/servicios/[slug]/page.tsx&lt;/span&gt;</span>
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>import<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> { <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Metadata<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> } &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">from</span>&lt;<span class="hljs-regexp">/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;next&amp;#x27;&lt;/</span>span&gt;

<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>export<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>async<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>function<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;</span>generateMetadata<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-params&quot;</span>&gt;</span>{ 
  params 
}: { 
  params: { slug: <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>string<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> } 
}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>): <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Promise<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>&amp;lt;<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Metadata<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>&amp;gt; {
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>return<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> {
    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>title<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;</span>`Servicio de <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-subst&quot;</span>&gt;</span>${params.slug}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>`<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>,
    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>description<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;</span><span class="hljs-symbol">&amp;#x27;</span>Descripción optimizada para SEO<span class="hljs-symbol">&amp;#x27;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  }
}

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">export</span>&lt;<span class="hljs-regexp">/span&gt; &lt;span class=&quot;hljs-keyword&quot;&gt;default&lt;/</span>span&gt; <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>function<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;</span>ServicioPage<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-params&quot;</span>&gt;</span>{ 
  params 
}: { 
  params: { slug: <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>string<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> } 
}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>) {
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>return<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;language-xml&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>div<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>Contenido del servicio {params.slug}<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span>/<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>div<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
}

Uso Next.js en prácticamente todos mis proyectos web profesionales por su balance perfecto entre DX y rendimiento.

TypeScript: Seguridad de tipos obligatoria

Por qué TypeScript es no negociable en 2026:

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment">// Sin TypeScript: bugs en runtime&lt;/span&gt;</span>
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>function<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;</span>calculatePrice<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-params&quot;</span>&gt;</span>quantity, price<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>) {
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>return<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> quantity * price  &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment">// ¿Qué pasa si alguien pasa strings?&lt;/span&gt;</span>
}

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment">// Con TypeScript: bugs en desarrollo&lt;/span&gt;</span>
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>function<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;</span>calculatePrice<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-params&quot;</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>quantity<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>: <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>number<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>, 
  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>price<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>: <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>number<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>): <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>number<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> {
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>return<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> quantity * price  &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment">// Error si recibes tipos incorrectos&lt;/span&gt;</span>
}

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment">// Tipos complejos para seguridad&lt;/span&gt;</span>
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>interface<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Product<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> {
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>id<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>string<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>name<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>string<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>price<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>number<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>stock<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>number<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>category<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;</span><span class="hljs-symbol">&amp;#x27;</span>web<span class="hljs-symbol">&amp;#x27;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> | <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;</span><span class="hljs-symbol">&amp;#x27;</span>ia<span class="hljs-symbol">&amp;#x27;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> | <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;</span><span class="hljs-symbol">&amp;#x27;</span>consultoria<span class="hljs-symbol">&amp;#x27;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
}

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">function</span>&lt;<span class="hljs-regexp">/span&gt; &lt;span class=&quot;hljs-title function_&quot;&gt;processProduct&lt;/</span>span&gt;(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-params&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>product<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>: <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Product<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>): <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>void<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> {
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;</span>// IDE autocompleta propiedades<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;</span>// Refactoring seguro<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;</span>// Documentación implícita<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
}

Beneficios reales:

  • 40-80% menos bugs en producción
  • Refactoring sin miedo
  • Documentación que nunca se desactualiza
  • Onboarding de nuevos developers más rápido

Tailwind CSS: Utility-first styling

Por qué Tailwind ha ganado la guerra de CSS:

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment">// Antes: CSS separado, naming decisions, especificidad&lt;/span&gt;</span>
&amp;lt;div className=<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;</span><span class="hljs-symbol">&amp;quot;</span>user-card<span class="hljs-symbol">&amp;quot;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>&amp;gt;
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;language-xml&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>h2<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>className<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>=<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;</span><span class="hljs-symbol">&amp;quot;</span>user-card__title<span class="hljs-symbol">&amp;quot;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>Título<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span>/<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>h2<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
&amp;lt;/div&amp;gt;

<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;</span>// Ahora: Tailwind utilities, composición rápida<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;language-xml&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>div<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>className<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>=<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;</span><span class="hljs-symbol">&amp;quot;</span>bg-white rounded-lg shadow-md p-6<span class="hljs-symbol">&amp;quot;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>h2<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>className<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>=<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;</span><span class="hljs-symbol">&amp;quot;</span>text-2xl font-bold text-gray-800<span class="hljs-symbol">&amp;quot;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>Título<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span>/<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>h2<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-tag&quot;</span>&gt;</span><span class="hljs-symbol">&amp;lt;</span>/<span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-name&quot;</span>&gt;</span>div<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-symbol">&amp;gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>

Ventajas:

  • Desarrollo ultra-rápido sin cambiar contexto
  • Diseño consistente automáticamente
  • CSS producido muy optimizado (solo clases usadas)
  • Responsive design simplificado
  • Dark mode trivial

Alternativas viable: Vue y Svelte

Vue.js sigue siendo excelente para:

  • Proyectos más pequeños
  • Teams que prefieren sintaxis templates
  • Curva de aprendizaje más suave

Svelte está creciendo para:

  • Rendimiento extremo (no virtual DOM)
  • Bundle sizes mínimos
  • DX excepcional

Personalmente, me especializo en React/Next.js porque cubre el 90% de casos de uso con calidad enterprise.

Backend: El cerebro de la aplicación

El backend maneja lógica de negocio, datos y seguridad.

Node.js con Express o Fastify

JavaScript/TypeScript en el backend:

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment">// Express con TypeScript&lt;/span&gt;</span>
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>import<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> express, { <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Request<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>, <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Response<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> } &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">from</span>&lt;<span class="hljs-regexp">/span&gt; &lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;express&amp;#x27;&lt;/</span>span&gt;

<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>const<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> app = <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;</span>express<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>()

app.&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;get&lt;<span class="hljs-regexp">/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;/</span>api/users/:id&amp;#x27;&lt;<span class="hljs-regexp">/span&gt;, &lt;span class=&quot;hljs-title function_&quot;&gt;async&lt;/</span>span&gt; (<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>req<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Request<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>, <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>res<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Response<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>) =&amp;gt; {
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>const<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> userId = <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>parseInt<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>(req.&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-property&quot;</span>&gt;params&lt;<span class="hljs-regexp">/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;id&lt;/</span>span&gt;)
  &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">const</span>&lt;<span class="hljs-regexp">/span&gt; user = &lt;span class=&quot;hljs-keyword&quot;&gt;await&lt;/</span>span&gt; db.&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-property&quot;</span>&gt;users&lt;<span class="hljs-regexp">/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;findById&lt;/</span>span&gt;(userId)
  
  &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">if</span>&lt;/span&gt; (!user) {
    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>return<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> res.&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;status&lt;<span class="hljs-regexp">/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;404&lt;/</span>span&gt;).&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;json&lt;<span class="hljs-regexp">/span&gt;({ &lt;span class=&quot;hljs-attr&quot;&gt;error&lt;/</span>span&gt;: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;</span><span class="hljs-symbol">&amp;#x27;</span>User not found<span class="hljs-symbol">&amp;#x27;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> })
  }
  
  res.&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;json&lt;/span&gt;(user)
})

app.&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;listen&lt;<span class="hljs-regexp">/span&gt;(&lt;span class=&quot;hljs-number&quot;&gt;3000&lt;/</span>span&gt;)

Cuándo usar Node.js:

  • Aplicaciones real-time (WebSockets)
  • APIs REST rápidas
  • Microservicios ligeros
  • Cuando frontend es React/Next.js (mismo lenguaje)

Python con Django o FastAPI

Python para proyectos complejos:

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment"># FastAPI con type hints&lt;/span&gt;</span>
&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">from</span>&lt;/span&gt; fastapi &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">import</span>&lt;/span&gt; FastAPI, HTTPException
&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">from</span>&lt;/span&gt; pydantic &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">import</span>&lt;/span&gt; BaseModel

app = FastAPI()

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">class</span>&lt;/span&gt; &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;User&lt;/span&gt;(&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title class_ inherited__&quot;</span>&gt;BaseModel&lt;/span&gt;):
    &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;<span class="hljs-built_in">id</span>&lt;/span&gt;: &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;<span class="hljs-built_in">int</span>&lt;/span&gt;
    name: &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;<span class="hljs-built_in">str</span>&lt;/span&gt;
    email: &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;<span class="hljs-built_in">str</span>&lt;/span&gt;

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-meta&quot;</span>&gt;@app.get(&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-params&quot;</span>&gt;&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;&amp;quot;/users/{user_id}&amp;quot;&lt;/span&gt;, response_model=User&lt;/span&gt;)&lt;/span&gt;
&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">async</span>&lt;/span&gt; &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">def</span>&lt;/span&gt; &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;get_user&lt;/span&gt;(&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-params&quot;</span>&gt;user_id: &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;<span class="hljs-built_in">int</span>&lt;/span&gt;&lt;/span&gt;):
    user = &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">await</span>&lt;/span&gt; db.get_user(user_id)
    &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">if</span>&lt;/span&gt; &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">not</span>&lt;/span&gt; user:
        &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">raise</span>&lt;/span&gt; HTTPException(status_code=&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-number&quot;</span>&gt;<span class="hljs-number">404</span>&lt;/span&gt;, detail=&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;&amp;quot;User <span class="hljs-keyword">not</span> found&amp;quot;&lt;/span&gt;)
    &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">return</span>&lt;/span&gt; user

Cuándo usar Python:

Python es mi elección cuando el proyecto involucra ingeniería de IA.

PHP moderno con Symfony

PHP ha renacido con versión 8.x:

&lt;span <span class="hljs-class"><span class="hljs-keyword">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">comment</span>&quot;&gt;// <span class="hljs-title">PHP</span> 8.3 <span class="hljs-title">con</span> <span class="hljs-title">tipos</span> <span class="hljs-title">y</span> <span class="hljs-title">attributes</span>&lt;/<span class="hljs-title">span</span>&gt;
&lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">meta</span>&quot;&gt;#[<span class="hljs-title">Route</span>&lt;/<span class="hljs-title">span</span>&gt;(&lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">string</span>&quot;&gt;&amp;#<span class="hljs-title">x27</span>;/<span class="hljs-title">api</span>/<span class="hljs-title">users</span>/</span>{id}&amp;<span class="hljs-comment">#x27;&lt;/span&gt;, &lt;span class=&quot;hljs-attr&quot;&gt;methods&lt;/span&gt;: [&lt;span class=&quot;hljs-string&quot;&gt;&amp;#x27;GET&amp;#x27;&lt;/span&gt;])&lt;span class=&quot;hljs-meta&quot;&gt;]&lt;/span&gt;</span>
&lt;span <span class="hljs-class"><span class="hljs-keyword">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">keyword</span>&quot;&gt;<span class="hljs-title">public</span>&lt;/<span class="hljs-title">span</span>&gt; &lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">function</span>&quot;&gt;&lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">keyword</span>&quot;&gt;<span class="hljs-title">function</span>&lt;/<span class="hljs-title">span</span>&gt; &lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">title</span>&quot;&gt;<span class="hljs-title">getUser</span>&lt;/<span class="hljs-title">span</span>&gt;(&lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">params</span>&quot;&gt;&lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">keyword</span>&quot;&gt;<span class="hljs-title">int</span>&lt;/<span class="hljs-title">span</span>&gt; &lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">variable</span>&quot;&gt;$<span class="hljs-title">id</span>&lt;/<span class="hljs-title">span</span>&gt;&lt;/<span class="hljs-title">span</span>&gt;): &lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">title</span>&quot;&gt;<span class="hljs-title">JsonResponse</span>&lt;/<span class="hljs-title">span</span>&gt;
&lt;/<span class="hljs-title">span</span>&gt;</span>{
    &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">variable</span>&quot;&gt;$<span class="hljs-title">user</span>&lt;/<span class="hljs-title">span</span>&gt; = &lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">variable</span> <span class="hljs-title">language_</span>&quot;&gt;$<span class="hljs-title">this</span>&lt;/<span class="hljs-title">span</span>&gt;-&amp;<span class="hljs-title">gt</span>;<span class="hljs-title">userRepository</span>-&amp;<span class="hljs-title">gt</span>;&lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">title</span> <span class="hljs-title">function_</span> <span class="hljs-title">invoke__</span>&quot;&gt;<span class="hljs-title">find</span>&lt;/<span class="hljs-title">span</span>&gt;(&lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">variable</span>&quot;&gt;$<span class="hljs-title">id</span>&lt;/<span class="hljs-title">span</span>&gt;);
    
    &lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">keyword</span>&quot;&gt;<span class="hljs-title">if</span>&lt;/<span class="hljs-title">span</span>&gt; (!&lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">variable</span>&quot;&gt;$<span class="hljs-title">user</span>&lt;/<span class="hljs-title">span</span>&gt;) </span>{
        &lt;span <span class="hljs-class"><span class="hljs-keyword">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">keyword</span>&quot;&gt;<span class="hljs-title">return</span>&lt;/<span class="hljs-title">span</span>&gt; &lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">keyword</span>&quot;&gt;<span class="hljs-title">new</span>&lt;/<span class="hljs-title">span</span>&gt; &lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">title</span> <span class="hljs-title">class_</span>&quot;&gt;<span class="hljs-title">JsonResponse</span>&lt;/<span class="hljs-title">span</span>&gt;(
            [&lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">string</span>&quot;&gt;&amp;#<span class="hljs-title">x27</span>;<span class="hljs-title">error</span>&amp;#<span class="hljs-title">x27</span>;&lt;/<span class="hljs-title">span</span>&gt; =&amp;<span class="hljs-title">gt</span>; &lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">string</span>&quot;&gt;&amp;#<span class="hljs-title">x27</span>;<span class="hljs-title">User</span> <span class="hljs-title">not</span> <span class="hljs-title">found</span>&amp;#<span class="hljs-title">x27</span>;&lt;/<span class="hljs-title">span</span>&gt;], 
            404
        );
    }
    
    &lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">keyword</span>&quot;&gt;<span class="hljs-title">return</span>&lt;/<span class="hljs-title">span</span>&gt; &lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">keyword</span>&quot;&gt;<span class="hljs-title">new</span>&lt;/<span class="hljs-title">span</span>&gt; &lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">title</span> <span class="hljs-title">class_</span>&quot;&gt;<span class="hljs-title">JsonResponse</span>&lt;/<span class="hljs-title">span</span>&gt;(&lt;<span class="hljs-title">span</span> <span class="hljs-title">class</span>=&quot;<span class="hljs-title">hljs</span>-<span class="hljs-title">variable</span>&quot;&gt;$<span class="hljs-title">user</span>&lt;/<span class="hljs-title">span</span>&gt;);
}</span>

Cuándo usar PHP:

  • Clientes con hosting compartido
  • Legacy systems que mantener
  • Ecosistema maduro (Symfony, Laravel)
  • Presupuestos ajustados (hosting más barato)

APIs: REST vs GraphQL

REST sigue siendo el estándar:

  • Más simple de entender
  • Caching HTTP standard
  • Herramientas establecidas

GraphQL para casos específicos:

  • Frontend necesita datos muy personalizados
  • Reducir overfetching
  • APIs públicas complejas

En mis proyectos de ecommerce y SaaS, uso REST con OpenAPI spec para documentación automática.

Bases de datos: Persistencia y cache

Elegir la base de datos correcta es crítico.

PostgreSQL: El rey de bases relacionales

Por qué PostgreSQL es mi default:

<span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-comment&quot;<span class="hljs-operator">&gt;</span><span class="hljs-comment">-- Tipos avanzados, JSON, full-text search&lt;/span&gt;</span>
<span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-keyword&quot;<span class="hljs-operator">&gt;</span><span class="hljs-keyword">CREATE TABLE</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span> products (
    id SERIAL <span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-keyword&quot;<span class="hljs-operator">&gt;</span><span class="hljs-keyword">PRIMARY KEY</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span>,
    name <span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-type&quot;<span class="hljs-operator">&gt;</span><span class="hljs-type">VARCHAR</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span>(<span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-number&quot;<span class="hljs-operator">&gt;</span><span class="hljs-number">255</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span>) <span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-keyword&quot;<span class="hljs-operator">&gt;</span><span class="hljs-keyword">NOT NULL</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span>,
    description TEXT,
    price <span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-type&quot;<span class="hljs-operator">&gt;</span><span class="hljs-type">DECIMAL</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span>(<span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-number&quot;<span class="hljs-operator">&gt;</span><span class="hljs-number">10</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span>, <span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-number&quot;<span class="hljs-operator">&gt;</span><span class="hljs-number">2</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span>) <span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-keyword&quot;<span class="hljs-operator">&gt;</span><span class="hljs-keyword">NOT NULL</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span>,
    metadata JSONB,  <span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-comment&quot;<span class="hljs-operator">&gt;</span><span class="hljs-comment">-- JSON con indexing&lt;/span&gt;</span>
    search_vector tsvector,  <span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-comment&quot;<span class="hljs-operator">&gt;</span><span class="hljs-comment">-- Full-text search&lt;/span&gt;</span>
    created_at <span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-type&quot;<span class="hljs-operator">&gt;</span><span class="hljs-type">TIMESTAMP</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span> <span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-keyword&quot;<span class="hljs-operator">&gt;</span><span class="hljs-keyword">DEFAULT</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span> NOW()
);

<span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-keyword&quot;<span class="hljs-operator">&gt;</span><span class="hljs-keyword">CREATE</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span> INDEX idx_products_metadata 
<span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-keyword&quot;<span class="hljs-operator">&gt;</span><span class="hljs-keyword">ON</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span> products <span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-keyword&quot;<span class="hljs-operator">&gt;</span><span class="hljs-keyword">USING</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span> GIN (metadata);

<span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-keyword&quot;<span class="hljs-operator">&gt;</span><span class="hljs-keyword">CREATE</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span> INDEX idx_products_search 
<span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-keyword&quot;<span class="hljs-operator">&gt;</span><span class="hljs-keyword">ON</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span> products <span class="hljs-operator">&lt;</span>span class<span class="hljs-operator">=</span>&quot;hljs-keyword&quot;<span class="hljs-operator">&gt;</span><span class="hljs-keyword">USING</span><span class="hljs-operator">&lt;</span><span class="hljs-operator">/</span>span<span class="hljs-operator">&gt;</span> GIN (search_vector);

Ventajas:

  • ACID compliant (transacciones confiables)
  • Tipos de datos avanzados (JSON, arrays, UUID)
  • Full-text search integrado
  • Extensiones potentes (PostGIS para mapas)
  • Performance excelente con tuning adecuado

MySQL/MariaDB: Compatibilidad universal

Cuándo sigue siendo buena opción:

  • Hosting compartido (disponibilidad universal)
  • Aplicaciones legacy
  • Casos de uso simples
  • Presupuesto muy ajustado

MongoDB: NoSQL para flexibilidad

Casos de uso específicos:

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment">// Schema flexible con Mongoose&lt;/span&gt;</span>
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>const<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> productSchema = <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>new<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Schema<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>({
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>name<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>String<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>,
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>price<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Number<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>,
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>attributes<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Schema<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>.&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-property&quot;</span>&gt;<span class="hljs-title class_">Types</span>&lt;<span class="hljs-regexp">/span&gt;.&lt;span class=&quot;hljs-property&quot;&gt;Mixed&lt;/</span>span&gt;,  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;</span>// Cualquier estructura<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>tags<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: [<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>String<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>],
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>reviews<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: [{
    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>user<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>String<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>,
    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>rating<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Number<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>,
    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>comment<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>String<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>,
    <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>date<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>: <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Date<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  }]
})

Cuándo usar MongoDB:

  • Schema altamente variable
  • Rapid prototyping
  • Logs y analytics
  • Datos semi-estructurados

Redis: Cache y datos en memoria

Imprescindible para performance:

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment">// Cache de queries costosas&lt;/span&gt;</span>
<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>async<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>function<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;</span>getUser<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>(<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-params&quot;</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-attr&quot;</span>&gt;</span>userId<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span>: <span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-built_in&quot;</span>&gt;</span>number<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>): <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>Promise<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>&amp;lt;<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-title class_&quot;</span>&gt;</span>User<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>&amp;gt; {
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;</span>// Intentar cache primero<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span>
  <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>const<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> cached = <span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;</span>await<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span> redis.&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-title function_&quot;</span>&gt;get&lt;<span class="hljs-regexp">/span&gt;(&lt;span class=&quot;hljs-string&quot;&gt;`user:&lt;span class=&quot;hljs-subst&quot;&gt;${userId}&lt;/</span>span&gt;<span class="hljs-string">`&lt;/span&gt;)
  &lt;span class=&quot;hljs-keyword&quot;&gt;if&lt;/span&gt; (cached) &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;hljs-title class_&quot;&gt;JSON&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;parse&lt;/span&gt;(cached)
  
  &lt;span class=&quot;hljs-comment&quot;&gt;// Si no está en cache, buscar en DB&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;const&lt;/span&gt; user = &lt;span class=&quot;hljs-keyword&quot;&gt;await&lt;/span&gt; db.&lt;span class=&quot;hljs-property&quot;&gt;users&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;findById&lt;/span&gt;(userId)
  
  &lt;span class=&quot;hljs-comment&quot;&gt;// Guardar en cache (TTL 1 hora)&lt;/span&gt;
  &lt;span class=&quot;hljs-keyword&quot;&gt;await&lt;/span&gt; redis.&lt;span class=&quot;hljs-title function_&quot;&gt;setex&lt;/span&gt;(
    &lt;span class=&quot;hljs-string&quot;&gt;`</span><span class="hljs-attr">user</span>:<span class="language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">span</span> <span class="hljs-attr">class</span>=<span class="hljs-string">&quot;hljs-subst&quot;</span>&gt;</span>${userId}<span class="hljs-tag">&lt;/<span class="hljs-name">span</span>&gt;</span></span><span class="hljs-string">`&lt;/span&gt;, 
    &lt;span class=&quot;hljs-number&quot;&gt;3600&lt;/span&gt;, 
    &lt;span class=&quot;hljs-title class_&quot;&gt;JSON&lt;/span&gt;.&lt;span class=&quot;hljs-title function_&quot;&gt;stringify&lt;/span&gt;(user)
  )
  
  &lt;span class=&quot;hljs-keyword&quot;&gt;return&lt;/span&gt; user
}</span>

Casos de uso:

  • Cache de queries frecuentes
  • Sessions de usuario
  • Rate limiting
  • Pub/sub para real-time
  • Queues de trabajos asíncronos

DevOps: De desarrollo a producción

Un programador web moderno debe saber deployar.

Docker: Entornos reproducibles

Containerización obligatoria:

&lt;span class=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment"># Dockerfile para Next.js app&lt;/span&gt;</span>
&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">FROM</span>&lt;/span&gt; node:&lt;span class=<span class="hljs-string">&quot;hljs-number&quot;</span>&gt;<span class="hljs-number">20</span>&lt;/span&gt;-alpine AS builder

&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">WORKDIR</span><span class="language-bash">&lt;/span&gt;&lt;span class=<span class="hljs-string">&quot;language-bash&quot;</span>&gt; /app&lt;/span&gt;</span>
&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">COPY</span><span class="language-bash">&lt;/span&gt;&lt;span class=<span class="hljs-string">&quot;language-bash&quot;</span>&gt; package*.json ./&lt;/span&gt;</span>
&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">RUN</span><span class="language-bash">&lt;/span&gt;&lt;span class=<span class="hljs-string">&quot;language-bash&quot;</span>&gt; npm ci&lt;/span&gt;</span>

&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">COPY</span><span class="language-bash">&lt;/span&gt;&lt;span class=<span class="hljs-string">&quot;language-bash&quot;</span>&gt; . .&lt;/span&gt;</span>
&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">RUN</span><span class="language-bash">&lt;/span&gt;&lt;span class=<span class="hljs-string">&quot;language-bash&quot;</span>&gt; npm run build&lt;/span&gt;</span>

&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">FROM</span>&lt;/span&gt; node:&lt;span class=<span class="hljs-string">&quot;hljs-number&quot;</span>&gt;<span class="hljs-number">20</span>&lt;/span&gt;-alpine AS runner
&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">WORKDIR</span><span class="language-bash">&lt;/span&gt;&lt;span class=<span class="hljs-string">&quot;language-bash&quot;</span>&gt; /app&lt;/span&gt;</span>

&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">COPY</span><span class="language-bash">&lt;/span&gt;&lt;span class=<span class="hljs-string">&quot;language-bash&quot;</span>&gt; --from=builder /app/next.config.js ./&lt;/span&gt;</span>
&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">COPY</span><span class="language-bash">&lt;/span&gt;&lt;span class=<span class="hljs-string">&quot;language-bash&quot;</span>&gt; --from=builder /app/public ./public&lt;/span&gt;</span>
&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">COPY</span><span class="language-bash">&lt;/span&gt;&lt;span class=<span class="hljs-string">&quot;language-bash&quot;</span>&gt; --from=builder /app/.next ./.next&lt;/span&gt;</span>
&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">COPY</span><span class="language-bash">&lt;/span&gt;&lt;span class=<span class="hljs-string">&quot;language-bash&quot;</span>&gt; --from=builder /app/node_modules ./node_modules&lt;/span&gt;</span>

&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">EXPOSE</span>&lt;/span&gt; &lt;span class=<span class="hljs-string">&quot;hljs-number&quot;</span>&gt;<span class="hljs-number">3000</span>&lt;/span&gt;
&lt;span class=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">CMD</span><span class="language-bash">&lt;/span&gt;&lt;span class=<span class="hljs-string">&quot;language-bash&quot;</span>&gt; [&lt;span class=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;&amp;quot;npm&amp;quot;&lt;/span&gt;, &lt;span class=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;&amp;quot;start&amp;quot;&lt;/span&gt;]&lt;/span&gt;</span>

Beneficios:

  • Entorno idéntico en dev, staging y prod
  • Despliegue consistente
  • Isolación de dependencias
  • Facilita CI/CD

CI/CD: Automatización de calidad

GitHub Actions ejemplo:

<span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-comment&quot;&gt;#</span> <span class="hljs-string">.github/workflows/test-and-deploy.yml&lt;/span&gt;</span>
<span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;Test&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;and&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;Deploy&lt;/span&gt;</span>

<span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;on:&lt;/span&gt;</span>
  <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;push:&lt;/span&gt;</span>
    <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;branches:&lt;/span&gt;</span> [<span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;main&lt;/span&gt;</span>]
  <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;pull_request:&lt;/span&gt;</span>
    <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;branches:&lt;/span&gt;</span> [<span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;main&lt;/span&gt;</span>]

<span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;jobs:&lt;/span&gt;</span>
  <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;test:&lt;/span&gt;</span>
    <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;runs-on:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;ubuntu-latest&lt;/span&gt;</span>
    <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;steps:&lt;/span&gt;</span>
      <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;uses:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;actions/checkout@v3&lt;/span&gt;</span>
      <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;uses:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;actions/setup-node@v3&lt;/span&gt;</span>
        <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;with:&lt;/span&gt;</span>
          <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;node-version:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;&amp;#x27;20&amp;#x27;&lt;/span&gt;</span>
      
      <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;run:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;npm&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;ci&lt;/span&gt;</span>
      <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;run:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;npm&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;run&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;lint&lt;/span&gt;</span>
      <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;run:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;npm&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;run&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;typecheck&lt;/span&gt;</span>
      <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;run:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;npm&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;run&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;test&lt;/span&gt;</span>
      <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;run:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;npm&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;run&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;build&lt;/span&gt;</span>
  
  <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;deploy:&lt;/span&gt;</span>
    <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;needs:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;test&lt;/span&gt;</span>
    <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;if:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;github.ref&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;==&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;&amp;#x27;refs/heads/main&amp;#x27;&lt;/span&gt;</span>
    <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;runs-on:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;ubuntu-latest&lt;/span&gt;</span>
    <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;steps:&lt;/span&gt;</span>
      <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;Deploy&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;to&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;production&lt;/span&gt;</span>
        <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;run:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;|&lt;/span&gt;</span>
          <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-comment&quot;&gt;#</span> <span class="hljs-string">Deploy</span> <span class="hljs-string">script</span> <span class="hljs-string">here&lt;/span&gt;</span>

Pipeline mínimo obligatorio:

  1. Linting (ESLint)
  2. Type checking (TypeScript)
  3. Tests (Jest, Vitest)
  4. Build (asegurar que compila)
  5. Deploy (solo si todo pasa)

Kubernetes: Orquestación para scale

Para aplicaciones que crecen:

<span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-comment&quot;&gt;#</span> <span class="hljs-string">deployment.yaml&lt;/span&gt;</span>
<span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;apiVersion:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;apps/v1&lt;/span&gt;</span>
<span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;kind:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;Deployment&lt;/span&gt;</span>
<span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;</span>
  <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;web-app&lt;/span&gt;</span>
<span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;</span>
  <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;replicas:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-number&quot;&gt;3&lt;/span&gt;</span>  <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-comment&quot;&gt;#</span> <span class="hljs-string">Alta</span> <span class="hljs-string">disponibilidad&lt;/span&gt;</span>
  <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;selector:&lt;/span&gt;</span>
    <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;matchLabels:&lt;/span&gt;</span>
      <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;web-app&lt;/span&gt;</span>
  <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;template:&lt;/span&gt;</span>
    <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;metadata:&lt;/span&gt;</span>
      <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;labels:&lt;/span&gt;</span>
        <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;app:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;web-app&lt;/span&gt;</span>
    <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;spec:&lt;/span&gt;</span>
      <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;containers:&lt;/span&gt;</span>
      <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;name:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;web-app&lt;/span&gt;</span>
        <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;image:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;myapp:latest&lt;/span&gt;</span>
        <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;ports:&lt;/span&gt;</span>
        <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-bullet&quot;&gt;-&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;containerPort:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-number&quot;&gt;3000&lt;/span&gt;</span>
        <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;resources:&lt;/span&gt;</span>
          <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;requests:&lt;/span&gt;</span>
            <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;memory:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;&amp;quot;256Mi&amp;quot;&lt;/span&gt;</span>
            <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;&amp;quot;250m&amp;quot;&lt;/span&gt;</span>
          <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;limits:&lt;/span&gt;</span>
            <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;memory:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;&amp;quot;512Mi&amp;quot;&lt;/span&gt;</span>
            <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-attr&quot;&gt;cpu:&lt;/span&gt;</span> <span class="hljs-string">&lt;span</span> <span class="hljs-string">class=&quot;hljs-string&quot;&gt;&amp;quot;500m&amp;quot;&lt;/span&gt;</span>

Cuándo introducir Kubernetes:

  • Múltiples microservicios
  • Necesitas auto-scaling
  • Alta disponibilidad crítica
  • Tráfico >10.000 usuarios/día

Para proyectos pequeños-medianos, Docker + VPS es suficiente.

Inteligencia Artificial: El diferenciador 2026

El programador web que ignora IA está obsoleto.

LangChain: Framework para apps con LLMs

Integración de IA generativa:

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">from</span>&lt;/span&gt; langchain.chat_models &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">import</span>&lt;/span&gt; ChatOpenAI
&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">from</span>&lt;/span&gt; langchain.chains &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">import</span>&lt;/span&gt; ConversationalRetrievalChain
&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">from</span>&lt;/span&gt; langchain.vectorstores &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-keyword&quot;</span>&gt;<span class="hljs-keyword">import</span>&lt;/span&gt; Chroma

&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-comment&quot;</span>&gt;<span class="hljs-comment"># Sistema RAG para chatbot con conocimiento empresarial&lt;/span&gt;</span>
llm = ChatOpenAI(model=&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;&amp;quot;gpt-<span class="hljs-number">4</span>&amp;quot;&lt;/span&gt;, temperature=&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-number&quot;</span>&gt;<span class="hljs-number">0</span>&lt;/span&gt;)

vectorstore = Chroma(
    persist_directory=&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;&amp;quot;./data/vectorstore&amp;quot;&lt;/span&gt;,
    embedding_function=OpenAIEmbeddings()
)

qa_chain = ConversationalRetrievalChain.from_llm(
    llm=llm,
    retriever=vectorstore.as_retriever(),
    return_source_documents=&lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-literal&quot;</span>&gt;<span class="hljs-literal">True</span>&lt;/span&gt;
)

response = qa_chain({
    &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;&amp;quot;question&amp;quot;&lt;/span&gt;: &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;&amp;quot;¿Cuál es nuestra política de devoluciones?&amp;quot;&lt;/span&gt;,
    &lt;span <span class="hljs-keyword">class</span>=<span class="hljs-string">&quot;hljs-string&quot;</span>&gt;&amp;quot;chat_history&amp;quot;&lt;/span&gt;: []
})

Uso LangChain en todos mis proyectos de IA, desde chatbots hasta sistemas RAG empresariales.

Modelos y APIs

Ecosistema actual:

  • OpenAI (GPT-4, GPT-4o): Calidad líder
  • Anthropic (Claude): Reasoning superior
  • Google (Gemini): Multimodal potente
  • Open source (Llama, Mistral): Control y privacidad

Casos de uso prácticos

  1. Chatbots inteligentes: Atención al cliente 24/7
  2. Sistemas RAG: Consultas sobre documentación
  3. Análisis de texto: Clasificación, sentiment, resumen
  4. Computer Vision: Detección de objetos, OCR
  5. Agentes autónomos: Automatización compleja

Mi stack personal como programador web

Después de 33 años, este es mi stack profesional:

Frontend

  • React + Next.js + TypeScript: 90% de proyectos
  • Tailwind CSS: Styling rápido y consistente
  • React Query: State management server
  • Zustand: State management cliente

Backend

  • Node.js + Express: APIs rápidas
  • Python + FastAPI: Proyectos con IA
  • PHP + Symfony: Clientes legacy

Databases

  • PostgreSQL: Default para datos relacionales
  • Redis: Cache y sessions
  • MongoDB: Casos específicos

DevOps

  • Docker: Todos los proyectos
  • GitHub Actions: CI/CD
  • OVH VPS: Hosting confiable y económico

AI/ML

  • LangChain: Framework principal
  • OpenAI API: GPT-4 para calidad
  • Pinecone: Vector database
  • Hugging Face: Modelos open source

Herramientas de desarrollo

Editor: VSCode con extensiones:

  • ESLint, Prettier (formatting automático)
  • TypeScript + Pylance (type checking)
  • GitHub Copilot (productividad)
  • Thunder Client (testing APIs)

Terminal: Zsh con Oh My Zsh Git UI: GitKraken o Sourcetree Database UI: DBeaver o TablePlus REST client: Insomnia o Thunder Client

Cómo aprender el stack moderno

Roadmap sugerido para aspirantes a programador web:

  1. Fundamentos (2-3 meses)

    • HTML, CSS, JavaScript sólidos
    • Git y control de versiones
    • Command line básico
  2. Frontend moderno (3-4 meses)

    • React con hooks
    • TypeScript
    • Next.js
    • Tailwind CSS
  3. Backend y APIs (3-4 meses)

    • Node.js o Python
    • REST APIs
    • PostgreSQL
    • Authentication/Authorization
  4. DevOps básico (2-3 meses)

    • Docker
    • CI/CD con GitHub Actions
    • Deployment (Vercel, Railway, VPS)
  5. Testing (continuamente)

    • Jest/Vitest
    • React Testing Library
    • E2E con Playwright
  6. IA (opcional pero recomendado)

    • LangChain basics
    • OpenAI API
    • RAG systems

Total: 12-18 meses para ser programador web competente

Con dedicación, práctica y proyectos reales.

Conclusión: Stack al servicio del negocio

El stack tecnológico no es un fin en sí mismo. Es medio para:

  • Resolver problemas de negocio
  • Crear valor para usuarios
  • Mantener código a largo plazo
  • Iterar rápido sobre feedback

Los mejores programadores web:

  • Eligen tecnologías por razones válidas, no por hype
  • Balancean modernidad con estabilidad
  • Priorizan DX para productividad
  • Nunca dejan de aprender

Con 33 años de experiencia, he visto docenas de tecnologías ir y venir. Lo que permanece:

  • Fundamentos sólidos (algoritmos, arquitectura, patterns)
  • Calidad no negociable (TDD, code review, docs)
  • Pragmatismo (usa tecnología apropiada, no la más cool)
  • Aprendizaje continuo (el día que dejas de aprender, estás obsoleto)

¿Necesitas ayuda con tu proyecto? Ya sea web profesional, ecommerce, plataforma SaaS o aplicación con IA, mi stack moderno y experiencia están a tu servicio.

Presupuesto detallado en menos de 24h.


Jordi Morillo - Programador Web | Ver mi stack completo | TDD obligatorio | Garantía de por vida