PAS7 Studio
Torna a tutti gli articoli

Node.js 25: cosa c’è davvero di nuovo, cosa si è rotto nell’ecosistema e se conviene aggiornare

Recensione “dal mondo reale” di Node.js 25 (Current): V8 14.1 e performance, Web Storage abilitato di default (con rotture su test/tooling), permission model con --allow-net, module compile cache portabile (ora stabile), require(esm) marcato stabile, http.setGlobalProxyFromEnv(), fs.watch con ignore, e SEA costruibile in un solo step con node --build-sea. Punti di vista di developer con link + verdetto chiaro: aggiornare ora o aspettare LTS.

Node.js 25 — cambiamenti, reazioni degli sviluppatori e decisione se aggiornare

Ci sono due tipi di upgrade Node. Il primo è “alzo la versione, tutto ok”. Il secondo è “alzo la versione e ora il backend mi spara errori da browser”. Node.js 25 ha fatto vivere a molti team il secondo scenario.

Con Docusaurus sembra surreale: DOMException [SecurityError]: Cannot initialize local storage without a --localstorage-file path durante docusaurus build.[1] Sintomi simili compaiono anche nel mondo CLI (Shopify) e nei test runner (Jest/Vitest).[2][3][4]

Qui il punto è: non è un “bug random nel tuo repo”. È una conseguenza del fatto che Node 25 ha abilitato Web Storage di default, ma localStorage su Node non è identico al browser (file-backed, quota, comportamento shared, niente cifratura).[7][5]

Eppure sarebbe un errore ridurre Node 25 alla saga di Web Storage. 25.4.0 e 25.5.0 portano miglioramenti maturi (require(esm) stabile, compile cache stabile, --build-sea) che riducono il dolore delle migrazioni e migliorano DX — se li adotti in modo controllato.[9][10][12]

Caso reale: docusaurus build fallisce su Node 25.x per localStorage SecurityError.[1]

Screenshot della sezione prologue

Node 25 è una linea Current (odd). Si muove veloce: prima arrivano nuovi default, poi l’ecosistema trova edge case, poi escono release di stabilizzazione.[6]

  • 25.0.0: V8 14.1, focus performance, web API, permission model, Web Storage abilitato di default.[8]

  • 25.2.0: emerge la regressione localStorage senza --localstorage-file (nodejs/node #60704) che colpisce toolchain.[5]

  • 25.4.0: require(esm) diventa stabile, module compile cache diventa stabile, arrivano “ops goodies” come http.setGlobalProxyFromEnv().[9]

  • 25.5.0: arriva node --build-sea — SEA “un solo step dal core”, più piccole ma utili modifiche ops/monorepo.[12]

Solo i concetti indispensabili per capire Node 25 senza perdersi nei flag.

  • Current vs LTS: odd major = Current, even major = LTS. Node raccomanda esplicitamente Active/Maintenance LTS per production.[6]

  • Web Storage in Node: localStorage su Node è file-backed (--localstorage-file), non cifrato, con quota 10MB, e shared nel processo server.[7]

  • Permission Model: permessi di processo (--permission, --allow-net, --allow-fs-read) come “cintura”. Non è un sandbox e non protegge da malicious code.[11]

  • require(esm): ponte tra CJS ed ESM. 25.4.0 segna il meccanismo come stabile (cambia la strategia di migrazione).[9]

  • Module compile cache: code cache su disco per accelerare la compilazione del grafo moduli, con modalità portable.[10]

  • SEA: single executable applications. In 25.5.0 diventa molto più semplice con --build-sea.[12][13]

  • Ops QoL: proxy da env (http.setGlobalProxyFromEnv()), ignore nei watcher (fs.watch({ ignore: ... })).[14][15]

25.0.0 è la base: V8 14.1, performance, web API e pulizia legacy. La vera “maturità” si vede in 25.4/25.5.[8][9][12]

14.1

Le note 25.0.0 evidenziano miglioramenti performance, inclusi su JSON.stringify.[8]

abilitato di default

Cambio di default che ha causato regressioni nell’ecosistema (tool/test/CLI).[8][5][4]

permissions

Permissions come parte “secure-by-default”, con limiti chiari (non sandbox).[11]

deprecations

I major release spesso fanno male per rimozioni di API deprecated (SlowBuffer).[16]

Segnale visivo dell’inizio linea: Node.js 25.0.0 (Current).[8]

Screenshot della sezione node-25-0

Il problema non è che Web Storage sia “cattivo”. Il problema è che è cambiato il default, e parte del tooling ha iniziato a eseguire rami non testati su server.

nodejs/node #60704 descrive la regressione 25.2.0: “Cannot initialize local storage without a --localstorage-file path”, e collega toolchain rotti (webpack/jest/html-webpack-plugin).[5]

Vitest #8757 mostra un altro failure mode: in Node 25 localStorage non è più undefined e questo può rompere i mock.[4] Jest #15888 aggiunge un altro caso: test runner che fallisce con SecurityError su Node 25.2.0.[3]

Workaround rapido (se non ti serve): disabilitare temporaneamente Web Storage con il flag documentato nelle globals docs.[7]

Lezione per i team: anche se “non usi localStorage”, le dipendenze potrebbero farlo. Tenere Current in CI è un modo sano per intercettare sorprese.[6]

nodejs/node #60704: regressione 25.2.0 — localStorage senza --localstorage-file può far fallire la build.[5]

Screenshot della sezione webstorage-saga

Vitest #8757: Web Storage abilitato di default può rompere i test per via delle nuove aspettative su localStorage.[4]

Screenshot della sezione webstorage-saga

Jest #15888: fallimento con SecurityError su Node 25.2.0.[3]

Screenshot della sezione webstorage-saga

Una di quelle modifiche che non fa rumore, ma ti salva settimane in repo dove CJS ed ESM devono convivere.

1) Perché conta

Con più pacchetti ESM-only, i progetti CJS incontrano spesso ERR_REQUIRE_ESM. Un ponte più maturo permette migrazioni progressive invece di un “big bang”.[9][22]

2) Pattern pratico: adattatore per default export

JS
const pkg = require('some-esm-only-package');
const api = pkg?.default ?? pkg;

module.exports = api;

È un modo standard per gestire il namespace object quando ESM espone un default export.[22]

3) Cosa significa per i team

Stabilizzare in Current prepara la strada all’ecosistema. LTS+Current in CI ti fa prendere valore senza rischio prod.[6]

Marker visivo della fase “stabilizzazione”: Node.js 25.4.0 (Current).[9]

Screenshot della sezione require-esm

La compile cache è un’ottimizzazione. È utile dove hai molti cold start o un grafo moduli grande (tool, CLI, worker).

Le docs node:module hanno una sezione concreta sulla portabilità: se cambiano gli absolute path, l’efficacia può scendere; portable aiuta a riusare la cache in più scenari.[10]

Esempio minimo:

JS
import module from 'node:module';

module.enableCompileCache({ directory: '.node-compile-cache', portable: true });

In CI, gestisci esplicitamente la directory cache per non perderla tra i run.

Docs: sezione sulla portabilità + modalità portable con esempi API/env.[10]

Screenshot della sezione compile-cache

Una delle modifiche più “product”: costruire un single executable non sembra più un rituale con injector esterno.

1) Idea base

25.5.0 introduce --build-sea e consolida i passi SEA in un singolo step disponibile dal core.[12][13]

BASH
echo 'console.log("Hello")' > hello.js
echo '{ "main": "hello.js", "output": "sea" }' > sea-config.json
node --build-sea sea-config.json
./sea

2) Takeaway pratico

Per CLI/agenti: meno dipendenze e meno step fragili. Ma testa su OS/shell target (ci sono segnalazioni su Windows Command Prompt).[21]

3) Consiglio team

SEA è per la distribuzione, non sostituisce un modello di sicurezza. Continua a curare dipendenze e supply chain. Tieni Current in CI per intercettare sorprese.[6]

25.5.0: sezione --build-sea con esempio comandi nelle release notes ufficiali.[12]

Screenshot della sezione sea-build-sea

Non è una headline feature, ma riduce “micro wrapper” custom nei progetti con CI aziendale dietro proxy.

Snippet minimo:

JS
import http from 'node:http';

const restore = http.setGlobalProxyFromEnv();
// restore();

http.setGlobalProxyFromEnv()

Utile quando il proxy è configurato via env (CI/reti enterprise).[14]

chiamalo all’avvio

Evita chiamate nel mezzo delle request; fallo nel bootstrap di service/CLI.[14]

più coerente

Meno probabilità che ogni client HTTP venga configurato in modo diverso.

Docs: http.setGlobalProxyFromEnv([proxyEnv]) + sezione built-in proxy support.[14]

Screenshot della sezione ops-qol

In repo grandi, i watcher diventano un problema (node_modules, .git, output generati). Le docs descrivono ignore come opzione che accetta glob/RegExp/function/array.[15]

Esempio minimo:

JS
import { watch } from 'node:fs';

watch('.', {
  recursive: true,
  ignore: ['**/node_modules/**', '**/.git/**'],
}, () => {});

I major release spesso fanno male per finalizzazione deprecations. SlowBuffer è l’esempio perfetto.[16]

1) Cosa è successo a SlowBuffer

Le deprecations docs indicano che SlowBuffer è stato rimosso e suggeriscono Buffer.allocUnsafeSlow(size).[16]

2) Come appare in produzione

C’è un caso reale: backend che crasha su Node 25.x perché una dependency chain tocca SlowBuffer.prototype.[17]

3) Quick scan prima dell’upgrade

BASH
rg -n "\bSlowBuffer\b" .

Poi pnpm why / npm ls per trovare la catena legacy.

Una checklist breve e realistica per i team.

  • 1) Prod su LTS, Node 25 in CI (matrice LTS + Current).[6]

  • 2) Esegui i test con Web Storage disabilitato per isolare velocemente: NODE_OPTIONS="--no-experimental-webstorage".[7]

  • 3) Se si è rotto, guarda dove si è rotto già: nodejs/node #60704, Vitest #8757, Jest #15888.[5][4][3]

  • 4) Se ti interessano le feature 25.4/25.5, provale prima in un esperimento separato (CLI/worker), non in prod “in un colpo”.[9][12]

  • 5) Per monorepo, aggiusta i watcher: fs.watch({ ignore }) riduce rumore e load.[15]

  • 6) Per CI dietro proxy, prova http.setGlobalProxyFromEnv() come soluzione globale semplice.[14]

Niente ideologia: Node 25 è ottimo come “detector” in CI, ed è utile per alcuni prodotti (CLI/agenti). Per i backend in produzione, LTS spesso vince per stabilità.

Meglio aspettare / restare su LTS

Node raccomanda Active/Maintenance LTS per production.[6]

Aggiungilo ora

Node 25 fa emergere regressioni (Web Storage) e cleanup legacy (SlowBuffer) senza rischio incidenti in prod.[5][16]

Upgrade sensato

--build-sea (25.5.0) + maturità 25.4.0 sono un vero boost DX. Testa su OS/shell target.[12][21]

Current può “mordere”

Current esiste per far adattare l’ecosistema. Se rompe la giornata, tienilo in CI e lascia prod su LTS.[6]

Node.js 25 è una release LTS?

No. È Current (odd major). Node dice chiaramente che in production dovresti usare Active o Maintenance LTS.[6]

Perché Web Storage ha fatto così tanto rumore?

Perché è cambiato il default. `localStorage` è diventato disponibile senza flag sperimentali, ma su Node la semantica è diversa (file, 10MB, shared). Il tooling ha rotto assunzioni.[7][5][4]

Come sbloccare CI velocemente se localStorage rompe tutto?

Disabilita temporaneamente Web Storage con `NODE_OPTIONS="--no-experimental-webstorage"` o tramite flag runtime. È documentato nelle globals e citato come workaround.[7][5]

SEA con --build-sea è già usabile?

Sì, ma testa su OS/shell target. C’è un issue specifico su Windows Command Prompt.[21] Per dettagli vedi le SEA docs.[13]

Fonti in ordine di apparizione (posizione in lista = numero [n]).

0

Strategia più sana: prod su LTS, Node 25 in CI come detector di regressioni, e adozione graduale delle feature 25.4/25.5 (require(esm), compile cache, build-sea) in esperimenti isolati (CLI/worker). DX su, rischio giù.

Articoli correlati

growth

AI SEO / GEO nel 2026: i tuoi prossimi clienti non sono umani — sono agenti

La ricerca sta passando dai click alle risposte. Bot e agenti AI scansionano, citano, raccomandano e sempre più spesso acquistano. Scopri cosa significa AI SEO / GEO, perché la SEO classica non basta più e come PAS7 Studio aiuta i brand a vincere visibilità nel web “agentico”.

blogs

Il chip Apple più potente? M5 Pro e M5 Max battono i record

Analisi di Apple M5 Pro e M5 Max aggiornata a marzo 2026. Spieghiamo perché questi chip possono essere considerati i SoC professionali per notebook più potenti di Apple, come si posizionano contro M4 Pro, M4 Max, M1 Pro, M1 Max e cosa mostrano rispetto ai concorrenti Intel e AMD.

telegram-media-saver

Tag automatici e ricerca per link salvati

Integra con GDrive/S3/Notion per tag automatici e ricerca veloce tramite API di ricerca

services

Sviluppo di bot e servizi di automazione

Sviluppo professionale di bot Telegram e automazione dei processi aziendali: chatbot, assistenti AI, integrazioni CRM, automazione dei flussi di lavoro.

Sviluppo professionale per la tua attività

Creiamo soluzioni web moderne e bot per le aziende. Scopri come possiamo aiutarti a raggiungere i tuoi obiettivi.