できない.dev

Node.js で「fetch is not defined」が解決できない(古い Node)

グローバル fetch は Node.js 18 で標準搭載された。
18 未満では未定義になるため、Node を更新するか node-fetch を導入すると解決する。

公開: 更新:

実行例あり(2026-09-10 に実環境で検証)

要約

ReferenceError: fetch is not defined は、使っている Node.js にグローバル fetch が無いときに出る。fetch は Node.js 18 で標準搭載されたため、18 以降へ更新すれば解決する。
更新できない環境では node-fetch を導入する。

実行例

Node.js 16.20.2 のイメージでは typeof fetch が undefined を返し、そのまま呼び出すと ReferenceError で終了コード 1 になる。
同じイメージでも --experimental-fetch を付ければ typeof fetch は function に変わり、node-fetch を入れて require した場合も関数として取り出せた。

$ node -v
v16.20.2
$ node app.js
typeof fetch: undefined
/tmp/tmp.so5ELjfc8w/app.js:2
fetch("http://127.0.0.1:1/");
^
 
ReferenceError: fetch is not defined
    at Object.<anonymous> (/tmp/tmp.so5ELjfc8w/app.js:2:1)
    at Module._compile (node:internal/modules/cjs/loader:1198:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1252:10)
    at Module.load (node:internal/modules/cjs/loader:1076:32)
    at Function.Module._load (node:internal/modules/cjs/loader:911:12)
    at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
    at node:internal/main/run_main_module:22:47
終了コード: 1
$ node --experimental-fetch -e 'console.log("typeof fetch:", typeof fetch)'
typeof fetch: function
(node:40) ExperimentalWarning: Fetch is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
終了コード: 0
npm notice 
npm notice New major version of npm available! 8.19.4 -> 12.0.2
npm notice Changelog: <https://github.com/npm/cli/releases/tag/v12.0.2>
npm notice Run `npm install -g npm@12.0.2` to update!
npm notice
$ node -e 'const f = require("node-fetch"); console.log("typeof node-fetch:", typeof f);'
typeof node-fetch: function
終了コード: 0

— 2026-09-10 時点の出力

検証環境

検証日
実行環境
node:16Debian GNU/Linux 10 (buster)
バージョン
  • Node.js 16.20.2
  • npm 8.19.4
  • Python 3.7.3
  • Git 2.20.1

この記事の「実行例」は、上記の環境で実際にコマンドを実行して得られた出力をそのまま掲載しています。 再現手順はリポジトリの検証スクリプトとして管理し、定期的に再実行して出力を更新しています。

よくある原因

  1. Node.js が古い: グローバル fetch は Node.js 18 で追加された。
    18 未満では未定義になる。
  2. ブラウザ前提のコード: ブラウザの fetch を前提にしたコードを、そのまま古い Node.js で実行している。
  3. 明示的に無効化: --no-experimental-fetch を付けると、18 以降でも fetch は消える。

解決策

1. Node.js を更新する(推奨)

バージョンを確認し、18 以降(できれば LTS)へ上げる。

node -v

nvm を使っているなら nvm install --lts で更新できる。

2. パッケージで補う

Node.js を上げられない場合は node-fetch を導入する。

npm install node-fetch
import fetch from "node-fetch";
 
const res = await fetch("https://example.com");
console.log(res.status);

3. 16.15.0 / 17.5.0 以降なら実験フラグで有効化する

--experimental-fetch が入ったのは 17.5.0 で、LTS の 16.15.0 にもバックポートされた。
そのため 16.15.0 以降の 16 系、または 17.5.0 以降の 17 系で使える。
16.15.0 未満にはこのフラグが無いため、その場合は node-fetch で補うか Node.js 自体を更新する。

node --experimental-fetch app.js

グローバル fetch が 18 で追加された経緯は公式のリリースアナウンス(新しいタブで開く)に記載されている。

この記事は役立ちましたか?