JavaScript

React Server Components: cosa cambiano davvero nel modo di costruire app web

Da quando Next.js App Router è diventato lo standard, capire i Server Components non è più opzionale. Ecco cosa cambia nel modo concreto di costruire applicazioni.

13 Apr 2026·8 min di lettura·Antonio Tufo
Schermata di codice React con componenti server e client su un editor VS Code scuro

I React Server Components (RSC) sono componenti React che vengono renderizzati esclusivamente sul server, senza JavaScript inviato al browser. A differenza dei Client Components, non possono usare 0.85em] font-mono">useState o useEffect, ma possono accedere direttamente a database, file system e API senza fetch aggiuntive. In Next.js con [App Router tutti i componenti nella cartella app/ sono Server Components per default — capire questa distinzione è il prerequisito per scrivere architetture moderne e performanti.

Nei progetti che seguo, da quando Next.js ha adottato l'App Router come standard, la domanda che ricevo più spesso da sviluppatori alle prime armi con l'architettura moderna è sempre la stessa: "Perché il mio componente non riesce a usare useState se è dentro la cartella app/?" La risposta è che stiamo parlando, molto probabilmente, di un Server Component, e capire cosa questo significhi nella pratica è uno di quei passaggi che, una volta interiorizzato, cambia completamente il modo in cui scrivi JavaScript per il web.

I React Server Components (RSC) non sono una novità assoluta del 2026, dal momento che il lavoro sperimentale del team di React risale al 2020, ma è soltanto con l'adozione massiccia di Next.js 13 in poi che sono diventati una realtà concreta nella vita quotidiana di chi costruisce applicazioni. Dunque, quello che voglio fare in questo articolo è andare oltre la definizione da documentazione ufficiale e ragionare su cosa cambia nel modo concreto di costruire un'app, quali sono i vantaggi reali e dove, di fatto, i Server Components non sono la scelta giusta.

La distinzione di base: dove gira il codice

Per capire i React Server Components bisogna prima mettere da parte l'idea che React sia soltanto un framework che gira nel browser. Prima dell'App Router, quando costruivi un'applicazione Next.js con le Pages Router, avevi un'unica separazione netta: il codice server stava in getServerSideProps o getStaticProps, e tutto il resto, ossia i componenti React, girava sul client oppure veniva pre-renderizzato lato server ma poi IDRATATO nel browser.

L'idratazione è proprio il concetto chiave da cui partire. Quando un componente React viene "idratato", significa che il browser scarica il bundle JavaScript corrispondente, lo esegue, e "attiva" il markup HTML statico rendendolo interattivo. Questo processo ha un costo: più componenti hai nell'albero, più JavaScript il browser deve scaricare, analizzare ed eseguire. In un'applicazione con decine o centinaia di componenti, questo peso diventa tangibile, in particolar modo su dispositivi mobili o connessioni lente.

I React Server Components rompono questa dinamica in modo RADICALE. Un Server Component non viene mai spedito al browser come JavaScript: gira soltanto sul server, produce il suo output HTML, e quest'ultimo viene inviato direttamente al client senza che ci sia nessun bundle associato da scaricare. Il browser riceve markup, non logica.

Cosa puoi (e non puoi) fare in un Server Component

Nella pratica, un Server Component in Next.js App Router è semplicemente un file .tsx o .jsx senza la direttiva "use client" all'inizio. Per impostazione predefinita, tutti i componenti dentro la cartella app/ sono Server Components, dal momento che questa è la scelta di default dell'App Router.

Nei Server Components puoi fare cose che prima richiedevano passaggi espliciti lato server: accedere direttamente al database, leggere variabili d'ambiente sensibili, fare fetch a API esterne senza esporre chiavi al browser, leggere il filesystem. Ho usato questa caratteristica in un progetto recente in cui, seppur il frontend fosse completamente in React, avevo bisogno di accedere a dati da un database PostgreSQL in modo diretto, senza costruire un'API REST intermedia soltanto per passare dati da server a client. Un Server Component fa la query, costruisce il JSX con i dati, e spedisce il risultato al browser, senza nemmeno che una riga del codice del database raggiunga mai il client.

Quello che non puoi fare in un Server Component è tutto ciò che dipende dal browser o dall'interattività: useState, useEffect, useRef, event handler come onClick o onChange, Context React lato client. Qualsiasi componente che ha bisogno di interazione diretta dell'utente deve essere un Client Component, il che significa che devi aggiungere la direttiva "use client" all'inizio del file.

Dunque la domanda che ti poni quando costruisci una nuova feature è diventata: "Questo componente ha bisogno di stato o di interazione?" Se la risposta è no, probabilmente è un Server Component. Se la risposta è sì, è un Client Component. Sembra semplice, e in buona parte lo è, ma ci sono alcune sfumature che vale la pena approfondire prima che diventino problemi reali in produzione.

Il confine tra server e client nell'albero dei componenti

Uno degli aspetti più importanti, e spesso fonte di confusione, è capire come funziona il confine tra Server e Client Components nell'albero React. La regola è semplice ma non sempre intuitiva: un Server Component può importare e renderizzare un Client Component, ma un Client Component non può importare un Server Component aspettandosi che quest'ultimo rimanga un Server Component.

Questo significa che il confine "scende" verso il basso: puoi avere una pagina che è un Server Component, che renderizza un componente di layout che è un Client Component (perché, per esempio, gestisce lo stato del menu mobile su smartphone), e dentro quest'ultimo puoi passare dati via props dal server. Quello che non puoi fare è importare un Server Component all'interno di un Client Component e aspettarti che rimanga lato server, dal momento che tutto ciò che si trova dentro un Client Component viene, di fatto, considerato parte del bundle client.

Una tecnica che nei progetti che seguo uso spesso è quella di passare Server Components come children ai Client Components, invece di importarli direttamente. In questo modo il Server Component mantiene la sua natura, viene renderizzato sul server, e il Client Component lo riceve già come markup pronto da mostrare. Quest'ultima tecnica è particolarmente utile quando hai un componente di layout interattivo (come una sidebar con animazioni o un drawer per il mobile) che deve contenere componenti che accedono al database o leggono dati riservati.

Streaming e Suspense: il vantaggio che si vede in produzione

Un aspetto che cambia profondamente l'esperienza dell'utente finale, seppur sia meno visibile al livello del codice durante lo sviluppo, è l'integrazione tra Server Components e React Suspense per lo streaming dell'HTML.

Con l'App Router puoi andare a avvolgere parti lente della tua pagina in un con un fallback, e Next.js invierà al browser prima il markup della pagina con il fallback (un skeleton o un semplice loader), e poi, man mano che i dati arrivano dal server, invierà i blocchi HTML dei componenti che stavano caricando. Di fatto il browser inizia a mostrare contenuto immediatamente, senza aspettare che tutti i dati siano pronti.

Ho visto questo pattern fare una differenza concreta su pagine con più sorgenti di dati indipendenti: una sezione che carica prodotti in evidenza, un'altra che mostra le ultime recensioni, un'altra ancora con statistiche aggregate. Con il vecchio approccio basato su getServerSideProps, la pagina aspettava la risposta più lenta prima di mostrare qualsiasi cosa. Con lo streaming, ogni sezione appare non appena i suoi dati sono pronti, e il risultato percepito dall'utente è quello di una pagina molto più reattiva, anche quando la connessione non è delle migliori.

Dal punto di vista del codice, la cosa interessante è che non devi fare nulla di speciale nei componenti: basta che siano 0.85em] font-mono">async (caratteristica possibile soltanto nei Server Components), che facciano await sui dati, e React gestirà automaticamente lo streaming in collaborazione con Next.js. Questa combinazione di async/await nativi nei componenti è, di fatto, una delle differenze più significative rispetto al mondo delle Pages Router, dove ogni dato asincrono doveva passare per hook dedicati o per le funzioni di fetching dell'App Router. Se ti interessa capire più a fondo come sfruttare le [Web API native del browser in combinazione con questo modello, il discorso si collega naturalmente a come strutturiamo oggi il codice lato client.

Quando i Server Components non sono la scelta giusta

Di certo non voglio darti l'impressione che i Server Components siano la risposta a tutto, dal momento che ci sono scenari in cui la loro adozione aggiunge complessità senza un vantaggio reale.

Il primo caso è quello delle applicazioni molto interattive, come dashboard con aggiornamenti in tempo reale, editor collaborativi, o qualsiasi cosa che abbia bisogno di uno stato che cambia frequentemente in risposta all'utente. In questi contesti la maggior parte dei componenti ha bisogno di useState o di connessioni WebSocket, dunque finiranno tutti nel bundle client comunque, e il beneficio dei Server Components si riduce considerevolmente. Non significa che non dovresti usarli, ma che la loro presenza nell'architettura sarà limitata ai componenti di scaffolding più esterni.

Il secondo caso riguarda applicazioni già costruite con l'architettura Pages Router di Next.js o con altri framework come Create React App (ormai deprecato, ma ancora molto diffuso in progetti legacy). Migrare una codebase esistente verso l'App Router e i Server Components non è un'operazione banale, dal momento che richiede di ripensare l'intera gestione dello stato e del fetching, e in alcuni casi anche di riscrivere integrazioni con librerie di terze parti che non sono ancora compatibili con il modello RSC. In questo caso, valuta concretamente se i benefici giustificano l'investimento di migrazione, oppure se ha più senso continuare con l'architettura esistente che funziona e porta risultati.

Il terzo caso è quello delle library React: se stai costruendo un componente da pubblicare su npm e destinato a essere usato in contesti diversi, è difficile fare affidamento sui Server Components proprio perché non tutti i progetti che useranno la tua library saranno su Next.js App Router. In questo caso il Client Component rimane la scelta più portabile e compatibile.

Come strutturare un progetto con i Server Components

Nella pratica, dopo aver lavorato su più progetti con l'App Router, mi sono fatto una regola semplice: comincio tutto come Server Component, e passo a Client Component soltanto quando incontro qualcosa che il server non può fare. Questo approccio mi porta quasi sempre a una struttura in cui le foglie dell'albero di componenti (i bottoni, i form, le dropdown, gli elementi interattivi puri) sono Client Components, mentre tutto ciò che riguarda il layout, il fetching e la struttura della pagina rimane sul server.

Un pattern che uso spesso nei progetti di sviluppo siti web che seguo, in particolar modo nei progetti con molte pagine di contenuto come blog o siti istituzionali, è separare la logica di fetching dalla logica di presentazione: un Server Component asincrono si occupa di prendere i dati e li passa come props a un Client Component che li visualizza con animazioni, tooltip o interazioni specifiche. Quest'ultimo approccio mantiene pulita la separazione tra responsabilità, rende più semplice il debugging (sai sempre dove sta il dato e dove sta l'interazione) e, cosa non trascurabile, riduce il rischio di esporre accidentalmente dati o chiavi API al browser per via di una direttiva "use client" messa nel posto sbagliato.

Un'altra cosa che faccio sistematicamente è tenere separati i file che contengono la logica di accesso ai dati (query al database, chiamate API) dai componenti React stessi, collocandoli in una cartella 0.85em] font-mono">lib/ o server/ chiaramente dedicata al codice server. Questo mi aiuta a mantenere la distinzione mentale netta anche quando il progetto cresce, dal momento che in un codebase grande è facile perdere traccia di dove gira cosa. In progetti di questo tipo, avere il [TypeScript strict mode attivo rende ancora più semplice individuare subito quando un dato pensato per girare solo sul server finisce per caso in un punto sbagliato dell'albero dei componenti.

L'impatto reale sulle performance

Hai probabilmente sentito parlare di Core Web Vitals e di quanto Google li usi come segnale di ranking. Tra questi, il Largest Contentful Paint (LCP) misura quanto tempo impiega il contenuto principale della pagina a diventare visibile. Con i Server Components e lo streaming, questo valore migliora in modo misurabile, proprio perché l'HTML arriva al browser in modo progressivo e il contenuto visivo non aspetta il JavaScript.

Nei progetti su cui ho fatto A/B testing tra Pages Router e App Router, ho visto miglioramenti nell'LCP nell'ordine del 30-40% su pagine con contenuto prevalentemente statico o semi-dinamico, ossia esattamente il tipo di pagine che compone la stragrande maggioranza dei siti web aziendali e dei blog. Questo si traduce in un vantaggio concreto sia per l'esperienza dell'utente sia per il posizionamento organico su Google, il che rende i Server Components rilevanti non soltanto dal punto di vista tecnico ma anche da quello del business.

I React Server Components, dunque, non sono una feature da imparare una volta e mettere da parte: sono, di fatto, un cambiamento nel modello mentale con cui si costruisce un'applicazione React moderna. Una volta che hai capito dove gira il codice e perché, il confine tra server e client smette di essere un ostacolo e diventa uno strumento di progettazione architetturale consapevole. E quando quel confine lo gestisci bene, si vede nel prodotto finale, dalle performance all'esperienza utente fino alla manutenibilità nel tempo.

Se stai lavorando su un progetto Next.js con l'App Router e hai dubbi su come strutturare i tuoi componenti o stai valutando una migrazione dall'architettura precedente, possiamo analizzarlo insieme: scrivi dal modulo di contatto e ti rispondo entro 24 ore.

Domande frequenti

Cosa sono i React Server Components e come si differenziano dai Client Components?

I React Server Components vengono eseguiti solo sul server: leggono dati direttamente, non inviano JavaScript al browser e non possono usare hook come useState o useEffect. I Client Components vengono eseguiti nel browser e gestiscono l'interattività. In Next.js App Router i componenti sono Server Components per default; si aggiunge "use client" solo dove serve interattività.

Perché il mio componente Next.js non riesce a usare useState?

Perché si trova nella cartella app/ e Next.js lo tratta come Server Component per default. I Server Components non supportano hook come useState, useEffect o useRef che dipendono dall'ambiente browser. Soluzione: aggiungere "use client" come prima riga del file per trasformarlo in Client Component, oppure isolare la parte interattiva in un componente figlio separato.

Quando conviene usare un Server Component invece di un Client Component?

Usa Server Components per: fetch di dati da database o API, rendering di contenuto statico o quasi-statico, componenti che non richiedono interattività, operazioni pesanti (parsing, calcoli) che non vuoi eseguire nel browser. Usa Client Components per: gestione dello stato locale, event listener, browser API (localStorage, geolocation), librerie di animazione.

I React Server Components migliorano le performance dell'app?

Sì, principalmente in due modi: riducono il bundle JavaScript inviato al browser (il codice del Server Component non viene mai scaricato dal client) e permettono fetch di dati più veloci perché avvengono direttamente sul server, vicino ai dati. Il risultato è un First Contentful Paint più rapido e un'esperienza utente migliore, specialmente su connessioni lente.

Argomenti

react server componentsnext.js app routerserver components vs client componentsnext.js 16 tutorialreact suspense streamingjavascript moderno 2026
AT

Antonio Tufo

Full-Stack Developer & Interaction Designer. Lavoro con startup e PMI italiane.

Chi sono

Tutti gli articoli

Torna al blog

Hai un progetto da realizzare?

Dalla consulenza al deploy: trasformo le idee in prodotti digitali che funzionano.

Parliamo del tuo progetto

Preferenze Cookie

Scegli i cookie non tecnici

Questo sito utilizza Google Analytics 4 per analizzare il traffico in forma aggregata. I cookie analitici vengono attivati solo con il tuo consenso e puoi modificare la scelta in qualsiasi momento.