Next.js su Cloudflare Workers: OpenNext, vinext e quando restare su Vercel

Cloudflare ora consiglia vinext al posto di OpenNext per Next.js su Workers. Cosa supportano i due adapter, i buchi dichiarati, la cache ISR che su Workers configuri tu e i casi in cui Vercel resta la scelta onesta, dalla documentazione ufficiale.

Francesco Pio Nocerino8 minCloudflare
Next.js su Cloudflare Workers: OpenNext, vinext e quando restare su Vercel
Indice

Questo pezzo è per chi ha un'app Next.js, magari generata da un agente, e vuole farla girare su Cloudflare Workers invece che su Vercel. Non è il racconto di una migrazione: è un confronto costruito sulla documentazione ufficiale di Cloudflare, OpenNext, vinext e Next.js, letta il 24 ottobre 2026.

Le versioni di riferimento su npm, lo stesso giorno: next 16.4.3, @opennextjs/cloudflare 1.20.13, vinext 1.3.0, @vinext/cloudflare 1.2.0, wrangler 4.152.0.

In breve:

  • Cloudflare oggi raccomanda vinext, non OpenNext, come strada predefinita per Next.js su Workers. OpenNext resta documentato per le app che lo usano già.
  • OpenNext prende l'output di next build e lo adatta a Workers. vinext reimplementa l'API di Next.js sopra Vite. Sono due scommesse diverse sulla compatibilità.
  • Con OpenNext funziona quasi tutto, tranne il middleware con runtime Node.js e il runtime edge. Il prezzo è la cache: ISR e revalidation chiedono R2, una coda su Durable Objects e una tag cache.
  • vinext è in beta. Secondo il suo README copre circa il 94% dell'API di Next.js 16, con buchi noti su immagini in build, moduli nativi in sviluppo e Cache Components.
  • Next.js dichiara il supporto completo solo per server Node.js e Docker. Gli adapter verificati oggi sono Vercel e Bun; quelli di Cloudflare non lo sono ancora.
  • Se la tua app usa le funzioni più nuove di Next.js e non hai tempo per fare da integratore, Vercel resta la scelta onesta.

La novità: Cloudflare ora consiglia vinext

La guida Next.js di Cloudflare Workers è cambiata. Apre così: Cloudflare raccomanda vinext come modo predefinito per eseguire applicazioni Next.js su Workers. La pagina dell'adapter OpenNext, aggiornata il 12 ottobre 2026, conferma: OpenNext serve per mantenere un'app esistente, e la migrazione a vinext è consigliata quando la compatibilità lo permette.

Cambiano anche i comandi. Secondo la guida Cloudflare, npm create cloudflare@latest -- my-next-app --framework=next crea un progetto già configurato con vinext. Anche la configurazione automatica di Wrangler usa vinext per i progetti Next.js. Per usare OpenNext ora si configura l'adapter a mano.

Quindi la domanda del titolo va riformulata. Non "OpenNext funziona?". È: la tua app sta meglio su un adapter che traduce l'output di Next.js, su una reimplementazione di Next.js, o sulla piattaforma per cui Next.js è pensato?

OpenNext e vinext non fanno la stessa cosa

OpenNext lavora dopo il build. Il comando opennextjs-cloudflare build lancia lo script build del tuo package.json, cioè next build, poi trasforma l'output in un Worker che Wrangler può servire in locale e deployare. Il compilatore resta quello di Next.js. L'app deve usare il runtime Node.js di Next.js, non quello edge.

vinext parte da un'altra idea. Il README lo descrive come un plugin Vite che reimplementa l'API di Next.js, invece di consumare l'output di next build. Le cartelle app/, pages/, public/ e next.config.js restano dove sono. Cambia la toolchain sotto.

La conseguenza pratica è questa. Con OpenNext un bug di compatibilità nasce di solito nella traduzione dell'output. Con vinext nasce in una parte di Next.js non ancora reimplementata, o reimplementata in modo diverso. Il README di vinext lo dice in chiaro: punta alla compatibilità pragmatica, non alla parità bug per bug. I casi che dipendono da comportamenti non documentati di Vercel sono esclusi apposta.

Cosa funziona con OpenNext, e cosa no

La tabella della pagina Cloudflare su OpenNext elenca come supportati App Router, Pages Router, Route Handlers, React Server Components, SSG, SSR, ISR, Server Actions, streaming, next/after e middleware. L'ottimizzazione delle immagini passa da Cloudflare Images. Partial Prerendering e "use cache" sono supportati, con la nota che in Next.js sono sperimentali.

I buchi dichiarati sono pochi, ma vanno controllati prima di partire:

  • Middleware con runtime Node.js. Introdotto in Next.js 15.2, non è ancora supportato.
  • Runtime edge. La guida di OpenNext chiede di rimuovere ogni export const runtime = "edge" prima del deploy.
  • Versioni. Supportate tutte le minor di Next.js 16 e le ultime minor di 14 e 15. Il supporto a 14 è in uscita.
  • Windows. Si può usare, ma il supporto completo non è garantito. La documentazione consiglia WSL, una VM Linux o il build in CI.

Per un'app esistente il punto di partenza documentato è un comando:

npx @opennextjs/cloudflare migrate

Secondo la guida, migrate automatizza i passaggi manuali: dipendenze, wrangler.jsonc, open-next.config.ts, script nel package.json. Se R2 è attivo sull'account crea anche un bucket per la cache. Nella configurazione servono il flag nodejs_compat e una compatibility_date dal 2024-09-23 in poi.

Il costo vero di OpenNext è la cache

Un'app solo SSR funziona senza configurare niente. La pagina sul caching di OpenNext lo precisa: tutto il resto riguarda SSG, ISR e la data cache. Ed è lì che Next.js su Workers smette di essere "un deploy".

Per un sito piccolo che usa la revalidation, la configurazione consigliata ha tre pezzi:

  • una incremental cache su R2, con il binding NEXT_INC_CACHE_R2_BUCKET
  • una coda su Durable Objects (DOQueueHandler), obbligatoria se usi la revalidation a tempo
  • una tag cache su D1 (NEXT_TAG_CACHE_D1), solo se usi revalidateTag o revalidatePath

Serve anche un service binding del Worker verso se stesso, WORKER_SELF_REFERENCE. Per siti più grandi la documentazione suggerisce di passare a una tag cache su Durable Objects divisa in shard. Workers KV è possibile, ma OpenNext non lo consiglia perché è eventualmente consistente.

La configurazione minima con R2 e coda:

// open-next.config.ts
import { defineCloudflareConfig } from "@opennextjs/cloudflare";
import r2IncrementalCache from "@opennextjs/cloudflare/overrides/incremental-cache/r2-incremental-cache";
import doQueue from "@opennextjs/cloudflare/overrides/queue/do-queue";

export default defineCloudflareConfig({
  incrementalCache: r2IncrementalCache,
  queue: doQueue,
});

Due dettagli che un agente salta spesso. Il primo: il Worker non sta davanti agli asset statici, quindi gli headers di next.config.ts non valgono per public/ e _next/static. La documentazione chiede di aggiungere a mano in public/_headers la cache immutabile per /_next/static/*. Il secondo: la cache va inizializzata a ogni deploy, e la documentazione affida questo passaggio ai comandi deploy e upload dell'adapter. Nella pipeline vanno usati quelli.

Su Vercel niente di questo è configurazione tua. Su Workers sono bucket, Durable Objects e un database da tenere in ordine. Se ISR non ti serve, il problema non esiste. Se ti serve, mettilo nel conto prima di scegliere.

vinext: cosa copre e dove si ferma

La guida Cloudflare elenca per vinext lo stesso perimetro di base: App Router, Pages Router, RSC, Server Actions, SSR in streaming, export statico, ISR con modello stale-while-revalidate, middleware.ts e proxy.ts. I binding si leggono da cloudflare:workers nei server component, nei route handler e nelle server action. L'ottimizzazione immagini è parziale: avviene al momento della richiesta.

Il README di vinext è più esplicito sui limiti:

  • È in beta. Si può usare in produzione "con cautela", e non è ancora stato messo alla prova su tutta la varietà di carichi Next.js.
  • Copertura. Circa il 94% dell'API di Next.js 16 ha supporto completo o parziale. Mancano Partial Prerendering e il comportamento completo di cacheComponents.
  • Immagini e font. Niente pipeline di ottimizzazione in build come quella di Next.js. next/image usa <img> con srcSet per le immagini locali.
  • Moduli nativi in sviluppo. sharp, satori, resvg, lightningcss possono fallire nell'ambiente RSC di Vite in dev. In build va meglio.
  • Configurazioni di piattaforma. preferredRegion viene ignorato, e runtime non decide dove gira una route.
  • Funzioni Vercel. Analytics, KV, Blob e Postgres di Vercel non sono supportati e non lo saranno: si usano gli equivalenti della piattaforma.

Il primo comando, prima di qualsiasi migrazione, è il controllo di compatibilità:

npx vinext check

Se il report è pulito, npx vinext init aggiunge vinext senza toccare il setup esistente: next dev continua a funzionare e puoi confrontare i due build. Il deploy passa da npx @vinext/cloudflare deploy.

I limiti di Workers che pesano su Next.js

Qualunque adapter scegli, il Worker vive dentro i limiti della piattaforma. Per un'app Next.js contano soprattutto quattro voci:

  • Dimensione: 64 MiB non compressi, sia Free sia Paid. Secondo la pagina Cloudflare non esiste più un limite sulla dimensione compressa.
  • CPU per richiesta: 10 ms sul piano Free. Sul Paid il default è 30 secondi, alzabile fino a 5 minuti.
  • Memoria: 128 MB.
  • Avvio: 1 secondo per il Worker startup time.

La pagina di OpenNext cita ancora 3 MiB su Free e 10 MiB su Paid, misurati sulla dimensione compressa. Sono i limiti di prima. Per i numeri fa fede la pagina dei limiti di Cloudflare.

I 10 ms di CPU sono il vincolo che morde davvero. La stessa pagina indica che i carichi con rendering lato server usano in genere 10-20 ms per richiesta. Un'app Next.js con SSR sul piano Free rischia di finire fuori limite. Per un progetto vero, conta di partire dal piano Paid.

OpenNext, vinext o Vercel: il confronto

OpenNext su Workers

vinext su Workers

Vercel

Come funziona

Adatta l'output di next build

Reimplementa l'API Next.js su Vite

Adapter verificato da Next.js

Stato per Cloudflare

Per app esistenti

Strada consigliata, in beta

n/a

ISR e revalidation

R2, coda DO e tag cache da configurare

Cache handler da configurare (KV o cache CDN)

Gestite dalla piattaforma

Buchi noti

Middleware Node.js, runtime edge

PPR, cacheComponents completo, immagini in build

Gira la suite di test completa di Next.js

Binding Cloudflare

Sì, con getCloudflareContext

Sì, da cloudflare:workers

No

Quando restare su Vercel è la scelta onesta

La documentazione di deploy di Next.js mette le cose in ordine. Server Node.js e container Docker supportano tutte le funzioni. Gli adapter hanno un supporto "variabile". Gli adapter verificati, che girano l'intera suite di test di compatibilità di Next.js, oggi sono due: Vercel e Bun. Cloudflare e Netlify stanno lavorando ad adapter verificati sulla Deployment Adapter API; nel frattempo le loro integrazioni non sono costruite su quell'API e non sono verificate dal team di Next.js.

Da qui tre casi in cui Vercel, o un server Node.js su un VPS, resta più sensato di Workers:

  • Usi le funzioni più nuove di Next.js. Partial Prerendering, Cache Components, middleware Node.js. Sono esattamente i punti dove OpenNext e vinext dichiarano buchi o supporto parziale.
  • Il tempo per fare da integratore non c'è. Su Workers la cache ISR è infrastruttura tua. Tempo umano è costo, e va messo accanto alla bolletta.
  • Dipendi da servizi Vercel. Se l'app usa Vercel Blob, KV o Analytics, spostarla vuol dire riscrivere quelle parti, non cambiare adapter.

Il caso opposto è altrettanto chiaro. Se il resto del progetto vive già su Cloudflare, con D1, R2 e Durable Objects, Next.js su Workers ti dà i binding direttamente nel codice server. È lo scenario del confronto Vercel vs Cloudflare vs VPS per un prodotto indie: il vincolo che decide è il lock-in, non il prezzo di partenza. Lo stack Workers + D1 + R2 spiega quando quella base conviene.

Se Next.js te l'ha scelto l'agente

Molte app Next.js nascono perché è lo stack che il modello propone per primo. Ne parla la trappola dello stack di default. Prima di adattare Next.js a Workers, vale la pena chiedersi se ti serve Next.js. Un sito di contenuti spesso sta meglio su Astro, e la guida per migrare un sito Astro da Pages a Workers copre quel percorso.

Se invece Next.js resta, metti le regole del deploy nel file di contesto del progetto. Un paragrafo in AGENTS.md o CLAUDE.md evita che l'agente rimetta runtime = "edge" in una route, o deployi senza passare dai comandi dell'adapter che inizializzano la cache.

Cosa conviene fare adesso

  • Lancia npx vinext check sull'app, anche se pensi di usare OpenNext. Il report ti dice quanto sei lontano dalla strada che Cloudflare consiglia.
  • Cerca nel codice runtime = "edge", middleware con runtime Node.js, cacheComponents e PPR. Sono i punti dove i due adapter si fermano.
  • Fai l'elenco di dove usi ISR, revalidateTag e revalidatePath. Se la lista è vuota, la parte difficile di OpenNext non ti riguarda.
  • Controlla le dipendenze da servizi Vercel. Ognuna è una riscrittura, non una configurazione.
  • Prova il build in locale con opennextjs-cloudflare preview o npm run dev:vinext prima di toccare il dominio.

Next.js su Workers oggi funziona per molte app. Non è però un deploy senza pensieri come su Vercel: la parte che Vercel ti nasconde, su Cloudflare la configuri tu.

[ DOMANDE FREQUENTI ]

Domande frequenti

01OpenNext è deprecato?

No. Cloudflare continua a documentarlo e il pacchetto @opennextjs/cloudflare riceve rilasci: la versione 1.20.13 è del 21 ottobre 2026. Per le nuove app Cloudflare consiglia vinext, e indica OpenNext per le app esistenti che non possono ancora migrare per un buco di compatibilità.

02Posso usare runtime = "edge" con OpenNext?

No. La guida di OpenNext chiede di rimuovere export const runtime = "edge" da tutti i file prima del deploy, perché il runtime edge non è supportato. L'adapter usa il runtime Node.js di Next.js, che su Workers si appoggia al flag nodejs_compat.

03Che fine ha fatto @cloudflare/next-on-pages?

La documentazione di OpenNext lo tratta come la strada precedente: supportava solo il runtime edge. La guida spiega come rimuoverlo e sostituire getRequestContext con getCloudflareContext. Per un'app statica Cloudflare documenta ancora il deploy su Pages, ma solo per l'export statico.

04Next.js su Workers costa meno che su Vercel?

Dipende dal traffico e da cosa usi, e questo pezzo non confronta listini. Il conto va fatto su due voci. La prima è il piano: con 10 ms di CPU il Free è stretto per l'SSR. La seconda sono le risorse della cache ISR, cioè R2, Durable Objects e D1, che su Workers paghi e gestisci tu.

Condividi