保守者が非推奨にしたパッケージでも、毎月数千万回ダウンロードされることがある。一方、保守が続いているのに、新しいプロジェクトでは同じ仕事をするために必須ではなくなったパッケージもある。npm のダウンロード数だけでは、どちらの変化も見えにくい。
どのライブラリやユーティリティが役割を終え、どれを残すべきなのか。「古くなったパッケージランキング」では答えられない。問うべきなのは、この依存関係を導入した理由は今も存在するか。存在するなら、誰のために何を引き受けているのかということだ。
私の見立てでは、必要性を失いやすいのは、プラットフォームの不足を補いながら、それ以上の複雑さを継続的には担っていない道具だ。小さなパッケージをすべて消すべきだという意味でも、標準 API が常に優れているという意味でもない。2026 年 10 月 8 日時点で確認した公式文書、保守方針、npm のデータをもとに、五つの置き換え圧力を調べ、確認できる事実と私の推論を分けて考える。
ダウンロード数が示すのは流量であり、選択そのものではない
Request の README は、2020 年 2 月 11 日から非推奨であると明記している。inflight のメタデータは、サポート終了とメモリリークを警告する。Moment は異なり、機能拡張を目的とせずに保守を続けている。三つをまとめて「死んだパッケージ」と呼ぶと、この違いが消えてしまう。Request の声明、inflight の情報、Moment の現行方針
npm の公式 Downloads API で、2026 年 9 月の暦月全体を共通期間として調べた。この三つは、非推奨や保守モードになればダウンロードが消えるのかを確かめるために選んだ事例だ。無作為標本でも、市場占有率の調査でもない。
非推奨や保守モードでも、大量のダウンロードは続く
三つの事例はいずれも 2026 年 9 月に大量のダウンロードがあった。新規プロジェクトの採用意向を示すグラフではない。
- request(非推奨)59.699
- moment(保守モード)149.03
- inflight(非推奨)392.617
npm ダウンロード数の表を表示
| パッケージと保守状態 | 百万ダウンロード(概数)/2026 年 9 月 |
|---|---|
| request(非推奨) | 59.699 |
| moment(保守モード) | 149.03 |
| inflight(非推奨) | 392.617 |
npm 公式 API。2026 年 9 月 1 日〜30 日、UTC、両端を含む。数値は百万回単位で小数第 3 位に四捨五入し、正確な回数は出典に記載。単月のスナップショットであり、増減の証拠ではない。回数は利用者数やプロジェクト数ではなく、新規採用、間接依存、自動インストールを区別したり、その割合を求めたりすることはできない。
出典API が返すのは期間内のダウンロード総数で、「エンジニアが意図的に選んだか」という項目はない。たとえば、古いツールが Request に間接依存し、キャッシュのない環境で再ビルドされれば、設計を再評価する人がいなくても再ダウンロードは起こりうる。これは仮定の仕組みの説明であり、今回の総数のうち何割がそうなのかは分からない。npm API と日付の定義
調査では、機能がまだ希少か、保守者は何を約束するか、新規プロジェクトが選ぶか、既存システムが移行できるか、という四つの問いを分ける必要がある。非推奨の声明は二つ目の一部を、API の比較は一つ目を明らかにする。単月の総数では、後の二つに答えられない。
本稿の限界もここにある。ある用途で必要性が薄れていることを論じる根拠はあるが、五つの分類すべてで新規採用率が下がっていると断言するデータはない。
1. 実行環境に標準機能を補う互換レイヤー
node-fetch の当初の役割は明快だ。Fetch API を Node.js に持ち込むことだった。実行環境に安定した fetch があれば、基本的な HTTP リクエストだけのために別パッケージを入れる理由は弱くなる。Node.js の文書では v21 から非実験的となっており、本稿は Node 24 の文書を能力の基準にする。Node.js Fetch
確認できるのはプラットフォームへの機能の取り込みであって、node-fetch の利用減少ではない。また、import を消せば移行完了という話でもない。node-fetch の response body は Node stream、標準 Fetch は Web Stream を使う。agent と Node 標準 Fetch の dispatcher も別のインターフェースだ。ストリームの読み方、接続設定、キャンセルの挙動を実際の用途と照合する必要がある。node-fetch 文書
HTTP client の価値は通信より上の層にもある。エラー分類、再試行方針、認証情報、観測ログを統一するなら、共通の抽象化は合理的だ。fetch はあらゆる HTTP エラーステータスを自動で Promise の拒否にするわけではない。レスポンスの扱いはアプリケーションが決める。書き込みの再試行も、ループを加える前に重複実行を考慮しなければならない。Fetch 標準
さらに、Node の Fetch 実装は Undici に基づく。明示的にインストールするパッケージが減っても、その下の保守作業が消えるとは限らない。実行環境に移っただけかもしれない。薄れているのは別途インストールする理由であり、背後にある技術知識の価値とは限らない。
2. 日常的な構文を便利にする道具箱
配列の検索、反復、重複除去は、汎用ユーティリティを導入する入口だった。現在は Array.prototype.find、map、Set が言語の一部だ。単純な文字列配列から重複を除くだけなら、追加の依存関係が担う仕事は少なくなる。ECMAScript の配列とコレクション
ただし、似た記述と同じ意味は別だ。次はその違いを示すために作った反例である。
const settings = { retries: null };
// _.get が既定値を使うのは結果が undefined の場合だけ。
_.get(settings, 'retries', 3); // null
// ?? は null と undefined の両方に既定値を適用する。
settings?.retries ?? 3; // 3null が「明示的に無効」を表すなら、機械的な置き換えは業務ルールを変える。前者の契約は Lodash の文書に定義されている。調査は文字数の比較ではなく、呼び出し側が依存する挙動の確認から始めるべきだ。Lodash get
structuredClone も多くの型や循環参照を扱えるが、任意の JavaScript オブジェクトをそのまま複製する機能ではない。関数、DOM ノード、プロトタイプ、プロパティ記述子には制約がある。値の種類を調べずに cloneDeep を一律置換するのは、移行戦略として不十分だ。構造化複製アルゴリズム
デバウンスも「後で実行する」だけではない。Lodash の debounce には leading、trailing、maxWait、cancel、flush がある。その相互作用を利用しているなら、十行の自作コードが安上がりとは限らない。Lodash debounce
圧力を受けるのは、道具箱のうち標準機能と重なる用途だ。「Lodash 全体が無価値になった」とは言えない。一つのライブラリには、簡単に置き換えられる便利機能と、残す価値のある契約が共存する。置換の単位は用途でよく、最初からパッケージ全体の削除を目指す必要はない。
3. Node.js の基本的なファイル操作を補う道具
多階層ディレクトリの作成、ディレクトリのコピー、パターンによるファイル検索には、追加ツールがよく使われてきた。Node 24 には再帰的な mkdir、fs.cp、fs.glob がある。cp は v22.3 で非実験的となり、glob は v24.0 で安定版になった。実行環境を固定できる新しいスクリプトなら、まず確認する価値がある。Node.js ファイルシステム文書
次は仮定のビルドスクリプトの断片だ。Node 24 が直接できることの例であり、あらゆる外部ツールとの完全な互換性を示すものではない。
import { mkdir, cp, glob } from 'node:fs/promises';
await mkdir('dist/assets', { recursive: true });
await cp('assets', 'dist/assets', { recursive: true });
for await (const file of glob('content/**/*.mdx')) {
console.log(file);
}アプリケーションは Node のバージョンを指定できるが、公開ライブラリは利用者の最低対応バージョンを考慮する必要がある。判断条件が異なる。バージョンが合っていても、シンボリックリンク、上書き、除外規則、隠しファイル、OS ごとのパスを比べたい。同名の API があるだけでは、外部 glob ツールのすべてのオプションが一致するとは言えない。
役割を終えるには三つの門がある。プラットフォームが機能を提供し、プロジェクトが対応環境を要求でき、そのうえで移行コストが保有コストを下回ることだ。最初の門を越えても、残り二つを越えたことにはならない。「古い依存関係」が残る理由は、対応範囲とリスクの配分にある場合が多い。
4. 以前のアーキテクチャの契約を守るラッパー
Request と Moment は並べて語られがちだが、保守の選択は異なる。Request は非推奨になり、Moment は可変オブジェクトの API を維持しながら保守を続ける。「新しい代替品がある」だけでは、既存システムが動かしにくい理由を説明できない。
Moment は 2026 年 8 月 17 日に方針を更新した。利用者向けの新機能は引き続き受け入れない一方、技術面の保守は可能であり、破壊的変更を伴う保守リリースとしての 3.0 も一律には排除しなくなった。旧公告の「v3 は出さない」を現行の約束として引用すべきではない。Moment の方針更新
移行コストは契約に潜む。たとえば、操作が元のオブジェクトを変更することに依存した日付処理を考える。新しいオブジェクトを返す道具に替えると、画面には妥当な日付が出ても、別の処理が古い値を読み続けるかもしれない。メソッド名を置き換える前に、可変性、解析、タイムゾーン、出力形式を棚卸しする必要がある。
標準の Intl.DateTimeFormat は多くの表示処理を担える。しかし、ある時点を整形することは、あらゆる人間の入力を解析することでも、「来月の同じ日」や夏時間をまたぐ予約の規則を定義することでもない。ECMA-402 の日付整形
Request の利用側も cookie、プロキシ、ストリームの設定に依存しているかもしれない。アプリケーションが実際に使う契約から出発し、新 client や薄い互換層を選ぶ。期限と責任者を決めて依存関係を一時的に残すのも、工学的な判断になりうる。「新たに使わない」と「今日すべて削除する」は異なる指示だ。
5. ブラウザ自身ができる仕事のための補助ツール
jQuery の入門的な用途の一部は、現在の querySelectorAll、classList、addEventListener で実現できる。要素がビューポートに入る検知には Intersection Observer が土台になる。それらだけがパッケージの価値なら、標準機能によって必要性は確かに薄れる。DOM 標準、Intersection Observer 仕様
それでも jQuery は 2026 年 1 月 17 日に 4.0 を公開した。「新しいプロジェクトには不要かもしれない」から「保守が終了した」と推論するのは誤りだ。既存プラグイン、統合、チームの習熟は、残す理由になりうる。jQuery 4.0 の公告
標準の部品は完成品ではない。交差状態を観察できても、画像読み込みの失敗、仮想リスト、フォーカス順序、スクリーンリーダーとのやり取りまで解決したことにはならない。フレームワークや上位のコンポーネントが責任を引き継げば、アプリが小さな utility を直接導入しなくなっても、仕事は統合層に残る。
| 分類と元の役割 | 引き継ぐ機能 | 残る要件 |
|---|---|---|
| Fetch 互換層:Node に Fetch を提供 | 実行環境の Fetch | ストリーム、接続設定、最低バージョン |
| 汎用ツール:データ操作を簡略化 | 配列メソッド、Set、オプショナルチェーン | 境界の意味、深いデータ、デバウンスの契約 |
| ファイル操作:作成、コピー、検索 | Node の mkdir、cp、glob | パス、リンク、除外、対応バージョン |
| 旧 API のラッパー:HTTP や日付操作を統一 | 新 client、Intl、別の日付ツール | 可変性、解析、タイムゾーン、互換性 |
| ブラウザ補助:選択、イベント、可視性 | DOM と Observer API | プラグイン、統合、完全な操作挙動 |
これは置換の境界を整理した表であり、衰退度の順位ではない。どの行にも、活発に保守され、需要が続く製品が含まれうる。
AI は薄いラッパーを置き換え、古い依存関係を延命もする
ここからは仕組みについての私の推論だ。安定した少数の API を包み、要件が明確で、入力を制御でき、検証しやすい道具なら、AI によって局所的な実装の費用が下がることで、外部依存の魅力が減る可能性がある。チームはパッケージ全体のインターフェースや更新周期を受け入れず、少量のコードを所有できる。
ただし、コード生成は責任を消さない。作者が担っていた境界条件、テスト、セキュリティ修正、バージョン互換性が自分たちの repository に移る。生成が容易になるほど、「これが間違ったとき、誰が見抜けるか」を問う意味は大きくなる。
保守者の観察には逆向きの動きもある。Moment の 2026 年公告は、既存コードや文書に agent が慣れていることが、新たな利用につながっている可能性を示している。これは成長源についての保守チームの解釈であり、AI の因果効果が証明されたわけではない。今回のダウンロード情報でも検証できない。Moment の agent 利用に関する観察
したがって「AI が utility を消す」だけでは結論にならない。簡単な実装を自前で持ちやすくする一方、サンプルや古い知識を通じて同じ依存関係を繰り返し導入する可能性もある。現在の環境への適合性より、過去の露出の多さが自動選択に効くかもしれない。これは管理すべきリスクであり、本稿が数量化した市場動向ではない。
ツール作者が蓄積するなら、検証可能な正しさ、明確な対応範囲、信頼できる文書、専門的な失敗事例のテストが重要だと思う。便利な薄い層は再現しやすいが、長年かけて見つけた失敗の条件は同じようには安くない。
残す価値は、継続して担う複雑さにある
タイムゾーンのデータは政治的な決定によって変わる。IANA は、UTC オフセット、地域の境界、夏時間の規則の変更に応じてデータベースを更新すると説明している。最初の実装が数個の関数で済んでも、この仕事は終わらない。IANA タイムゾーンデータベース
パーサー、暗号実装、複雑なプロトコル、アクセシブルなコンポーネントにも、同じ評価の方向がある。費用の本体は、仕様への追随、悪意ある入力や予想外の入力への対処、環境をまたぐテスト、誤りの修正かもしれない。これは依存先を選ぶ際に調べるべき責任であって、特定パッケージの安全性を保証する話ではない。
数十行の道具が、自分では持ちたくない微妙な意味を引き受けることもある。大きなツール群が、一行の標準操作のためだけに使われることもある。大きさと価値は比例しない。削除後に残る仕事をプラットフォームが担うのか、実はチームに戻るだけなのかが重要だ。
私は依存関係ゼロを目標にせず、次の行動に落とし込む。
| 現状 | 行動 | 確認点 |
|---|---|---|
| 標準機能で足り、環境が固定され、用途が単純 | 直接依存を段階的に置換 | 実際の入力で成功と失敗の挙動を検証 |
| 標準機能は近いが意味が異なる | まず残すか、薄い互換層を設ける | null、エラー、キャンセル、タイムゾーンなど |
| 非推奨のパッケージを直接利用 | 新規利用を抑え、移行を計画 | 責任者、代替案、ロールバック地点 |
| 上流から非推奨パッケージが入る | 親の依存先を追跡して更新・置換 | lockfile の手編集を根治と見なさない |
| 変化する専門問題を担う依存先 | 維持しつつ再評価 | 保守方針、テスト、対応範囲、更新能力 |
実行時は、まずパッケージマネージャーで依存元を追い、実際に呼んでいる関数を検索する。最低バージョンと重要な意味を記録し、小さな経路を一つ置き換える。既存の挙動テストで成功、失敗、境界入力を比較し、本番ビルドと依存ツリーを確認する。直接依存の宣言を消しても、上流が持ち込む別コピーは残りうる。lockfile を消しても、上流が新 API を使い始めるわけではない。
大量にダウンロードされ続けるパッケージに戻ろう。それは重要な基盤かもしれず、未完了の移行の痕跡かもしれない。数値だけでは決められない。
追跡すべき退場の兆候は、パッケージが担っていた仕事に、より適切で検証可能な引き受け先ができたことだ。 基盤が基本機能を取り込むほど、道具には深い専門性が必要になる。チームがコードを所有するなら、外に任せていた責任も引き取る。パッケージが一つ減るのは結果であり、残る複雑さを誰が担うかを知ることが判断の本体である。
