
2025 年 10 月 16 日(日本時間)にリリースされた Node.js v25 の主な変更点を紹介します。
- V8 のアップデートによる高速化
- --allow-net オプションによるネットワークアクセスの制限
- Web Storage API がフラグなしで利用可能に
- ErrorEvent の追加
- v25 の EOL 予定について
- まとめ
- 参考記事
記事内のサンプルコードはすべて以下のリポジトリにあります。
V8 のアップデートによる高速化
JavaScript エンジンの V8 が v13.6 から v14.1 にアップデートしました。
以下の変更により実行速度が向上しました。
JSON.stringifyの高速化- WebAssembly と JIT パイプラインの最適化
以下の記事によると、JSON.stringifyのパフォーマンスを 2 倍以上に向上させたと書かれています。
v8.dev
オブジェクトのシリアライズによって副作用が発生しないことを V8 が認識できる場合、JSON.stringifyのパフォーマンスが大幅に向上します。
ただし、以下のような場合は副作用が発生する可能性があるため、パフォーマンスの向上は見込めません。
- オブジェクトに
toJSONメソッドが定義されている場合 replacer引数が指定されている場合space引数が指定されている場合
これらについては MDN のドキュメントに詳しく書かれています。 developer.mozilla.org
以下のサンプルコードは MDN のドキュメントから引用したreplacer引数を使った例です。
function replacer(key, value) { // プロパティをフィルターする if (typeof value === "string") { return undefined; } return value; } const foo = { foundation: "Mozilla", model: "box", week: 45, transport: "car", month: 7, }; JSON.stringify(foo, replacer); // '{"week":45,"month":7}'
以下はspace引数を使った例です。よく使うのではないでしょうか。
const obj = { a: 1, b: 2, c: 3 }; JSON.stringify(obj, null, 2); /* `{ "a": 1, "b": 2, "c": 3 }` */
以下はtoJSONメソッドを定義した例です。
const obj = { a: 1, b: 2, toJSON() { return { a: this.b, b: this.a }; }, }; JSON.stringify(obj); // '{"a":2,"b":1}'
これらを利用しないように気をつけていれば、JSON.stringifyのパフォーマンスが向上します。
--allow-net オプションによるネットワークアクセスの制限
Node.js v20 で Process-based Permission Model という機能が導入されました。 shisama.hatenablog.com
上記の記事で紹介したとおり、すでに --allow-fs-writeオプションなどでファイルシステムなどのアクセスを制限することができますが、--allow-netオプションを使うことでネットワークアクセスも制限できるようになりました。
Node.js の実行時に--allow-netオプションを指定します。
$ node --permission --allow-net index.js
これにより、ネットワークアクセスが許可されます。
--allow-netオプションを指定しない場合、ネットワークアクセスは拒否されます。
以下はhttp://example.comにアクセスしようとした場合の例です。
const http = require("node:http"); // Attempt to bypass the permission const req = http.get("http://example.com", () => {}); req.on("error", (err) => { console.log("err", err); });
以下のように--permissionオプションのみで実行すると、ネットワークアクセスが拒否され、エラーが発生します。
$ node --permission index.js
err Error: getaddrinfo ERR_ACCESS_DENIED example.com
at lookup (node:dns:234:32)
at emitLookup (node:net:1446:5)
at defaultTriggerAsyncIdScope (node:internal/async_hooks:472:18)
at lookupAndConnectMultiple (node:net:1445:3)
at node:net:1391:7
at defaultTriggerAsyncIdScope (node:internal/async_hooks:472:18)
at lookupAndConnect (node:net:1390:5)
at Socket.connect (node:net:1285:5)
at Object.connect (node:net:245:17)
at Agent.createConnection (node:\_http_agent:240:16) {
errno: undefined,
code: 'ERR_ACCESS_DENIED',
syscall: 'getaddrinfo',
hostname: 'example.com'
}
これにより、意図しないネットワークアクセスを行うことを防止できます。
Web Storage API がフラグなしで利用可能に
Web Storage API (sessionStorage/localStorage)がフラグなしで利用可能になりました。
developer.mozilla.org
Web Storage API は Node.js v22.4.0 以降で利用可能になっていましたが、--experimental-webstorageフラグを付けて実行する必要がありました。
Node.js v25.0.0 からはフラグなしで利用可能になりました。
Web Storage API はグローバルオブジェクトとして提供されるため、import 文や require 文でインポートする必要はありません。
以下は sessionStorage の例です。
// sessionStorage にデータを保存 sessionStorage.setItem("key", "value"); // sessionStorage に保存したデータを取得 let data = sessionStorage.getItem("key"); console.log(data); // 'value' // sessionStorage に保存したデータを削除 sessionStorage.removeItem("key"); console.log(sessionStorage.getItem("key")); // null // sessionStorage からすべての保存したデータを削除 sessionStorage.clear();
以下は localStorage の例です。
localStorage.setItem("foo", "bar"); const foo = localStorage.getItem("foo"); console.log(foo); // 'bar' localStorage.removeItem("foo"); console.log(localStorage.getItem("foo")); // null localStorage.clear();
localStorage は永続的にデータを保存するため、ファイル名を指定する必要があります。以下の例では、localStorageFileというファイルにデータが保存されます。
$ node --localstorage-file=./localStorageFile index.js
また、Web Storage API を無効にするには --no-webstorageオプションを使用します。
--no-webstorageオプションを指定して実行すると、Web Storage API を使用しようとしたときにエラーが発生します。
$ node --no-webstorage index.js
node:internal/modules/esm/translators:464
throw new ERR_UNKNOWN_BUILTIN_MODULE(url);
^
Error [ERR_UNKNOWN_BUILTIN_MODULE]: No such built-in module: node:storage
at ModuleLoader.builtinStrategy (node:internal/modules/esm/translators:464:11)
at #translate (node:internal/modules/esm/loader:564:20)
at afterLoad (node:internal/modules/esm/loader:614:29)
...
ErrorEvent の追加
Node.js v25 で ErrorEventクラスが追加されました。
ErrorEventクラスは、イベントエミッターで発生したエラーを表すために使用されます。
以下のようにEventTargetに対してErrorEventが発生したときに、そのエラー情報を取得できます。
const eventTarget = new EventTarget(); eventTarget.addEventListener("error", (event) => { console.log("Message: ", event.error.message); console.log("Stack: ", event.error.stack); console.log("Name: ", event.error.name); console.log("Code: ", event.error.code); }); const error = new Error("error message"); eventTarget.dispatchEvent(new ErrorEvent("error", { error }));
また独自のカスタムエラーを作成して、ErrorEventで発生させることもできます。
class CustomErrorEvent extends Event { constructor(message) { super("customerror"); this.message = message; } } const eventTarget = new EventTarget(); eventTarget.addEventListener("customerror", function (event) { console.error("Message:", event.message); }); const errorEvent = new CustomErrorEvent("This is a custom error message"); eventTarget.dispatchEvent(errorEvent); // Message: This is a custom error message
v25 の EOL 予定について
今回紹介した Node.js v25 は 2026 年 6 月でメンテナンスが終了する予定です。 今回紹介した機能は次の v26(2026 年 4 月リリース予定)でも利用可能なので、そちらへ移行するようにしてください。 日程についての最新の情報は以下のリポジトリをご確認ください。
まとめ
今回は Node.js v25 の主な変更点を紹介しました。
長年の懸案事項だった JSON.stringify の高速化は結構嬉しいのではないでしょうか。fast-json-stringifyといったライブラリもあるぐらいです。
また、--allow-netオプションによるネットワークアクセスの制限もセキュリティ面で便利です。
Web Storage API もフラグなしで利用可能になったので、ブラウザと同じコードが書きやすくなりました。
Web 標準化に向けた取り組みが継続されていたり、他の JavaScript ランタイムの良いところを取り入れたりと、ここ数年の流れに沿った正当なアップデートが続いている印象です。
長くなってしまいましたが、最後までお読みいただきありがとうございました。不備や質問がございましたら、@shisama_までメンションするかブコメなどでコメントください。