Cos'è Deno e cosa risolve
Cos'è Deno, il runtime con permessi espliciti e TypeScript nativo: cosa risolve rispetto a Node, i limiti della compatibilità npm e se conviene migrare.
Installi un pacchetto npm per formattare una data, e con lui arrivano quaranta dipendenze scritte da persone che non conosci. Ognuna gira nel tuo processo con i tuoi permessi: può leggere i tuoi file, aprire connessioni di rete e leggere le tue chiavi API. In Node non c'è nessun modo di impedirglielo. Deno è nato principalmente per questo. In questo articolo trovi cosa risolve davvero, dove sta il limite della compatibilità npm e se conviene passarci.
Cos'è
Deno è un ambiente di esecuzione per JavaScript e TypeScript creato da Ryan Dahl, lo stesso autore di Node, per correggere alcuni difetti strutturali che Node si porta dietro dal 2009.
Non è un fork di Node né un framework: è un binario separato, scritto in Rust, che usa lo stesso motore V8 ma ha fatto scelte diverse su sicurezza, moduli e strumenti. Nel 2018 Dahl ha tenuto un intervento intitolato "10 cose di cui mi pento in Node.js": Deno è, in larga parte, quella lista trasformata in codice.
I permessi: la differenza che conta davvero
Se devi ricordare una cosa sola di Deno, è questa.
Un programma Node, quando lo avvii, può fare tutto quello che puoi fare tu. Leggere l'intero disco, aprire socket, lanciare processi, leggere le variabili d'ambiente. Non esiste un livello intermedio tra "non eseguo questo script" e "questo script ha pieno accesso alla mia macchina".
Deno parte dal presupposto opposto: di default il codice non accede a niente. Niente rete, niente file system, niente variabili d'ambiente, niente sottoprocessi. Ogni accesso va concesso esplicitamente sulla riga di comando.
# Nessun accesso: se lo script prova a leggere un file, si ferma
deno run app.ts
# Solo rete e solo lettura della cartella corrente
deno run --allow-net --allow-read=./dati app.ts
# Solo verso un host specifico
deno run --allow-net=api.example.com app.ts
Se il programma tenta qualcosa che non gli hai concesso, Deno lo interrompe e te lo dice:
error: Requires read access to "/etc/passwd", run again with the --allow-read flag
Il valore pratico si vede con le dipendenze. Uno script che formatta date non ha nessun motivo di aprire una connessione di rete: se ci prova, con Deno lo scopri subito invece di scoprirlo mai. È una difesa concreta contro la categoria di attacchi alla catena di fornitura che ogni anno colpisce npm, dove un pacchetto popolare viene compromesso e la versione nuova esfiltra variabili d'ambiente.
Va detta anche la limitazione: i permessi sono a livello di processo, non di pacchetto. Se la tua applicazione ha bisogno di --allow-net per funzionare, quel permesso vale anche per le dipendenze che gira dentro lo stesso processo. Deno riduce molto la superficie, non la azzera. Ma passare da "tutto sempre" a "solo la rete, solo verso questo host" è comunque un salto enorme, ed è la ragione per cui vale la pena conoscerlo anche se poi resti su Node. Il tema più ampio è in cos'è la cybersecurity.
TypeScript senza configurazione
In Node, far girare TypeScript ha storicamente significato un tsconfig.json, il pacchetto typescript, uno strumento per l'esecuzione diretta e un passaggio di build. Node recente ha aggiunto la capacità di eseguire file .ts togliendo i tipi, che copre molti casi ma resta una funzionalità arrivata dopo.
In Deno scrivi il file e lo esegui:
deno run main.ts
Niente tsconfig.json obbligatorio, niente dipendenza da installare, niente cartella dist. I tipi vengono controllati e il codice gira. Non è una rivoluzione concettuale — è meno attrito, ripetuto tutti i giorni, e su un progetto nuovo si nota.
Il toolchain integrato
L'altra scelta che cambia la vita quotidiana: gli strumenti che in Node installi uno per uno, in Deno ci sono già.
deno fmt # formattatore
deno lint # linter
deno test # esecuzione dei test
deno check # controllo dei tipi
deno bench # benchmark
deno compile # eseguibile singolo, senza runtime installato
Nessuna dipendenza di sviluppo, nessun file di configurazione da copiare da progetto a progetto, nessuna discussione su quale formattatore usare. Chi ha passato un pomeriggio a far andare d'accordo linter e formattatore capisce il punto.
deno compile merita una menzione a parte: produce un binario autonomo che gira su una macchina dove Deno non è installato. Per uno strumento da riga di comando da distribuire, è comodissimo.
Sul tema dei test in generale, vedi cosa sono i test software.
La libreria standard
Deno ha una libreria standard ufficiale, revisionata e versionata insieme al runtime: gestione di file e percorsi, formati di dati, utilità HTTP, funzioni crittografiche, strumenti per i test.
L'idea è coprire ciò per cui in Node si installa un micro-pacchetto. Meno dipendenze esterne significa meno superficie di attacco e meno manutenzione. Non copre tutto — per un ORM o un framework completo installi comunque qualcosa — ma il livello base è coperto senza toccare npm.
Deno ha anche adottato le API web standard dove possibile: fetch, Request, Response, URL, AbortController. Codice scritto per il browser spesso gira in Deno senza modifiche, e questo vale anche verso i runtime edge, che sulle stesse API sono costruiti.
La compatibilità con npm: c'è, ma va capita
All'inizio Deno rifiutava npm per scelta, importando moduli direttamente da URL. È stata la decisione che più ne ha rallentato l'adozione, e infatti è stata rivista: oggi Deno supporta i pacchetti npm.
import express from "npm:express@4";
import { z } from "npm:zod";
Funziona per la grande maggioranza dei pacchetti puri JavaScript. Dove le cose si complicano:
- I moduli nativi compilati in C++ per Node possono non funzionare. Sono relativamente pochi ma spesso importanti: driver di database, librerie di crittografia, elaborazione di immagini.
- Le API interne di Node meno documentate hanno gradi di copertura variabili. Un pacchetto che ci si appoggia può rompersi in modi poco chiari.
- Gli strumenti di build dell'ecosistema Node presuppongono spesso Node, non solo un runtime compatibile.
La regola realistica: la libreria che ti serve probabilmente funziona, ma non puoi darlo per scontato e lo scopri provando. In Node quella domanda non te la poni mai, ed è un costo che va messo nel conto.
Node e Deno a confronto
| Node | Deno | |
|---|---|---|
| Permessi | Accesso completo, sempre | Espliciti, negati di default |
| TypeScript | Supporto aggiunto in seguito | Diretto, senza configurazione |
| Moduli | CommonJS ed ES Modules | Solo ES Modules |
| Strumenti | Da installare separatamente | Formattatore, linter, test inclusi |
| Libreria standard | Minima, si integra con npm | Ampia e ufficiale |
| Pacchetti npm | Nativi | Supportati, con qualche limite |
| Ecosistema | Il più grande al mondo | Molto più piccolo |
| Offerte di lavoro | Ovunque | Rare |
| Hosting | Supportato ovunque | Supportato a macchia di leopardo |
Cosa fa perdere ore a chi arriva da Node
Dimenticare un permesso. Il messaggio di errore è chiaro, ma in un container o in una pipeline CI dove non leggi l'output in tempo reale sembra un crash inspiegabile. Elenca i permessi nella configurazione o in un compito deno task invece di ricordarteli a mente.
--allow-all per stanchezza. Dopo il terzo errore di permesso la tentazione è mettere -A e andare avanti. Lo fai in sviluppo, finisce in produzione e hai buttato via l'unica cosa per cui avevi scelto Deno.
Aspettarsi che ogni pacchetto npm funzioni. Verifica le dipendenze critiche — soprattutto driver di database e librerie con parti native — prima di impegnarti su un progetto, non a metà.
Cercare __dirname o require. Non esistono: Deno è solo ES Modules. Si usano import.meta.dirname e import.
Dare per scontato il supporto dell'hosting. È il punto più sottovalutato: prima di scegliere Deno per un progetto, controlla che la piattaforma su cui vuoi pubblicare lo supporti. Deno Deploy è la scelta naturale, molte piattaforme lo reggono tramite Docker o su un VPS, ma i runtime gestiti pensati per Node possono non offrirlo affatto. Scoprirlo il giorno del deploy è una brutta giornata.
Vale la pena migrare?
Rispondo senza giri di parole.
Per un progetto esistente in Node che funziona: quasi mai. La migrazione costa tempo reale — dipendenze da verificare, strumenti di build da rifare, pipeline da riscrivere — e in cambio ottieni benefici che nella maggior parte dei casi non risolvono un problema che stai avendo davvero. "È più moderno" non è un movente sufficiente per toccare qualcosa che sta in piedi.
Per un progetto nuovo: può avere senso, in casi abbastanza precisi. Uno strumento da riga di comando da distribuire come binario. Uno script che esegue codice o dipendenze di cui non ti fidi del tutto. Un servizio piccolo, con poche dipendenze, dove il toolchain integrato ti fa risparmiare davvero un pomeriggio di configurazione. Un progetto interamente TypeScript senza passaggi di build.
Quello che va detto con onestà è la dimensione delle cose. L'ecosistema di Deno è una frazione di quello di Node. Le risposte su Stack Overflow sono meno, le guide sono meno, e quando sbatti contro un problema strano è più probabile che tu sia il primo a documentarlo. Sul mercato del lavoro il divario è ancora più netto: le offerte che chiedono Deno si contano, quelle che chiedono Node sono ovunque. Se stai imparando il backend JavaScript per lavorarci, la scelta non è in discussione — impari Node.
Questo non rende Deno un esercizio accademico: è un runtime serio, usato in produzione, con idee che hanno influenzato anche Node stesso (il supporto TypeScript e il modello di permessi sperimentale in Node arrivano da lì). Vale la pena conoscerlo. Vale la pena usarlo nei casi giusti. Non vale la pena adottarlo perché è nuovo.
In sintesi
Deno è un runtime JavaScript e TypeScript dello stesso autore di Node, pensato per correggerne i difetti strutturali.
La sicurezza basata su permessi espliciti è la differenza filosofica più importante: di default il codice non tocca rete, file e variabili d'ambiente, e ogni accesso si concede a mano.
TypeScript gira diretto e il toolchain è integrato: formattatore, linter, test e compilazione in un binario, senza installare nulla.
La compatibilità npm esiste ma ha dei limiti, soprattutto sui moduli nativi. Le dipendenze critiche vanno verificate prima, non dopo.
Migrare un progetto Node esistente quasi mai conviene. Per un progetto nuovo può valerne la pena, sapendo che ecosistema, hosting e mercato del lavoro sono enormemente più piccoli.
Per il confronto a tre con il terzo protagonista, vedi Node, Deno o Bun: quale scegliere nel 2026. Se il framework per le API in Node ti manca ancora, parti da cos'è Express; per il quadro generale delle scelte tecnologiche, come scegliere lo stack.