Lo scenario
00Cosa è cambiato in Next 16
Next.js 16 è arrivato e quando il codice è “vibe” può capitare che certe parti facciano riferimento a delle vecchie istanze del framework.
Next 16:
Le tre cose che cambiano davvero il modo in cui scrivi codice ogni giorno sono il nuovo modello di caching, il rendering ibrido di default e la ridenominazione del middleware.
Il cambio di mentalita piu grande e questo: in Next 16 il caching e opt-in. Nelle versioni precedenti l’App Router cachava automaticamente. Oggi, di default, tutto e dinamico finchè non chiedi esplicitamente use cache.
Sul fronte performance, Turbopack e ora il bundler di default e stabile sia in sviluppo che in produzione. La 16.2 accelera ulteriormente il dev server. Runtime minimo Node.js 20+ e React 19.2.
Facendo ormai il tanto amato vibe coding oppure affidandosi troppo alle intelligenze artificiali per la stesura del codice, può spesso capitare che esse facciano riferimento ad una nuova versione di Next, per questo lascio in questa lista, che è un reminder anche per me, quelle 10 cose che secondo me sono sempre da tenere sotto controllo.
Caching
01Cache Components & use cache
I Cache Components sono il cuore di Next 16: tu decidi cosa cachare marcando pagina, componente o funzione con 'use cache'.
Per attivare il modello, accendi il flag in config. Da quel momento ogni codice dinamico gira a ogni richiesta, a meno che non venga cachato.
La direttiva funziona a tre livelli (file, componente, funzione). A livello funzione ottieni controllo granulare e pratico.
Tre funzioni accompagnano la direttiva: cacheLife() (freschezza), cacheTag() (invalidazione mirata) e revalidateTag() (butta via le entry col tag).
Sicurezza della cache
02Mai cache condivisa sui dati utente
La 'use cache' normale crea una cache condivisa: il risultato calcolato per un utente puo essere servito ad altri.
La soluzione e esplicita: 'use cache: private' per isolare le entry per sessione utente.
Rendering
03Shell statico, dati in streaming
Con Cache Components, la Partial Prerendering diventa il comportamento di default. Non devi piu scegliere tra tutta statica o tutta dinamica.
Next pre-renderizza uno shell statico e streamma le parti dinamiche in <Suspense> man mano che sono pronte.
Il fallback non è estetica: e quello che l utente vede mentre arrivano i dati. Uno skeleton fatto bene riduce CLS e migliora la percezione di velocità.
Data fetching
04Carica i dati sul server, in parallelo
Nell’App Router i componenti sono Server Components di default: fetch vicino a dove servono i dati, niente useEffect + useState per caricare dati pagina.
Errore comune: waterfall sequenziale. Se le chiamate sono indipendenti, usa Promise.all.
Se una delle due chiamate è lenta ma non blocca il resto della pagina, non aspettarla nel componente: spostala in un sotto-componente avvolto in <Suspense> e lasciala streammare. Server Components per i dati, Suspense per i pezzi lenti: e la combinazione che tiene le pagine reattive.
Proxy (ex middleware)
05proxy.ts
In Next 16 middleware.ts diventa proxy.ts. La funzione esportata si chiama proxy e resta utile per redirect, rewrite e header.
Due dettagli pratici della migrazione: il proxy gira solo sul runtime Node.js — l’edge non è supportato. E i flag con "middleware" sono rinominati: skipMiddlewareUrlNormalize diventa skipProxyUrlNormalize. Il codemod ufficiale della 16 fa quasi tutto il lavoro.
Il punto più importante è pero strategico: il proxy non è un confine di sicurezza. Non metterci l'autenticazione!
L'autorizzazione va vicino ai dati — in Server Actions, Route Handler e Data Access Layer centralizzato.
Assets
06Immagini e font senza layout shift
Per immagini usa sempre next/image con priority sulla hero e sizes corretti. Per font usa next/font per self-host e meno CLS.
Bundle & client
07Spedisci meno JavaScript
Ogni componente con 'use client' e tutto cio che importa finisce nel bundle browser. Tienilo sui componenti interattivi.
Mutazioni
08Server Actions per scrivere dati
Le validazioni una volta venivano fatte lato back, poi lato front, ora si ha una doppia validazione spesso, sia front che back, ma in un app fullstack tutta in Next, la validazione che io preferisco è quella lato server action.
Le validazioni in zod stanno diventando sempre più importanti anche nell’era della generative UI per verificare le risposte degli llm, secondo me ne vale la pena comprendere questo pacchetto.
Qualità & codice AI
09Non fidarti dell'input (ne dell'AI)
Eccoci al cuore del controllare il codice generato dall'AI. Il principio di base vale sempre: ogni dato che entra dal mondo esterno va validato al confine - body delle richieste, query string, FormData, parametri.
Lo strumento standard e zod (o equivalente): definisci la forma attesa e .parse() rifiuta tutto cio che non combacia, dandoti anche i tipi TypeScript gratis.
Quando rivedi codice scritto da un assistente, oltre alla validazione ci sono due controlli mirati che intercettano la grande maggioranza dei problemi di sicurezza.
Verifica
10Misura, non indovinare
L'ultima ottimizzazione lega tutte le altre: non ottimizzare a sensazione, misura. Hai tre strumenti, dal piu semplice al piu automatico.
L'output di next build ti dice rotta per rotta cosa e statico e cosa e dinamico. Dopo aver attivato i Cache Components e la prima cosa da guardare: spesso scopri una pagina creduta statica ma dinamica per cookie o data runtime.
I Web Vitals sono il termometro onesto: LCP (contenuto principale), INP (reattivita input), CLS (stabilita layout).
Infine il gate automatico: le regole che non puoi seguire quasi sempre vivono in CI. ESLint, tsc --noEmit e test su ogni PR bloccano il codice AI difettoso prima del merge.
Testing
TTesting con Jest, da zero
Cos'e un test (e cos'e Jest)
Il capitolo 10 diceva metti i test in CI. Ma se non hai mai scritto un test, da dove parti? Qui l'idea e partire da esempi copiabili.
Un test e codice che verifica altro codice: se passi questo input, ti aspetti questo output. Se in futuro rompi il comportamento, il test fallisce prima che lo vedano gli utenti.
Jest e il motore che esegue i test, li trova e segnala verdi/rossi. Next.js lo supporta in modo nativo con next/jest, quindi il setup e piu rapido.
L'anatomia di un test: describe / it / expect
Tre keyword bastano per iniziare: describe raggruppa, it descrive il caso, expect contiene l asserzione.
Schema mentale AAA: Arrange (prepara), Act (esegui), Assert (verifica).
Se il risultato differisce, Jest segna rosso e mostra differenza atteso/reale.
Configurare Jest con Next 16
Primo passo: installa Jest e Testing Library come dipendenze di sviluppo.
jsdom e un browser finto in Node: serve ai componenti React che si aspettano document/DOM.
Primo test: una funzione pura
Il modo piu semplice per partire e testare funzioni pure: input dentro, output fuori, zero effetti collaterali.
Lancia npm test e vedrai i casi verdi. Anche gli schemi zod sono candidati perfetti: input valido passa, input errato throw.
Testare un componente: React Testing Library
Per i componenti usa RTL: testa come un utente, non i dettagli interni. Cerca elementi per ruolo/testo, simula click, verifica output.
getByRole('button', { name: /mi piace/i }) usa ruolo + testo visibile. toHaveTextContent arriva da jest-dom.
Avvio rapido
Bonus
+React Compiler: memoizzazione gratis
In Next 16 il supporto al React Compiler e stabile (dopo release 1.0). Memoizza automaticamente i componenti e riduce re-render inutili.
Non e attivo di default: conviene abilitarlo, misurare tempi build e Web Vitals, poi decidere con numeri alla mano.
Automatizzare
★Dare queste regole all'AI
Tutto ciò che hai letto può diventare regole versionate per Cursor e Claude Code. Principio: file letto a ogni sessione come contratto di comportamento.
Premessa chiave: piu le regole sono specifiche e imperative, piu ti puoi fidare. MAI X / SEMPRE Y batte consigli vaghi.
Per questo motivo, in questa lista il tutto spesso è imperativo + esempio, così che anche io possa copiarlo in una fare di “code review”.
Cursor -> .cursor/rules/*.mdc
Cursor usa file .mdc in .cursor/rules con frontmatter YAML e globs di attivazione. Il vecchio file unico non basta in Agent mode.
Claude Code -> CLAUDE.md + AGENTS.md
Claude Code legge CLAUDE.md all avvio. Strategia pulita: regole in AGENTS.md come fonte unica e CLAUDE.md che rimanda li.
Le due regole che fanno la differenza
Riepilogo
✓Un esempio di checklist del codice (anche chiedendo all’AI)
- Cache esplicita solo su dati lenti e identici per tutti.
- Dati per-utente con use cache: private, mai in cache condivisa.
- Parti dinamiche dentro Suspense con fallback reale.
- Fetch sul server, indipendenti in Promise.all.
- Auth nelle Server Action / DAL, mai nel proxy.ts; Next aggiornato.
- next/image con priority+sizes e font con next/font.
- 'use client' solo sulle foglie; pesanti con next/dynamic.
- Server Action: autorizza -> valida -> scrivi -> invalida.
- Input validato con zod; query parametrizzate; autorizzazione su ogni accesso.
- next build + Web Vitals + lint/tipi/test in CI.