↑ top
← Back to blog
EN | ES

Por Qué No Usé un Framework (Y Lo Que Realmente Me Costó)

Sin Next.js, sin Astro, sin Hono. Solo un archivo JavaScript de 1600 líneas. Un balance honesto de los tradeoffs.

✦ AI Summary

Cloudflare Workers no es Node.js. No es un navegador. Es un aislado V8 con un subconjunto de las APIs de the Web Platform. No aprendes lo que puede hacer la plataforma.

Por Qué No Usé un Framework (Y Lo Que Realmente Me Costó)

Cuando empecé a construir este sitio, tomé una decisión deliberada: sin framework. Sin Next.js, sin Astro, sin Remix. Ni siquiera una librería de routing ligera como Hono o Itty Router.

Un archivo. Un punto de entrada. Todo en src/worker.js.

Ese archivo ahora tiene 1600 líneas.

Esto es lo que gané, lo que perdí, y si tomaría la misma decisión de nuevo.

Por Qué Sin Framework

La razón principal: quería entender la plataforma.

Cloudflare Workers no es Node.js. No es un navegador. Es un aislado V8 con un subconjunto de las APIs de la Web Platform y un conjunto de bindings específicos de Cloudflare. Si pones un framework encima, aprendes las abstracciones del framework. No aprendes lo que puede hacer la plataforma.

La razón secundaria: los pasos de build añaden fricción.

Un framework como Astro o Next.js requiere un paso de build para compilar templates, empaquetar assets y generar salida estática. Eso significa una herramienta de build, un archivo de configuración, un paso de CI, y un entorno local que coincida con CI. Para un sitio personal con un puñado de rutas, esto se sentía como un costo alto para un beneficio pequeño.

Qué Obtuve

Cero dependencias en runtime. El worker se despliega como un único archivo JS. No hay nada que instalar, nada que empaquetar, nada que pueda romperse porque una dependencia publicó una actualización mala.

Visibilidad completa. Cada petición pasa por código que escribí y puedo leer. Cuando algo se rompe, miro worker.js. No hay internos de framework por los que rastrear.

Bundle pequeño. El script del worker está muy por debajo del límite de 1MB de Cloudflare, con amplio margen. Un framework añade código muerto incluso cuando configuras tree-shaking.

Cold starts rápidos. Los Workers arrancan en microsegundos en parte porque hay menos código que parsear.

Lo Que Realmente Costó

1600 líneas de código que hace todo. Routing, renderizado, CSS, JavaScript, acceso a KV, consultas D1, lecturas de R2, syntax highlighting, extracción de tabla de contenidos, generación de tags OG — todo en un archivo. Un colaborador nuevo necesitaría leer todo para entender la estructura.

Template literals como motor de plantillas. El HTML se construye concatenando strings en template literals. No hay verificación de tipos en props, ni aislamiento de componentes, ni renderizado basado en diff. Un typo en un nombre de clase falla silenciosamente. Añadir un nuevo elemento de diseño significa encontrar el string correcto en la función correcta y editar con cuidado.

javascriptfunction blogCardHTML(post, i) {
  return `<article class="blog-card ${i === 0 ? 'blog-card-featured' : ''}">
    <div class="blog-card-body">
      <h2 class="blog-card-title">${escapeHtml(post.title)}</h2>
      ...
    </div>
  </article>`;
}

Funciona. No es agradable de mantener a escala.

Sin hot reload. wrangler dev recarga al guardar el archivo, pero es un reinicio completo, no HMR. Para cambios de CSS, recargas el navegador y esperas ~1 segundo. Está bien. No es el feedback loop instantáneo que obtienes con Vite.

Escribí mucho código que no necesitaba escribir. El syntax highlighter son ~60 líneas. Un extractor de ToC. Una configuración del renderer de Markdown. Un escapador de HTML. Todos existen como librerías. Los escribí de todas formas.

El Tradeoff Real

La elección de no-framework tuvo sentido para este proyecto en esta escala. Un sitio personal con 10 rutas, un desarrollador, y sin necesidad de paso de build.

El archivo de 1600 líneas no es un problema ahora mismo. Lo sería con un segundo desarrollador, un design system con muchos componentes, o un número significativamente mayor de rutas.

Los frameworks existen porque los equipos descubrieron que las abstracciones compartidas se pagan solas a cierta escala. La pregunta interesante es: ¿a qué escala? Para la mayoría de proyectos, es más baja de lo que la gente asume. Para el mío, aún no la he cruzado.

La respuesta que le daría a alguien empezando hoy: usa un router ligero (Hono son 14KB y es excelente) y mantén tus templates en template literals si quieres. Salta el paso de build. Llega a un framework cuando la codebase te diga que lo necesita — cuando estés copiando código de layout por tercera vez o cuando el primer colaborador se pierda.

No empieces con complejidad que no te has ganado.

Was this helpful?