Node.js 26が10月28日にLTS入り!Node 22から24を飛ばして上げる前に確認した5つのこと
🙌 結論から
Node.js 26 は2026年10月28日に LTS になるので、Node 22 を使っている本番は、24 を経由せず 26 に直接上げる計画で準備を始めるのがおすすめです!
Node 22 はすでにメンテナンス LTS に入っていて、サポートは2027年4月30日で終わります。
一方で Node 26 は、2029年4月30日までサポートされる予定です。
私は仕事の Laravel+Vite のプロジェクトでフロントのビルドに Node 22 を使っているので、LTS 入りの前に「上げたら何が壊れそうか」を先に洗い出しておきました。
結果、一番引っかかりそうなのはネイティブアドオンの再ビルドと、fetch のヘッダーの扱いでした(・_・;)
👀 Node 22のままでいいのか気になった理由
きっかけは、Node.js のリリースの仕組みが変わると知ったことです。
これまで Node.js は年に2回メジャー版を出して、偶数版だけが LTS になる流れでした。
それが Node.js 27 からは年1回のリリースになり、すべてのメジャー版が LTS になる、と公式のリリースページに書かれています。
つまり Node 26 は、旧方式の最後のメジャー版なんですよね。
「次の LTS は来年の秋まで出ない」と分かった時点で、今 22 のまま止まっていると、上げるタイミングを逃しそうだなと思いました🤔
📅 サポート期限を並べると26に直行が楽だった
Node.js の公式リリーススケジュールから、手元で関係あるバージョンだけ抜き出すとこうなります。
| バージョン | 状態(2026年10月時点) | アクティブ LTS 開始 | メンテナンス開始 | サポート終了 |
|---|---|---|---|---|
| Node 22 | メンテナンス LTS | 2024-10-29 | 2025-10-21 | 2027-04-30 |
| Node 24 | アクティブ LTS | 2025-10-28 | 2026-10-20 | 2028-04-30 |
| Node 26 | Current | 2026-10-28 | 2027-10-20 | 2029-04-30 |
Node 24 は10月20日でメンテナンスに移るので、今から 24 に上げても、サポートの残りは26より1年短いです。
どうせ一度は動作確認をするなら、残りが一番長い26に1回で上げる方が手間が少ない、というのが私の判断でした。
ただし、LTS になる10月28日までは Current なので、本番の切り替えは LTS 入りを待ってからにしています。
それまでは、ローカルと CI だけ26で回して壊れる所を探す期間、という位置づけです💡
🔧 私の確認手順はこれ
ここはそのまま真似できる形で書いておきます(`・ω・´)
1. mise で22と26を並べて入れる
mise の記事で書いたとおり、私は Node のバージョンを mise で管理しています。
作業ブランチだけ .mise.toml を書き換えて、26で動かします。
[tools]
node = "26"
main ブランチに戻れば22に戻るので、行ったり来たりしながら確認できるのが楽です👍
2. ネイティブアドオンを再ビルドする
rm -rf node_modules
npm ci
npm rebuild
Node のメジャー版が変わると、C++ で書かれたアドオンは作り直しが必要です。
画像の変換に使っている sharp や、パスワードのハッシュに使う bcrypt のような依存があると、古いままだと「different Node.js version using NODE_MODULE_VERSION」というエラーで起動しません。
3. 削除された API を grep する
grep -rn "_stream_" --include="*.js" --include="*.ts" src/ scripts/
grep -rn "writeHeader" --include="*.js" --include="*.ts" src/ scripts/
Node 26 では、_stream_readable のような内部のストリームモジュールと、res.writeHeader() が削除されています。
自分のコードにはまず無いのですが、社内の古いスクリプトに1件だけ残っていたので、grep する価値はありました。
4. 非推奨の警告を出しながらテストを回す
NODE_OPTIONS="--pending-deprecation --trace-deprecation" npm test
警告が出た依存は、テストが通っていても今のうちにバージョンを上げておきます。
5. CI と Dockerfile のバージョン指定を洗い出す
.nvmrc、.mise.toml、package.json の engines、GitHub Actions の node-version、Dockerfile の FROM node:22 は、どれか1つだけ上げ忘れるとローカルと CI で結果が変わります。
私は grep -rn "22" .nvmrc .mise.toml package.json .github/ Dockerfile で、22と書いてある所を全部出してから直すようにしています✨
🤔 ハマりやすいところと回避策
ひとつ目は、fetch のヘッダーに改行が混ざっているケースです。
Node 26 の fetch は undici 8 になり、ヘッダーの値に改行(\n や \r)が入っていると、黙って取り除かずに TypeError を出すようになりました。
import { readFileSync } from 'node:fs';
// ファイルの末尾に改行が入っていると、Node 26 では TypeError になる
const token = readFileSync('.token', 'utf8');
await fetch(url, { headers: { Authorization: `Bearer ${token}` } });
// 読み込んだ時点で trim() しておく
const safeToken = readFileSync('.token', 'utf8').trim();
トークンをファイルや環境変数から読むスクリプトは、末尾の改行が混ざりやすいので、ここは真っ先に疑っていいと思います(T_T)
ふたつ目は、22から上げると24の変更もまとめて来ることです。
24を飛ばすと、Node 24 で入った変更も一緒に受けることになります。
たとえば OpenSSL 3.5 になったことで、2048ビット未満の RSA 鍵は使えなくなっています。
古い社内システムとの通信で、短い鍵を使った証明書が残っていないかは確認しておきたいところです。
Node 24 で削除された API のいくつかは、公式の移行ガイドに codemod が用意されています。
npx codemod run @nodejs/dirent-path-to-parent-path
dirent.path を dirent.parentPath に書き換えてくれるもので、こういう機械的な置き換えは手で直すより安全です🙌
みっつ目は、"type": "module" のパッケージで拡張子を省いた CommonJS の読み込みです。
Node 26 では、ESM のパッケージの中で拡張子なしの CommonJS ファイルを読み込む例外が無くなりました。
古い設定ファイルを拡張子なしで import していると読み込めなくなるので、.cjs か .js を付けておきます。
🔗 関連記事と使い分け
- mise で Node.js と PHP のバージョン管理:今回のように22と26を行き来しながら確認するときの土台です
- Node.js 26 の Temporal API:26に上げたら使えるようになる新機能の話です。今回は「上げる前の確認」、あちらは「上げたあとに使う物」です
- Node.js 24 の TypeScript そのまま実行:22から直行すると、この機能も一緒に手に入ります。tsx を外せるか検討するきっかけにもなりました
パパ系Webエンジニア〜愛用ガジェット一覧 🛍️
この記事を書いている作業環境のガジェットを楽天ROOMにまとめています ✨ 在宅エンジニアのデスク作りの参考にどうぞ 🙌
🙌 まとめ
Node 22 を使っているなら、10月28日の Node 26 の LTS 入りに合わせて、24を飛ばして26に上げる準備を始めておくのがかなり楽です。
最初は「22でまだ動いてるし…」と後回しにしかけましたが、サポート期限を表に並べたら、先延ばしするほど損だと気づきました(^o^)/
LTS 入りまではローカルと CI で壊れる所を探して、本番は LTS になってから切り替える、という順番がおすすめです!
※ バージョン番号・料金・機能は今後も変わる可能性があります。最新情報は Node.js の公式サイト をご確認ください👀