wandres.dev
ADAPTERS · Node, Cloudflare, Vercel

Adapters de edge y serverless

Desplegar Astro sin gestionar una máquina: los adapters de Vercel, Netlify y Cloudflare. La diferencia profunda no es el proveedor sino el runtime, funciones serverless sobre Node frente a runtimes de edge sobre APIs web (workerd y Deno), donde no hay fs ni process ni módulos nativos. Las palancas que desplazan trabajo entre la función y el edge, y por qué el motor de Astro, escrito sobre estándares web, hace posibles todos estos destinos a la vez.

⏱ 16 min

Más allá de tu propio servidor Node, las grandes plataformas —Vercel, Netlify, Cloudflare— ejecutan tu código bajo demanda sin que tú administres ninguna máquina. Cada una tiene su adapter oficial, pero la diferencia más honda no está en el nombre del proveedor: está en el runtime. Las funciones serverless de Vercel y Netlify corren sobre Node, con toda su API a mano. Los runtimes de edge —los Workers de Cloudflare, el edge de Vercel, las funciones de edge de Netlify— corren sobre APIs estándar de la web, en workerd o en Deno, donde no existen fs, ni process, ni los módulos nativos de Node. Esa frontera de runtime, y no la marca comercial, decide qué puede hacer tu código y cómo debes escribirlo.

🎯 Al terminar esta lección sabrás
  • Distinguir el despliegue serverless (funciones Node) del de edge (runtime web).
  • Instalar @astrojs/vercel, @astrojs/netlify o @astrojs/cloudflare.
  • Entender por qué el edge exige APIs web y veta los módulos nativos de Node.
  • Usar las palancas del adapter para desplazar trabajo entre la función y el edge.

Serverless: funciones Node bajo demanda

El modelo serverless empaqueta tu código en funciones que la plataforma invoca cuando llega una petición y descarta cuando termina. No hay servidor que administrar: escala a cero cuando nadie visita y se multiplica solo bajo carga. Los adapters de Vercel y Netlify producen, por defecto, funciones sobre el runtime Node, así que dispones de casi toda su API —incluidos módulos nativos como Sharp— con las salvedades propias de un sistema de ficheros efímero y de solo lectura.

npx astro add vercel
# o
npx astro add netlify
import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel';

export default defineConfig({
  output: 'server',
  adapter: vercel(),
});

El precio de esa comodidad es el cold start: cuando una función lleva rato dormida, la primera petición paga el arranque del entorno antes de responder. A cambio, no mantienes ni parcheas nada, y solo pagas por invocación. Estos adapters añaden además capacidades propias de la plataforma —renderizado incremental, optimización de imágenes, analíticas— que activas por opciones, sin salir de tu proyecto.

📝
El sistema de ficheros efímero cambia cómo guardas cosas

En una función serverless el disco es efímero y a menudo de solo lectura: lo que escribas en una invocación puede no existir en la siguiente, porque cada una puede correr en una instancia recién nacida. No guardes ahí estado que deba persistir —subidas de usuarios, cachés, sesiones—; envíalo a un almacén externo, un bucket, una base de datos o un KV. Asumir un disco estable, un reflejo heredado del servidor de larga vida, es una fuente clásica de errores intermitentes al mudar a serverless.

Edge: el runtime web, sin Node debajo

El edge lleva el cómputo a decenas de ubicaciones cercanas al usuario y lo ejecuta en un runtime distinto: no Node, sino un motor construido sobre los estándares de la web. Cloudflare corre en workerd; el edge de Vercel y Netlify, en variantes basadas en Deno y en Web APIs. Ahí dispones de fetch, Request, Response, URL, crypto.subtle y los Web Streams —pero no de fs, ni del process completo, ni de complementos nativos compilados—.

npx astro add cloudflare
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  output: 'server',
  adapter: cloudflare(),
});
🟩

Runtime Node

Serverless en Vercel y Netlify. API completa de Node, módulos nativos, sistema de ficheros efímero. Cold start notable.

Runtime de edge

Cloudflare Workers, Deno. Solo APIs web, sin fs ni process ni nativos. Cold start casi nulo y cercanía global.

🧩

El motor no cambia

Astro habla Request y Response en ambos. El adapter absorbe la diferencia del destino, no tu código.

🚫

La frontera del edge

Si dependes de fs, de un binario nativo o de mucha CPU, el edge te rechaza. Es un límite de runtime, no un capricho.

⚠️
El error clásico: un módulo nativo en el edge

El fallo más común al mudar al edge es arrastrar una dependencia que asume Node —un cliente de base de datos con binario nativo, una librería que lee del disco, un uso de process—. En Node funciona; en workerd revienta en el build o en la primera petición. La regla mental es simple: en el edge, si no forma parte de la plataforma web, probablemente no está. Cloudflare ofrece una bandera de compatibilidad con Node que rellena algunos huecos, pero no la asumas como una red de seguridad universal.

💡
Más allá de los tres grandes

Node, Vercel, Netlify y Cloudflare son los adapters oficiales, pero no los únicos destinos posibles. La comunidad mantiene adapters para Deno Deploy y otros runtimes, y como todos hablan el mismo contrato de Request y Response, encajan en el mismo hueco de la configuración. Elegir un destino menos común no cambia cómo escribes tus páginas; solo cambia el paquete que registras en adapter.

Un proveedor, varias palancas de runtime

Vercel y Netlify no son un único runtime monolítico: sus adapters exponen opciones que desplazan trabajo entre la función Node y el edge, para que ajustes dónde ocurre cada cosa sin cambiar de proveedor. Dos palancas concentran casi todo. edgeMiddleware mueve tu middleware de Astro al edge, donde corre antes de que la petición llegue a la función —perfecto para autenticación, redirecciones o geolocalización con latencia mínima—. Y isr, el renderizado estático incremental, cachea la salida de una ruta bajo demanda para servir la mayoría de las visitas como si fueran estáticas, recomputando solo cuando el caché expira.

import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel';

export default defineConfig({
  output: 'server',
  adapter: vercel({
    edgeMiddleware: true,        // el middleware corre en el edge
    isr: { expiration: 60 },     // cachea la salida bajo demanda 60 s
  }),
});

Netlify expone las mismas ideas con su propia forma, prueba de que estas palancas son un patrón del ecosistema y no un truco de un solo proveedor:

import { defineConfig } from 'astro/config';
import netlify from '@astrojs/netlify';

export default defineConfig({
  output: 'server',
  adapter: netlify({ edgeMiddleware: true }),
});
📝
ISR difumina la frontera entre estático y dinámico

El renderizado incremental es un híbrido astuto: una ruta bajo demanda que, tras la primera visita, se sirve desde caché como un fichero estático hasta que caduca. Consigues frescura sin pagar cómputo en cada petición, y controlas el equilibrio con el tiempo de expiración. Es la prueba de que estático y dinámico no son dos cajones cerrados, sino los extremos de un dial que estas plataformas te dejan girar por ruta.

Un mismo motor, muchos destinos

Lo asombroso de esta variedad es que tu proyecto no cambia al elegir uno u otro. La misma página que se renderiza en tu Node local se renderiza en una función serverless de Vercel o en un Worker de Cloudflare, porque en los tres casos el motor recibe un Request y devuelve un Response. El adapter absorbe todo lo que difiere entre destinos; tu código habla el idioma común.

flowchart TD
APP[motor de Astro sobre Request y Response] --> NODE[adapter node]
APP --> VER[adapter vercel]
APP --> NET[adapter netlify]
APP --> CF[adapter cloudflare]
NODE --> SRV[servidor node propio]
VER --> FN[funciones serverless o edge]
NET --> FN2[funciones o edge de netlify]
CF --> WK[workers en el edge]
style APP fill:#89b4fa,color:#11111b
style WK fill:#a6e3a1,color:#11111b
El edge es el regreso de la web a sus propios estándares

Durante quince años, escribir servidor en JavaScript significó escribir para Node, y Node significó una API propia —fs, process, Buffer, sus streams— que se convirtió, por pura ubicuidad, en sinónimo de lo que se podía hacer en el servidor. El auge del edge deshace ese equívoco y revela una verdad que estaba tapada: la API de Node nunca fue el estándar del servidor, solo el más extendido. Los runtimes de edge no inventan un dialecto nuevo; regresan al que ya existía en cada navegador —fetch, Request, Response, URL, crypto.subtle, los Web Streams— y lo llevan al lado del servidor. Cuando tu código de Cloudflare usa fetch para llamar a una API y crypto.subtle para firmar un token, está usando exactamente las mismas primitivas que un frontend en un navegador. Esa convergencia es profunda: significa que el conocimiento deja de estar atado a un runtime y pasa a estar atado a la plataforma web, que es para siempre y está en todas partes. Astro tomó partido por ese lado de la historia antes de que fuera evidente: al escribir su motor contra Request y Response en lugar de contra Node, se hizo desplegable en el edge sin reescribir nada el día que el edge maduró. La lección para ti como ingeniero es estratégica, no táctica: cuando dos capas compiten por ser el estándar —la API cómoda y omnipresente de hoy frente a la especificación abierta y portable—, apostar por la especificación es apostar por tu propia movilidad futura. El código que escribes contra Web APIs corre en Node, en Deno, en Bun, en el edge y en el navegador; el que escribes contra la API privada de un runtime corre solo donde ese runtime esté. El edge no es una moda de despliegue: es la señal de que la plataforma web ganó también el servidor, y de que aprender sus estándares es la inversión que nunca caduca.

⚔️ Explora la frontera de los runtimes
  1. Instala @astrojs/vercel en un proyecto de prueba y despliega una ruta bajo demanda que lea la fecha del servidor.
  2. Activa isr con una expiración corta y observa cómo la misma ruta se sirve casi siempre desde caché.
  3. Añade el adapter @astrojs/cloudflare en otra rama y anota qué dependencias del proyecto dejarían de compilar en workerd.
  4. Escribe una función que use solo fetch y crypto.subtle, comprueba que corre igual en Node y en el edge, y enumera tres capacidades que tengas en Node y no allí.