Node.jsは、ChromeのJavaScriptエンジンであるV8を単体で動かせるようにしたサーバーサイドの実行環境です。ブラウザの外でJavaScriptを走らせ、HTTPサーバー・バッチ処理・CLIツールまで同じ言語で書けます。この記事では、V8とlibuvの役割分担という仕組みの話から、2026年9月時点でどのバージョンを本番に置くべきかという版選定、標準モジュールだけでHTTPサーバー・テスト・TypeScript実行・権限制御まで到達する具体的な手順、そしてCommonJSとESモジュールの相互運用やフレームワーク・パッケージマネージャの選び分けまでを扱います。数値と日付は公式ドキュメントとリリース管理リポジトリの実測値に揃えました。
まとめ:版選定の結論と標準機能で足りる範囲
2026年9月時点で本番に置くべきはNode.js 24(Krypton)です。v22(Jod)は2025年10月21日にMaintenanceへ移行済みで、新規案件の既定にする理由はもうありません。v26は2026年5月5日リリースのCurrentで、2026年10月28日にLTS入りが予定されています。新規プロジェクトを今月立ち上げるなら、v24で始めてv26のLTS化後に上げる段取りが手戻りを最小にします。
もう一つの結論は、外部パッケージを入れる前に標準モジュールで足りるかを確認すべき、ということ。テストランナー(node:test)とTypeScriptの型ストリッピングはどちらもStability 2(Stable)に到達しており、テストフレームワークとトランスパイラを外せる場面が実際にあります。依存を1つ減らすことは、脆弱性対応の工数をそのぶん減らすことと同じです。HTTPクライアントのfetchとWebSocketクライアントも標準側に入っているため、この2つのために外部パッケージを足す判断も見直す余地があります。
採用判断の線引きは明快です。DB照会・外部API連携・ファイル入出力といった待ち時間主体の処理ならNode.jsが向きます。画像変換や大量データの数値計算のようにCPUを長時間占有する処理を主軸に据える設計なら、Node.jsを中心に置く判断は取りません。
2026年に入って手順が変わった箇所も先に挙げておきます。パッケージマネージャの版を固定するCorepackはv25.0.0以降の公式配布物に同梱されなくなりました。v24ではcorepack enableが通り、v26では通りません。もう1点、CommonJSのrequireからESモジュールを読む機能はv25.4.0で実験的な位置づけを離れており、モジュール方式の混在に対する回避策の書き方も変わっています。
Node.jsの実行モデルとV8・イベントループが処理を捌く仕組み
Node.jsの挙動を理解する近道は、「JavaScriptを実行する部分」と「入出力を待つ部分」が別のライブラリで動いていると知ることです。ここを押さえると、なぜシングルスレッドで数千接続を捌けるのか、なぜ一つの重い処理で全体が固まるのかが同じ理屈で説明できます。
V8とlibuvが担う役割の分担とシングルスレッドで捌ける理由
V8はJavaScriptを機械語へコンパイルして実行するエンジンで、Chromeと同じものが組み込まれています。一方、ファイル読み書き・ネットワーク・タイマーといった入出力を管理するのがC言語で書かれたlibuvです。JavaScriptのコードが走るスレッドは1本しかありませんが、libuvは裏でスレッドプールを持ち、ファイルI/OやDNS解決をそこへ逃がします。
このスレッドプールの既定サイズは4です。UV_THREADPOOL_SIZE環境変数で変更でき、上限値を含む仕様はNode.js公式のCLIドキュメントに記載されています。ファイル処理が並列に伸びないときは、まずこの4という数字を疑うのが順序として正しいです。
ノンブロッキングI/Oが有利な処理とCPU負荷で崩れる分岐点
Node.jsが得意なのは「待つ時間が長く、計算は軽い」処理です。DBへ問い合わせて結果を待つ、外部APIを叩いて応答を待つ、S3からファイルを取る。これらは待機中にイベントループが他のリクエストを処理できるため、1プロセスでも同時接続数を稼げます。
崩れるのは逆のケース。数十MBのJSONを同期的にパースする、画像をリサイズする、暗号化のハッシュを大量に回す。こうした処理はJavaScriptスレッドを占有し、その間に届いた全リクエストが待たされます。分岐点の目安は「1回の処理でイベントループを50ミリ秒以上止めるか」。止めるならnode:worker_threadsへ切り出すか、その処理だけ別サービスへ分離します。
npmとnode_modulesが前提にする依存解決の仕組みと落とし穴
Node.jsにはパッケージマネージャのnpmが同梱され、package.jsonに書いた依存をnode_modulesへ展開する仕組みです。バージョン指定はsemverで、キャレット付きの^4.18.2は「4系の範囲で最新」を意味します。つまり同じpackage.jsonでも、インストールした日によって入るバージョンが変わります。
ここが最大の落とし穴です。再現性を担保するのはpackage-lock.jsonのほうで、これをリポジトリに含め、CIではnpm installではなくnpm ciを使います。ローカルでは動いたのに本番だけ壊れる、という事故の相当数はこの一手で消えます。
インストールからバージョン確認まで最短で動かす手順と確認コマンド
導入方法は大きく2通りです。1つの版だけ使うなら公式インストーラで十分ですが、複数案件を並行して抱えるならバージョン管理ツールが前提になります。どちらを選ぶかは、扱うプロジェクト数で決まります。
公式インストーラとnvm・miseを使い分ける基準と導入手順
Node.js公式のダウンロードページでは、OSとアーキテクチャを選ぶとインストーラとパッケージマネージャ経由の両方の手順が表示されます。Windowsで学習用に1台だけ整えるなら、この公式インストーラが最短です。
案件ごとに指定バージョンが違う場合は話が変わります。プロジェクトAはv22、プロジェクトBはv24という状況で1つの版を全体に入れると、切り替えのたびに再インストールが必要です。この用途にはnvm、mise、Voltaといった管理ツールを使い、リポジトリ側にバージョンを固定させます。導入と切り替えの具体的な操作はNodebrewを使ったNode.jsのバージョン管理と切り替え手順で整理しているので、ツール選定の段階で参照してください。
導入直後に確認するバージョン表示とHello Worldの実行結果
インストール後にまず確認するのは、実行ファイルにパスが通っているかと、npmが同梱されているかの2点です。次の3行を順に実行します。
node --version
npm --version
node -e "console.log('hello from node')"
1行目でv24系またはv26系の番号が返り、2行目でnpmの版が返れば導入完了です。3行目の-eはファイルを作らずにその場でコードを走らせるオプションで、標準出力にhello from nodeと出れば実行環境として機能しています。バージョン番号が返らない場合はインストール自体ではなくPATHの問題なので、シェルを開き直してから再確認します。
v22・v24・v26のLTS日程と本番で選ぶべき版の判断基準
バージョン選定を感覚で決めると、稼働から1年でサポート切れの版に載っていた、という事態が起きます。Node.jsはリリース日程を機械可読な形で公開しているため、判断は日付を見るだけで済みます。
v22・v24・v26のリリース日とEnd-of-Life日の一覧
リリース日程はNode.js Release Working Groupのリポジトリで管理され、schedule.jsonに各版の日付が入っています。2026年9月7日時点の値は次のとおりです。
| 版 | コード名 | 初回リリース | LTS入り | Maintenance移行 | サポート終了 |
|---|---|---|---|---|---|
| v22 | Jod | 2024-04-24 | 2024-10-29 | 2025-10-21 | 2027-04-30 |
| v24 | Krypton | 2025-05-06 | 2025-10-28 | 2026-10-20 | 2028-04-30 |
| v25 | 未設定 | 2025-10-15 | なし | 2026-04-01 | 2026-06-01 |
| v26 | 未設定 | 2026-05-05 | 2026-10-28 | 2027-10-20 | 2029-04-30 |
| v27 | 未設定 | 2027-04-22 | 未記載 | 2027-10-20 | 2030-04-30 |
偶数版は初回リリースから約半年後にLTS入りし、そこから約1年でMaintenanceへ移り、初回から3年で終了する流れです。v26のLTS入りは2026年10月28日に予定されています。表のv25は奇数版でLTSに入らず、2025年10月15日のリリースから約8か月後の2026年6月1日で終了しました。奇数版へ本番を載せるとこの短さがそのまま移行圧力になるため、検証用途に限定する扱いが前提になります。
本番はActive LTS・検証はCurrentで分ける版選定の基準
本番環境はActive LTSに置きます。2026年9月時点でこれに該当するのはv24だけで、v22はすでにMaintenanceです。Maintenanceの版でも重大なバグ修正とセキュリティ修正は届きますが、新機能は入りません。v22で動いている既存システムをいま急いで止める必要はないものの、2027年4月30日という終了日から逆算して移行計画を引く時期には入っています。
Currentのv26は検証環境で回します。v26で何が変わったかはNode.js 26の新機能・変更点とLTSスケジュールの総まとめに詳しくまとめてあるため、移行前の影響調査はそちらを起点にすると早いです。順序としては、v26がLTS入りする2026年10月28日を待ってから本番を上げる判断が堅実でしょう。
Node.js 27以降の年1回リリースが運用計画に与える変更点
公式のリリース案内では、Node.js 27以降はメジャーリリースが年1回になり、すべてのメジャー版がLTSへ移行すると説明されています。v27の初回リリースは2027年4月22日、サポート終了は2030年4月30日という予定値です。schedule.jsonにはv27のLTS入り日がまだ入っていないため、この1点だけは日程確定を待つ必要があります。
これが運用に与える影響は単純で、「偶数版だけを追う」という従来の判断基準が使えなくなることです。半年ごとに出る奇数版を無視していれば良かった運用から、年1回のメジャー版を必ず評価する運用へ切り替わります。保守契約にバージョン追随の条項を入れている場合、更新頻度の前提が変わる点は事前に共有しておくべき事項です。
標準モジュールだけで書くHTTPサーバーとnode:testの実行例
Node.jsで何ができるかを掴む最短路は、フレームワークを入れずに標準モジュールだけで動かしてみることです。ExpressもJestも入れずに、HTTPサーバーとテストがここまで書けます。
node:httpだけで書く最小サーバーと起動確認までのコード
次のコードをserver.mjsとして保存し、node server.mjsで起動します。外部パッケージは1つも要りません。
import http from 'node:http';
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
res.end(JSON.stringify({ path: req.url, ok: true }));
});
server.listen(3000, () => {
console.log('listening on http://localhost:3000');
});
ブラウザでlocalhostの3000番を開くと、リクエストしたパスがJSONで返ります。この30行未満のコードが、Node.jsのサーバー機能の実体です。Expressなどのフレームワークは、ここにルーティングとミドルウェアの層を足しているにすぎません。小さな内部ツールやヘルスチェック用エンドポイントであれば、標準モジュールのままで完結させる選択も現実的です。
このサーバーを外部サービスのWebhook受け口として検証する場合、localhostのままでは通知が届きません。公開URLを発行して手元の3000番へ転送する方法はngrokでローカルサーバーを外部公開する手順で扱っています。
node:testで外部フレームワークなしにテストを回す実行例
テストランナーは公式ドキュメントのnode:testでStability 2(Stable)に分類され、v20.0.0で安定版になっています。test/sum.test.jsのようなファイル名にしておけば、node --testだけで検出して実行されます。
import test from 'node:test';
import assert from 'node:assert/strict';
test('合計値を返す', () => {
assert.strictEqual(1 + 2, 3);
});
test('非同期の解決値を検証する', async () => {
const value = await Promise.resolve('ok');
assert.strictEqual(value, 'ok');
});
既定で検出されるパターンにはtest.jsで終わるファイルやtestディレクトリ配下が含まれます。テストランナーを1つ外せば、依存ツリーからその関連パッケージがまとめて消えます。既存プロジェクトのJestを無理に置き換える必要はありませんが、新規の小規模なライブラリやCLIツールなら標準のもので十分です。
CommonJSとESモジュールの相互運用で詰まる箇所と切り替えの手順
Node.jsにはモジュールの読み込み方式が2つあります。requireを使う従来のCommonJSと、importを使うESモジュール(ESM)です。この差はインストール直後には見えず、既存コードへ新しいライブラリを足す段階で表面化します。エラーメッセージが分かりづらい領域なので、条件を先に押さえておくと調査時間が短くなります。
require(esm)が既定で通る条件とtop-level awaitで落ちる理由
公式のモジュール解説によれば、require()からESモジュールを読む機能はv22.0.0とv20.17.0で追加され、v23.0.0とv22.12.0で--experimental-require-moduleフラグが外れ、v25.4.0で実験的な位置づけを離れました。ESM専用で公開されたパッケージを、CommonJSのコードベースから直接読める状態になっています。
ただし通る条件が決まっています。第一に、対象のモジュールが完全に同期であること。第二に、拡張子が.mjsであるか、最も近いpackage.jsonに"type": "module"があるか、拡張子が.jsで最も近いpackage.jsonが"type": "commonjs"を持たずESM構文を含むか、のいずれかを満たすことです。
落ちる典型はトップレベルawaitです。読み込む側から見て、対象モジュールまたはそれがimportするグラフのどこかにトップレベルawaitがあるとERR_REQUIRE_ASYNC_MODULEが投げられます。この場合は同期のrequire()を諦め、動的import()へ切り替えるのが正しい対処です。原因箇所を特定したいときは--experimental-print-required-tlaを付けると、該当位置が標準エラー出力へ表示されます。
戻り値の形も押さえておきたい箇所です。require(esm)が返すのはモジュール名前空間オブジェクトで、default exportは.defaultプロパティに入ります。呼び出し側の書き換えを避けたい場合、ESM側でmodule.exportsという文字列名のexportを宣言すると戻り値を直接差し替えられますが、その代わり名前付きexportはCommonJS側から見えなくなります。両方式の構造差はNative ESMの仕組みとCommonJSとの根本的な違いで整理しているので、移行方針を決める前に確認してください。
__dirnameが無いESMをimport.meta.dirnameへ置き換える手順
公式のESM解説のとおり、ESモジュールにはrequire・exports・module.exports・__filename・__dirnameが存在しません。CommonJSから移す作業でまず止まるのが、この__dirnameを使ったパス組み立てです。代わりにimport.meta.dirnameとimport.meta.filenameを使います。どちらもv21.2.0とv20.11.0で追加され、v24.0.0とv22.16.0で実験的フラグが外れました。
CommonJS専用のパッケージを部分的に読み続けたい箇所では、node:moduleのcreateRequire()でESM内にrequire関数を作れます。次のコードは、設定ファイルを自分のディレクトリ基準で読み、あわせてCommonJS専用パッケージを1つ読み込む最小例です。
import fs from 'node:fs/promises';
import path from 'node:path';
import { createRequire } from 'node:module';
const configPath = path.join(import.meta.dirname, 'config.json');
const raw = await fs.readFile(configPath, 'utf-8');
// CommonJS専用パッケージを読む箇所だけrequireを作る
const require = createRequire(import.meta.url);
const legacy = require('some-cjs-only-package');
console.log(Object.keys(JSON.parse(raw)), typeof legacy);
実務上の判断としては、方式を混在させたまま長く運用しないほうが扱いやすくなります。混在期間が伸びるとビルド設定とテスト設定の両方に例外が積み上がり、担当者が変わったときに解読コストが出ます。移行の順序は、末端のユーティリティからESMへ寄せ、エントリポイントを最後に切り替える形が安全です。
型ストリッピングとPermission Modelで減らせる外部依存の範囲
ここ数年で標準側へ取り込まれた機能のうち、実装工程への影響が大きいものが2つあります。TypeScriptの直接実行と、実行時の権限制御です。どちらも外部ツールを1段減らせます。
型ストリッピングで.tsを直接実行できる条件と主な非対応の構文
Node.jsは.tsファイルから型注釈だけを取り除いて実行します。公式のTypeScriptモジュール解説によれば、この型ストリッピングはv23.6.0とv22.18.0で既定有効になり、v25.2.0とv24.12.0でStableへ昇格しました。v26.0.0では--experimental-transform-typesフラグが削除されています。
ただし何でも動くわけではありません。JavaScriptコードの生成を伴う構文はエラーになります。具体的にはenum宣言、値を出力するnamespace、コンストラクタのパラメータプロパティ、デコレータです。型のみを出力するnamespaceは通ります。既存のTypeScript資産をそのまま流し込むと、この4つで止まる可能性があると見ておくべきです。無効化したい場面では--no-strip-typesを渡します。型注釈と型推論の書き分けから整理したい場合はTypeScriptの型・型推論・型注釈の書き分けを先に読むと、どこまでを型ストリッピングで済ませられるか見通しが立ちます。
Permission Modelでファイル・ネットワークを絞る実行例
Permission Modelは公式ドキュメントでStability 2(Stable)とされ、v20.0.0で追加、v23.5.0とv22.13.0で実験的な位置づけを外れました。--permissionを付けて起動すると既定で全アクセスが遮断され、許可したリソースだけが通ります。
node --permission \
--allow-fs-read=./data \
--allow-net \
app.js
いきなり強制モードにすると起動しないため、まずは--permission-auditで監査モードを回し、違反ログを見てから許可範囲を決める順序が現実的です。素性の分からないnpmパッケージを組み込む案件や、顧客データを扱うバッチをサーバー上で走らせる場面では、この一行の有無が事故の規模を変えます。
Node.jsで作れるものとフレームワークを案件条件で選ぶ基準
「Node.jsで何が作れるか」という問いは、標準機能で届く範囲と、外部パッケージを足して初めて届く範囲を分けると答えが出ます。境界が見えていれば、初期構成で入れるライブラリの本数をそのまま削れます。
HTTPサーバー・CLI・バッチ・常時接続まで届く標準機能の範囲
標準機能だけで、HTTP API・CLIツール・定期バッチ・常時接続サーバーの4つは書けます。HTTPクライアントのfetchはv17.5.0とv16.15.0で追加され、v21.0.0で実験的な位置づけを離れました。公式のグローバルオブジェクト解説によれば、WebSocketクライアントもv21.0.0とv20.10.0で追加され、v22.4.0で実験を外れています。外部のHTTPクライアントとWebSocketクライアントを入れずに済む構成が、v24の時点で成立します。
保存先も標準側へ入ってきました。node:sqliteモジュールはv22.5.0で追加され、v23.4.0とv22.13.0で--experimental-sqliteフラグが外れ、v25.7.0でStability 1.2(Release candidate)へ上がりました。仕様変更の余地が残る段階なので、本番の主データベースには置かず、CLIのローカルキャッシュや検証用スクリプトの保存先に絞る使い方が妥当な線です。
常時接続を本番で運用する場合は、標準のWebSocketクライアントとは別に、サーバー側のハンドシェイクと切断検知の設計が必要になります。プロトコルの挙動からNode.jsでの実装、負荷分散を通す条件まではWebSocketの仕組みとNode.js実装・運用の判断で扱っているため、リアルタイム要件のある案件ではそちらを設計の起点にしてください。
Express・Fastify・NestJSを案件規模と体制で選び分ける基準
標準機能を超える段階でフレームワークを入れます。2026年9月7日時点の版はExpressが5.2系、Fastifyが5.12系です。Express公式はミドルウェアの資料量が多く、参画者が入れ替わる案件でも読める人を確保しやすい選択になります。5系での変更点と4系からの移行手順はExpress 5対応のバックエンド入門と4系からの移行点にまとめてあります。
Fastifyはスキーマ駆動を前提にした構成で、公式サイトのとおりJSONスキーマでリクエスト検証とレスポンスのシリアライズを宣言します。入出力がJSON主体でリクエスト数が多い案件では、この宣言がそのまま仕様書の役目を兼ねる構成です。NestJSは依存性注入とモジュール分割の型が決まっているため、5名以上で長期保守する業務システムで設計のばらつきを抑える方向に効きます。
決め手になるのは実行速度の差ではなく体制です。保守を引き継ぐ人数が読める規約を優先し、参画者の経験がある方へ寄せるほうが、総保守コストは下がります。ベンチマークの数値差は、実案件ではDB照会と外部API応答の待ち時間に埋もれる程度でしかありません。
npm・pnpm・yarnの選定とCorepack非同梱後の版固定の手順
パッケージマネージャは、単独案件なら同梱のnpmで足ります。モノレポで複数パッケージを抱える構成や、node_modulesの重複容量が問題になる規模ではpnpmを選ぶ判断が増えます。Yarnは系統差が大きく、Classic(v1)とBerry(v2以降)で設定ファイルも挙動も違うため、既存プロジェクトを引き継ぐ際はYarn Classicとv2以降の違いでどちらの系統かを先に見分けてください。
2026年に効く変更が1つあります。パッケージマネージャの版を固定するCorepackは、公式リポジトリの記載のとおりNode.js 14.19.0から25.0.0未満までは同梱でしたが、v25.0.0以降の公式配布物には含まれません。v24(Active LTS)ではcorepack enableがそのまま通る一方、v26で同じ手順書を渡すとコマンドが見つからず失敗します。v26以降で使うならnpm install -g corepackで別途入れる前提へ手順書を書き換えます。
固定自体はpackage.jsonのpackageManagerフィールドで宣言し、Corepackがその版を取得して使います。CIとローカルで別の版が走る事故を防ぐための設定です。v26への移行時にこの手順が抜け落ちると、再現性の担保が静かに外れます。corepack enableとcorepack prepareの具体的な操作はcorepackでpnpmを管理する方法とNode.js 25での変更で扱っています。
受託開発でNode.jsを採用する条件と見送るべき案件の切り分け
ここからは技術解説ではなく判断の話です。Node.jsは万能ではなく、向かない案件に入れると保守フェーズで負債になります。条件を明示して線を引きます。
Node.jsを採用してよい案件の条件と開発チーム体制側の前提
採用してよいのは次の条件が揃うときです。第一に、処理の主体がDB照会・外部API連携・ファイル転送といったI/O待ちであること。第二に、フロントエンドがReactやVueで、同じ言語のまま型定義を共有できること。第三に、非同期処理を読み書きできる開発者がチームに2名以上いること。
3つ目の軽視は禁物です。asyncとawaitの書き方は覚えられても、Promiseの例外がどこで握り潰されるかまで追える人がいないチームでは、原因不明の無応答が本番で出ます。判定の目安としては、try/catchとPromise.all・allSettledの使い分けの水準を説明できるかを確認するとよいでしょう。弊社ではNode.jsを含むバックエンドの設計・実装をAPI開発・システム連携のサービスとして提供しており、既存システムとの接続方式やバージョン方針の相談も受け付けています。
Node.jsを見送るべき処理特性と別言語へ寄せる判断の線引き
見送るべき条件も明確にします。動画のエンコード、数百万行のCSV集計、機械学習の推論をリクエストごとに回すような、CPUを長時間占有する処理が主業務の場合はNode.jsを中心に据えません。worker_threadsで逃がす手はありますが、それは回避策であって適材適所ではありません。この種の処理はGoやPython、あるいは専用のジョブ基盤へ寄せます。
もう一つ、既存資産がJavaやPHPで統一されており、運用チームにJavaScript経験者がいない場合も見送りの対象です。言語を増やすコストは、実行速度の差より保守で効いてきます。ランタイムそのものを比較検討している段階なら、BunランタイムとNode.jsの実行差と版の固定方法で両者の違いを確認したうえで判断してください。
本番運用で詰まるヒープ上限・単一障害点・依存更新への実務的な対処
開発環境で動いたNode.jsアプリが本番で落ちる原因は、たいてい3つに集約されます。メモリ、プロセス数、そして依存パッケージです。順に潰します。
ヒープ上限の指定とプロセス多重化でスループットを保つ設定の目安
V8のヒープには上限があり、大きなデータを抱えると上限到達で異常終了します。--max-old-space-sizeにメガバイト単位の数値を渡すと上限を明示でき、指定できるオプションの一覧はCLIドキュメントにまとまっています。コンテナで動かす場合は、コンテナのメモリ制限より小さい値を入れるのが原則です。制限と同値にすると、V8がGCを走らせる前にOOM Killerに落とされます。
CPUコアを使い切るには複数プロセスが必要です。標準のnode:clusterモジュールはマスタープロセスがワーカーを生成し、同一ポートへの接続を分配します。コンテナ環境ではオーケストレーター側でレプリカ数を増やす方式が主流なので、clusterを使うか外側で増やすかは基盤の構成に合わせて選びます。
脆弱性情報の追い方と依存パッケージ更新を止めないための運用手順
npmの依存ツリーは数百パッケージに膨らみやすく、放置すると更新できない状態に陥ります。未宣言の依存を読み込ませたくない場合は、共有ストアとハードリンクで依存を管理するpnpmへの切り替えも選択肢になります。運用に載せるのは次の3つです。npm auditを毎週のCIジョブに組み込み、Dependabotなどで更新PRを自動作成し、lockファイル差分をレビュー対象に含める。3か月止めるだけで、メジャー版を跨いだ更新が積み上がって手が付けられなくなります。
npmはサプライチェーン攻撃の標的にもなっており、正規パッケージへ悪性コードが混入した事例が実際に出ています。影響確認の手順と平時の防御策はnpmサプライチェーン攻撃Shai-Huludの全体像と対策にまとめてあるため、npm ciとpackage-lock.jsonの運用とあわせて設計してください。
ランタイム本体の脆弱性はまた別系統で、Node.js側からセキュリティリリースとして配信されます。影響範囲の確認方法と更新手順はNode.jsの脆弱性の確認方法と対応バージョンの判断手順にまとめてあります。稼働中のサーバーOS側の更新方針とあわせて設計してください。
よくある質問
Node.jsの導入検討や学習の初期段階で実際によく検索されている質問を5つ取り上げ、公式ドキュメントの記載に沿って回答します。
Node.jsとJavaScriptの違いは何ですか?
JavaScriptは言語そのもの、Node.jsはその言語をブラウザの外で実行する環境です。同じV8エンジンを使いますが、ブラウザにあるDOM操作やwindowオブジェクトはNode.jsに存在せず、代わりにファイルシステム操作のnode:fsやHTTPサーバーのnode:httpといったモジュールが用意されています。言語仕様は共通なので、フロントエンドで書いたロジックの一部をそのままサーバー側で再利用できる場面があります。
Node.jsのインストールにnvmは必要ですか?
扱うプロジェクトが1つなら不要で、公式インストーラで問題ありません。複数案件を並行し、それぞれ指定バージョンが異なる場合に管理ツールが要ります。nvmのほかmise、Voltaといった選択肢があり、いずれもリポジトリ内の設定ファイルでバージョンを固定できます。チームで使うなら、固定方法をREADMEに明記して全員の環境を揃えるところまでを1セットにしてください。
Node.jsはどのバージョンを本番で使えばよいですか?
2026年9月時点ではv24(Krypton)です。2025年10月28日にLTS入りし、Active LTSに該当するのがv24のみで、サポート終了は2028年4月30日と先まで確保されています。v22は2025年10月21日にMaintenanceへ移っており、新規案件の既定に選ぶ理由はありません。v26は2026年10月28日にLTS入りが予定されているため、それ以降であればv26も本番候補に入ります。
Node.jsでTypeScriptを動かすのにトランスパイルは必要ですか?
型注釈を消すだけで済む範囲なら不要です。型ストリッピングがv25.2.0とv24.12.0でStableへ昇格し、.tsファイルをそのまま実行できます。ただしenum宣言、値を出力するnamespace、パラメータプロパティ、デコレータの4つは対応外でエラーになります。これらを使っているコードベースでは、従来どおりtscやビルドツールを経由させる構成のままにしてください。
Node.jsで作ったツールを単体の実行ファイルに固められますか?
可能ですが、機能の成熟度には注意が必要です。単一実行可能アプリケーション(SEA)はv19.7.0とv18.16.0で追加され、v25.5.0では--build-seaというCLIフラグが加わりました。安定度はStability 1.1(Active development)で、仕様変更の余地が残る段階です。公式のSEAドキュメントで現行の手順を確認したうえで、社内配布ツールなど影響範囲の限られる用途から試すのが妥当な進め方です。
関連記事
- Node.js 26の新機能・変更点とLTSスケジュール総まとめ:本記事で触れたv26の中身を機能単位で確認できます
- Nodebrewとは?Node.jsのバージョン管理・インストール・切り替えを入門解説:複数版を並行運用する際の具体的な操作手順です
- Volta(ヴォルタ)とは?Node.jsバージョン管理ツールの使い方と現状:管理ツール選定でnvm以外の候補を比較する際に参照してください
- Native ESMの基本仕組みとCommonJSとの根本的な違いの整理:モジュール方式の移行方針を決める段階向けです
- Express.jsとは?Express 5対応のバックエンド入門と4系からの移行点:標準モジュールの次に入れるフレームワークの具体です
- Bunランタイムとは?JavaScriptCoreで動く仕組みとNode.jsとの実行差:ランタイムそのものを比較検討する段階向けです
- Linuxとは?仕組み・ディストリビューション・サーバー用途を実装目線で解説:Node.jsを載せるサーバー側の前提知識を補います
- Node.js LTSとは?現行版の確認とlts/*の固定・移行時期を実装目線で解説:LTSの確認コマンドとnvm・CI・Dockerでの版固定、EOL前の移行時期まで運用面を詰めたい場合に