Node.js è un runtime JavaScript open source e multipiattaforma che permette di eseguire JavaScript fuori dal browser. Viene utilizzato soprattutto per backend, API, servizi di rete, applicazioni real-time, strumenti da riga di comando e automazioni.
La definizione sembra semplice, ma contiene già il punto che crea più confusione: Node.js non è un linguaggio di programmazione e non è un framework. Il linguaggio resta JavaScript; il runtime è invece l’ambiente che lo esegue e mette a disposizione API per lavorare con rete, file system, processi e altre risorse del sistema operativo.
Il progetto ufficiale lo descrive come un runtime JavaScript asincrono ed event-driven progettato per applicazioni di rete scalabili. Utilizza il motore V8, lo stesso motore JavaScript alla base di Chrome, ma lo porta fuori dal contesto del browser. La documentazione ufficiale è il riferimento primario per questa architettura.
In questa guida vediamo cosa significa davvero, come funzionano event loop e I/O non bloccante, quale ruolo svolgono libuv e i Worker Threads, quando questo modello è una buona scelta e quando invece conviene valutare tecnologie diverse. Alla fine creeremo anche un piccolo server HTTP senza utilizzare framework.
Cos’è e cosa non è Node.js
Node.js è un ambiente di esecuzione per JavaScript. La parola runtime indica proprio questo: un ambiente capace di eseguire il codice e mettere a disposizione funzionalità che il linguaggio, da solo, non possiede.
Se hai già letto la nostra guida su cos’è JavaScript, la distinzione fondamentale è questa:
JavaScript = linguaggio.
Node.js = runtime che esegue JavaScript.
Il browser è a sua volta un ambiente di esecuzione JavaScript, ma mette a disposizione API orientate alle pagine web: DOM, eventi dell’interfaccia, storage del browser e altre Web API.
Il runtime server-side non ha bisogno di una pagina HTML e non dispone normalmente di oggetti browser come document o window. Offre invece API adatte a operazioni come:
- leggere e scrivere file;
- aprire connessioni di rete;
- creare server HTTP;
- lavorare con processi;
- eseguire script da terminale;
- gestire stream;
- comunicare con servizi e database attraverso librerie e driver.
È quindi lo stesso linguaggio eseguito in un ambiente differente.
Un runtime JavaScript, non un linguaggio né un framework
Definirlo un “linguaggio backend” è impreciso. Il linguaggio è JavaScript.
Anche chiamarlo semplicemente framework è fuorviante. Un framework come Express si installa sopra il runtime e offre astrazioni aggiuntive per routing, middleware e applicazioni web.
La distinzione diventa evidente osservando un semplice programma:
console.log("Ciao da Node.js!");
Salvalo come app.js ed eseguilo dal terminale:
node app.js
Non hai installato un framework e non hai creato un sito. Hai semplicemente chiesto al runtime di eseguire codice JavaScript.
V8 fuori dal browser: cosa cambia davvero
Il motore JavaScript utilizzato è V8, sviluppato nell’ecosistema Chromium. V8 si occupa dell’esecuzione del linguaggio, ma l’ambiente server-side non è soltanto “V8 senza Chrome”.
Attorno al motore esiste un runtime più ampio che aggiunge API, gestione dell’I/O, event loop e integrazione con il sistema operativo.
Questo modello permette a JavaScript di fare cose che nel browser non sarebbero disponibili nello stesso modo. Un programma può, per esempio, leggere un file locale, aprire una porta di rete oppure avviare un processo.
Il modello mentale più utile è quindi:
codice JavaScript → V8 → runtime → sistema operativo / rete / file / processi
Una volta separati questi livelli, anche termini come event loop, callback e I/O asincrono diventano molto meno misteriosi.
Come funziona il runtime
Il tratto più importante dell’architettura è il modo in cui vengono gestite le operazioni che richiedono attesa.
Pensa a una richiesta verso un database, alla lettura di un file o alla comunicazione con un servizio remoto. La CPU non deve necessariamente lavorare per tutto il tempo: spesso deve semplicemente aspettare una risposta.
Bloccare l’intero programma durante quell’attesa sarebbe uno spreco.
Il modello è invece asincrono ed event-driven: il runtime può continuare a gestire altro lavoro mentre alcune operazioni sono in corso.
Event loop e I/O non bloccante
L’event loop coordina l’esecuzione dei callback JavaScript quando il relativo lavoro è pronto.
Consideriamo un esempio semplificato:
console.log("inizio");
setTimeout(() => {
console.log("timer");
}, 1000);
console.log("fine");
L’output sarà inizialmente:
inizio fine
e successivamente:
timer
Il programma non rimane fermo per un secondo aspettando il timer.
La stessa idea diventa molto più importante quando l’attesa riguarda rete, file o altri servizi. Il runtime può continuare a gestire eventi e callback invece di dedicare un thread bloccato a ogni singola richiesta.
Questo è uno dei motivi per cui il modello si presta bene a carichi con molte operazioni I/O concorrenti.
Non significa però che qualsiasi applicazione sia automaticamente veloce. Se un callback esegue per molto tempo calcoli sincroni sul thread dell’event loop, le altre richieste devono aspettare.
La documentazione ufficiale insiste infatti sul principio di non bloccare né l’Event Loop né il Worker Pool.
libuv e Worker Pool: il lavoro che non resta sull’Event Loop
Una semplificazione frequente descrive Node.js come “un singolo thread che fa tutto”.
Non è un modello sufficientemente preciso.
Il codice JavaScript ordinario viene coordinato dall’event loop, ma il runtime collabora con il sistema operativo e con libuv, la libreria che contribuisce alla gestione dell’I/O asincrono e del thread pool.
Alcune operazioni possono essere gestite direttamente attraverso meccanismi asincroni del sistema operativo; altre utilizzano un Worker Pool. La documentazione ufficiale cita, tra i casi rilevanti, operazioni relative a file system, DNS, crittografia e compressione.
Il modello è quindi più vicino a:
JavaScript → Event Loop → operazione asincrona → sistema operativo / Worker Pool → completamento → callback
La conseguenza pratica conta più del dettaglio implementativo: non dovresti trasformare l’event loop in una coda bloccata da un singolo lavoro troppo pesante.

È davvero single-threaded?
La risposta corretta è: dipende da cosa stai descrivendo.
Dire che l’esecuzione ordinaria del JavaScript avviene sul thread dell’event loop è utile. Dire che l’intero runtime usa sempre e soltanto un thread è invece sbagliato.
Internamente vengono utilizzati altri thread e il modulo worker_threads permette anche di eseguire JavaScript in parallelo.
I Worker Threads sono particolarmente indicati per elaborazioni CPU-intensive. Per il normale I/O, invece, le API asincrone integrate sono generalmente più appropriate. La documentazione di worker_threads classifica questa API come stabile.
Quindi:
- molte connessioni e molto I/O non richiedono automaticamente molti Worker Threads;
- un calcolo JavaScript pesante può invece essere candidato a un worker;
- aggiungere thread non corregge automaticamente un’architettura sbagliata.
A cosa serve nella pratica
Ridurre questa tecnologia alla creazione di “server JavaScript” significa perdere una parte importante dei suoi casi d’uso.
Il runtime viene usato per applicazioni server, ma anche per strumenti di sviluppo, automazioni, command line tool e processi che non espongono affatto un sito web.
Server web, backend e API
Uno degli utilizzi più comuni è l’esecuzione della logica backend di un’applicazione.
Un programma può ricevere richieste HTTP, interrogare un database, applicare regole applicative e restituire una risposta al client.
Se il concetto di client, endpoint, richiesta e risposta non ti è ancora familiare, la nostra guida alle API chiarisce il flusso completo.
Una tipica API potrebbe seguire questo percorso:
client → richiesta HTTP → applicazione → logica → database/servizio → risposta
La risposta viene spesso serializzata in JSON, formato molto diffuso per lo scambio di dati tra applicazioni.
Node.js non è però l’unica tecnologia capace di creare backend o API. PHP, Python, Java, .NET, Go e molti altri ecosistemi possono svolgere lo stesso ruolo. La scelta dipende dal tipo di applicazione, dal team e dai vincoli del progetto.
Applicazioni real-time, WebSocket e streaming
Il modello event-driven è particolarmente interessante quando l’applicazione mantiene molte connessioni o gestisce un flusso continuo di eventi.
Esempi possibili sono:
- chat;
- notifiche in tempo reale;
- dashboard aggiornate continuamente;
- sistemi collaborativi;
- gateway e servizi di rete;
- applicazioni che utilizzano WebSocket;
- elaborazione di stream.
Il vantaggio non deriva dalla parola “real-time” in sé. Deriva dal fatto che gran parte del lavoro consiste spesso nel ricevere dati, attendere eventi e gestire I/O, anziché mantenere la CPU impegnata in calcoli lunghi per ogni connessione.
Script, automazione, CLI e strumenti di sviluppo
Un file JavaScript può essere eseguito direttamente dal terminale. Questo rende il runtime utile anche per task che non hanno nulla a che vedere con un web server.
Puoi utilizzarlo per:
- trasformare file;
- automatizzare attività;
- generare contenuti o asset;
- elaborare dati;
- creare strumenti da riga di comando;
- eseguire script di build;
- orchestrare altri processi.
Una parte enorme dell’ecosistema frontend moderno lo utilizza proprio in questo modo: il codice finale può essere destinato al browser, mentre build tool, bundler, generatori e script di sviluppo vengono eseguiti fuori dal browser.
JavaScript e runtime: qual è la differenza
Questa è probabilmente la distinzione da ricordare meglio.
JavaScript è il linguaggio. Node.js è uno degli ambienti in cui quel linguaggio può essere eseguito.
Nel browser JavaScript interagisce soprattutto con la piattaforma Web.
In un runtime server-side interagisce invece con API orientate a file, rete, processi e servizi del sistema operativo.
| Aspetto | Browser | Node.js |
|---|---|---|
| Linguaggio | JavaScript | JavaScript |
| Ambiente | Browser | Runtime Node.js |
| DOM | Disponibile | Non disponibile per default |
window | Disponibile | Non disponibile per default |
| File system locale | Fortemente limitato dal modello browser | API dedicate |
| Server HTTP | Il browser agisce normalmente da client | Può crearne uno |
| Processi di sistema | Non accessibili come in un runtime server | API dedicate |
| Moduli | ES Modules e piattaforma Web | ES Modules + CommonJS + moduli integrati |
La differenza non sta quindi nella sintassi fondamentale del linguaggio, ma nelle capacità offerte dall’ambiente.
Stesso linguaggio, ambienti e API differenti
Considera questa riga:
document.querySelector("h1");
È JavaScript valido nel browser perché l’ambiente mette a disposizione il DOM (Document Object Model) e quindi l’oggetto document.
In un normale processo Node.js, invece, document non esiste.
Al contrario:
import { readFile } from "node:fs";
utilizza un modulo integrato per interagire con il file system.
Capire questa distinzione evita di attribuire al linguaggio funzionalità che appartengono in realtà all’ambiente di esecuzione.
È frontend o backend?
Node.js viene utilizzato soprattutto nel backend e nel tooling, ma la risposta richiede una precisazione.
Un’applicazione frontend destinata al browser non viene normalmente eseguita “dentro Node.js” quando l’utente visita la pagina.
Il runtime può però essere utilizzato durante lo sviluppo frontend per:
- eseguire build tool;
- installare dipendenze;
- avviare server di sviluppo;
- compilare o trasformare asset;
- eseguire test;
- produrre bundle destinati al browser.
Può inoltre eseguire il backend dello stesso progetto.
Per questo uno sviluppatore JavaScript può lavorare su entrambi i lati utilizzando lo stesso linguaggio, pur operando in ambienti differenti.
npm, package.json e moduli
Un progetto raramente vive soltanto della libreria standard.
L’ecosistema dei pacchetti è una parte fondamentale dell’esperienza di sviluppo, ma anche qui conviene separare alcuni concetti.
Che cos’è npm e cosa installa realmente
npm non è Node.js.
npm comprende un registry di pacchetti, un sito e una Command Line Interface. Il registry pubblico ospita software e metadati, mentre la CLI permette di installare e gestire le dipendenze di un progetto. La documentazione ufficiale npm distingue esplicitamente questi componenti.
Per inizializzare un progetto puoi incontrare il comando:
npm init
o, per accettare rapidamente i valori predefiniti:
npm init -y
Viene creato un file package.json.
Questo file può descrivere, tra le altre cose:
- nome e versione del progetto;
- script disponibili;
- dipendenze;
- dipendenze di sviluppo;
- sistema di moduli;
- altre informazioni utilizzate dagli strumenti.
Quando esegui:
npm install nome-pacchetto
stai aggiungendo una dipendenza al progetto. Non stai “aggiungendo una funzione a JavaScript”: stai incorporando software esterno che il programma potrà importare e utilizzare.
Questa distinzione è importante anche dal punto di vista della sicurezza. Ogni dipendenza introduce codice, versioni e una supply chain che devono essere gestiti.
ES Modules e CommonJS: cosa serve sapere per iniziare
L’ambiente supporta due sistemi di moduli principali:
- ECMAScript Modules (ESM);
- CommonJS.
CommonJS utilizza storicamente sintassi come:
const http = require("node:http");
Gli ES Modules utilizzano invece:
import * as http from "node:http";
Gli ES Modules sono supportati pienamente, mentre CommonJS rimane disponibile per compatibilità con l’enorme ecosistema esistente. Il comportamento dei file può essere dichiarato tramite estensioni .mjs e .cjs oppure attraverso il campo "type" di package.json.
La documentazione ufficiale sui package descrive nel dettaglio le regole attuali.
Per un primo esercizio useremo un file .mjs, così la scelta del sistema di moduli resta esplicita.
Quando conviene usarlo e quando scegliere altro
La domanda utile non è “Node.js è migliore di PHP, Python o Java?”.
La domanda utile è:
il suo modello di esecuzione e il suo ecosistema sono adatti al lavoro che deve fare questa applicazione?
I/O, molte connessioni e applicazioni event-driven
Questo modello è particolarmente naturale quando l’applicazione dedica molto tempo ad aspettare operazioni esterne:
- rete;
- API;
- database;
- file;
- code;
- eventi;
- connessioni persistenti.
In questi scenari l’approccio asincrono può permettere di gestire molto lavoro concorrente senza costruire l’applicazione attorno a un thread dedicato per ogni singola connessione.
Questo non significa che “Node.js scala automaticamente”.
Per scalare servono comunque:
- codice che non blocchi il runtime;
- gestione corretta del database;
- cache quando necessaria;
- osservabilità;
- gestione degli errori;
- architettura dell’infrastruttura;
- bilanciamento del carico quando richiesto;
- strategia di deploy.
Il runtime è solo uno dei livelli.
Elaborazioni CPU-intensive e Worker Threads
Un’operazione CPU-intensive mantiene il processore occupato.
Esempi possono essere trasformazioni numeriche pesanti, alcune elaborazioni crittografiche applicative, parsing molto costoso o algoritmi che eseguono grandi quantità di calcoli JavaScript.
Se un task del genere viene eseguito per troppo tempo sul thread dell’event loop, può ritardare la gestione degli altri eventi.
In questi casi puoi:
- ridurre o ottimizzare il lavoro;
- spezzarlo quando possibile;
- spostarlo in un Worker Thread;
- delegarlo a un processo o servizio specializzato;
- scegliere un’architettura diversa se il carico dominante è computazionale.
I worker_threads permettono l’esecuzione parallela di JavaScript e sono pensati soprattutto per lavoro CPU-intensive.
Il limite non è quindi “JavaScript server-side non può usare più core”. Il problema reale è evitare che il lavoro sbagliato venga eseguito nel punto sbagliato.
Node.js rispetto a PHP, Python e Java: il criterio corretto
Un confronto sensato deve partire dal progetto.
| Tecnologia | Punto distintivo | Ha particolare senso quando |
|---|---|---|
| Node.js | JavaScript + modello asincrono/event-driven | backend I/O-heavy, API, servizi real-time, team JavaScript |
| PHP | ecosistema Web e hosting estremamente diffusi | CMS, WordPress, applicazioni Web PHP, stack già consolidati |
| Python | ecosistema molto ampio oltre al Web | automazione, data/AI, servizi Python, backend con framework dedicati |
| Java | JVM ed ecosistema enterprise maturo | sistemi enterprise, stack JVM, applicazioni con requisiti organizzativi e architetturali specifici |
La tabella non è un benchmark prestazionale. Due applicazioni scritte con tecnologie differenti possono avere risultati completamente diversi in base ad architettura, database, qualità del codice, infrastruttura e carico.
Se stai semplicemente scegliendo una tecnologia perché “Node.js è più veloce”, stai probabilmente partendo dalla domanda sbagliata.
Versioni LTS, Current ed EOL
Il progetto utilizza un ciclo di release in cui le linee possono assumere stati diversi.
I tre termini da conoscere sono:
Current — linea più recente, con le novità introdotte più rapidamente.
LTS — Long Term Support, linea destinata a una finestra di supporto più lunga e normalmente più adatta alla stabilità richiesta dai progetti in produzione.
EOL — End of Life, linea che non riceve più il normale supporto previsto dal progetto.
La pagina ufficiale delle release permette di verificare quali linee sono Current, LTS, Maintenance o EOL. La pagina ufficiale di download propone la release consigliata per l’installazione.
Quale versione installare per un nuovo progetto
Per un progetto destinato alla produzione, la linea LTS corrente è normalmente il punto di partenza più prudente, salvo che dipendenze, provider o requisiti specifici richiedano una versione differente.
La Current ha senso quando vuoi lavorare con le funzionalità più recenti e sei disposto a seguire un ciclo di aggiornamento più rapido.
Non utilizzare invece una versione EOL per iniziare un nuovo progetto senza una ragione tecnica molto specifica: perderesti gli aggiornamenti previsti dal normale ciclo di supporto.
Evita anche di memorizzare un numero di versione letto in una guida. Prima dell’installazione controlla sempre lo stato sulla pagina ufficiale.
Perché conviene usare un version manager
Progetti differenti possono richiedere release diverse.
Un version manager permette di cambiare versione del runtime senza trasformare ogni aggiornamento in una reinstallazione manuale dell’intero ambiente.
È utile soprattutto quando:
- mantieni progetti vecchi e nuovi;
- lavori in team;
- devi riprodurre un ambiente;
- una dipendenza non è ancora compatibile con la release più recente;
- vuoi testare un aggiornamento prima di adottarlo.
La cosa importante non è quale version manager utilizzi, ma rendere esplicita e riproducibile la versione richiesta dal progetto.
Installazione e verifica dal terminale
Per una prima installazione, usa la pagina ufficiale di download e scegli una modalità adatta al tuo sistema operativo.
Per un progetto normale partirei dalla release LTS corrente, a meno che tu non abbia un requisito preciso per la Current.
Evita download provenienti da siti casuali: per binari e documentazione è preferibile partire dalle fonti ufficiali.
Verificare runtime e npm
Dopo l’installazione apri il terminale e digita:
node --version
oppure:
node -v
Se tutto è installato correttamente vedrai la versione disponibile.
Controlla poi npm:
npm --version
Non serve che il numero npm coincida con quello del runtime: sono componenti distinti con versioning differente.
Puoi infine creare app.js:
console.log("Node.js funziona");
ed eseguire:
node app.js
Se il terminale stampa:
Node.js funziona
hai già eseguito il tuo primo programma JavaScript fuori dal browser.
Primo esempio: un server HTTP senza framework
Per capire la differenza tra runtime e framework conviene evitare, almeno nel primo esempio, Express.
La libreria standard include già un modulo HTTP capace di creare client e server. La relativa API fa parte del core ed è documentata nella sezione ufficiale dedicata al modulo HTTP.
Crea un file chiamato:
server.mjs
e inserisci:
import { createServer } from "node:http";
const hostname = "127.0.0.1";
const port = 3000;
const server = createServer((req, res) => {
res.statusCode = 200;
res.setHeader("Content-Type", "text/plain; charset=utf-8");
res.end("Ciao da Node.js!");
});
server.listen(port, hostname, () => {
console.log(`Server attivo su http://${hostname}:${port}/`);
});
Avvialo:
node server.mjs
Vedrai un messaggio simile a:
Server attivo su http://127.0.0.1:3000/
Apri quell’indirizzo nel browser e riceverai:
Ciao da Node.js!
Non abbiamo usato Express, Apache o NGINX per creare questo esempio. Il server HTTP è stato aperto direttamente attraverso un modulo integrato.
Questo aiuta anche a distinguere il runtime dal concetto generale di server: un server è un ruolo o un software che fornisce un servizio; Node.js è invece l’ambiente con cui puoi creare un’applicazione capace di svolgere quel ruolo.
Cosa succede quando arriva una richiesta
La chiamata:
createServer((req, res) => {
crea un server e registra una funzione che verrà eseguita quando arriva una richiesta.
req rappresenta la richiesta ricevuta.
res rappresenta la risposta che costruiremo.
Con:
res.statusCode = 200;
indichiamo un esito positivo.
Con:
res.setHeader("Content-Type", "text/plain; charset=utf-8");
dichiariamo il tipo di contenuto.
Infine:
res.end("Ciao da Node.js!");
invia il corpo della risposta e la conclude.
È un esempio volutamente minimale, ma contiene già il meccanismo centrale di molte applicazioni di rete:
richiesta → callback → logica → risposta
In un’applicazione reale aggiungeresti routing, validazione, accesso ai dati, autenticazione, logging, gestione degli errori e altri livelli.
Express non è il runtime
Una delle confusioni più frequenti nasce perché molti tutorial iniziano direttamente con Express.
Express è un framework Web per Node.js. Node.js è il runtime che lo esegue.
Il sito ufficiale di Express lo definisce un framework Web minimalista e flessibile.
La libreria standard possiede già API HTTP native. Express aggiunge però astrazioni comode per attività come:
- routing;
- middleware;
- gestione delle richieste;
- gestione delle risposte;
- organizzazione dell’applicazione.
Con le API native puoi creare un server HTTP.
Con Express puoi costruire sopra il runtime un’applicazione Web utilizzando convenzioni e API di livello più alto.
La relazione può essere sintetizzata così:
JavaScript → Node.js → Express → applicazione
Non devi quindi “scegliere tra Node.js ed Express” come se fossero alternative dello stesso livello.
La vera scelta è se utilizzare direttamente le API del runtime oppure adottare Express o un altro framework che aggiunga un livello di astrazione.
Domande frequenti
Node.js è gratuito e open source?
Sì. Node.js è un progetto open source e multipiattaforma. Può essere eseguito sui principali sistemi operativi e progetto, documentazione e release sono disponibili attraverso i canali ufficiali.
Questo non significa però che tutti i servizi, hosting, database o pacchetti utilizzati insieme al runtime siano necessariamente gratuiti o open source.
Node.js è un web server?
Non esattamente.
Node.js è un runtime JavaScript. Tra le API integrate contiene strumenti che permettono di creare un server HTTP, quindi un’applicazione eseguita in questo ambiente può svolgere il ruolo di server.
Chiamare l’intero runtime semplicemente “web server” nasconde però gran parte delle sue funzioni: può eseguire CLI, script, automazioni, processi di build e programmi che non ascoltano alcuna porta HTTP.
Bisogna conoscere JavaScript prima di Node.js?
È fortemente consigliato.
Il runtime non sostituisce le basi del linguaggio.
Prima di affrontarlo dovresti almeno comprendere:
- variabili;
- funzioni;
- array e oggetti;
- scope;
- moduli;
- Promise;
asynceawait;- gestione degli errori.
Senza queste fondamenta rischi di attribuire all’ambiente di esecuzione problemi che dipendono invece dal funzionamento di JavaScript.
Node.js può eseguire TypeScript?
Sì, ma bisogna distinguere supporto leggero nativo e toolchain TypeScript completa.
Le versioni moderne possono eseguire direttamente una parte del codice TypeScript attraverso il type stripping, cioè rimuovendo la sintassi dei tipi che non necessita di trasformazione in JavaScript.
Non significa però che il runtime sostituisca automaticamente il compilatore TypeScript.
Il supporto integrato:
- non esegue type checking;
- non interpreta automaticamente tutte le funzionalità che richiedono trasformazione;
- non applica l’intera configurazione di
tsconfig.json; - non sostituisce una toolchain completa quando il progetto ne ha bisogno.
La documentazione TypeScript ufficiale distingue infatti il type stripping nativo dall’esecuzione con strumenti esterni quando serve supporto completo.
Conclusione
Node.js diventa molto più semplice da capire quando smetti di considerarlo un generico “framework per fare backend”.
È un runtime che esegue JavaScript fuori dal browser e mette a disposizione un ambiente progettato attorno a I/O asincrono, eventi e applicazioni di rete.
Questo modello lo rende particolarmente adatto a backend, API, servizi real-time, automazioni e applicazioni che devono gestire molte operazioni concorrenti senza trascorrere la maggior parte del tempo in calcoli CPU pesanti.
Il punto più importante, però, è evitare gli slogan.
Non è automaticamente più veloce di qualsiasi altra tecnologia, non utilizza letteralmente un solo thread per tutto e non coincide con Express, npm o JavaScript.
Se devi decidere se adottarlo in un progetto, parti dal carico reale: molto I/O, eventi e un team già competente in JavaScript sono segnali favorevoli; carichi computazionali dominanti o un ecosistema consolidato su un’altra tecnologia possono portare a una scelta diversa.
Una volta chiarito questo, il passo successivo non è installare dieci framework. È costruire un piccolo progetto, osservare come si comportano richieste asincrone, errori e callback e imparare a riconoscere ciò che può bloccare l’event loop.