◆ node-fetch がダウンロード数 2 位になってた
◆ サイズも軽いし依存なしだし これで困らない限りはこれでよさそう

Node.js アプリを作るとき 結構迷うのが http のリクエストするときのライブラリです
できる限り標準に頼りたいのですが Node.js の標準の http client はちょっと機能が足りなすぎです
http と https で別のパッケージを使わないといけないですし リダイレクトも自動では解決してくれないので手動でリダイレクト先に再度リクエストを送らないといけないです
なのでさすがに Node.js で標準の http client を使うことはないです
ちょっとしたものであってもライブラリを入れます

ただ その選択が難しいんですよね

選択肢

古くからある有名なものだと requestsuperagent
割と最近のだと よくおすすめされてるのが axios
シンプルで軽量らしいのが got
ブラウザの fetch 互換なのが node-fetch
すごくシンプルで軽いけど新しすぎかつ知名度イマイチなのが phin
他にないかぐぐったら出てきたのが needle

とりあえずこの辺が選択肢です
使ったことあるのは request, superagent, node-fetch, phin
残りの got, axios, needle は使ったことないです

多くのライブラリが依存として使っていて機能も多い request が安定な気もします
ただ ちょっと重すぎるんです
ファイルサイズ的に

superagent も同じような印象でこれなら request でいっかと思えます

個人的には ブラウザ互換であるのが嬉しいので node-fetch を使うことが多いのですが ちょっとマイナー感もあります
ブラウザ互換を優先するために便利機能を入れてくれてなかったりもします
ただコードは軽くシンプルなので自分で軽く改造したりもしやすく 必要な機能を自分で追加して使ったこともあります

phin はすごく軽くて機能もそこまで多くないので とりあえず URL のデータとってきたいってときに使ってます
そこそこちゃんとしたものを作るときには別のものがいいかなというところ

axios はどっちかというとフロントエンドで React とかフレームワーク使ってる人がよく使っていて宣伝してる印象です
あんまり Node.js で使ってるイメージがないです

かと言って残り 2 つもなんかピンときません

調べる

ということで特に決まらないので npm のダウンロード数とか github の star 数とかファイルサイズとかを調べてみました

npmtrends を使ってみた結果です
https://www.npmtrends.com/needle-vs-axios-vs-got-vs-node-fetch-vs-superagent-vs-request-vs-phin

http-client-npmtrends-1909

グラフで気になったのが 年末年始のタイミングで一気に落ちてます
年末年始はどこの国も仕事してないからなのかな?
それとも npm 自体が落ちてたとか問題あったっけ?

それはさておき パッケージを見比べるとやっぱり request がダントツです
ほかが徐々に上がってきてるので差は縮まって来てますが それでも余裕を見せてます

意外だったのは node-fetch がなんと 2 位
下から 2 番目か 3 番目を想像してたのに……
これなら特殊なことしようとしない限り node-fetch でいい気がしました
グラフ的には去年は got と同じくらいで少し負けていたのが 2019 年の頭から一気に伸びています
なにか有名なライブラリの依存パッケージに選ばれたのでしょうか
8587 Dependents もあって ソートもできないので原因探しは諦めました

got が 3 位だったのも意外です
request, axios, superagent が TOP 3 だろうと思っていたのでもっと下だと思ってたのですけど

axios は勧めてる人もよく見かけて人気ぽく見えていて実は 4 位 5 位争いを needle としてる下の方でした
ただ github の star を見ると axios がダントツで 2 位の 3 倍弱あります
とりあえず話題に上がってるから star だけつけといたけど結局使ってない という感じでしょうか
ちなみに私も star だけつけて使ってない人の一人です

needle は他になにかないかググって見つけて知ったくらいのものなので phin くらいの立ち位置かなと思ってました
ですが意外と古いもので 2011 年にはあったそうです
request や superagent と同じ年です
star は少なめですが superagent よりはダウンロード数があって axios と同じくらいです

superagent はもっとダウンロードされてると思ったのですがなんとこの中では 下から 2 番目
最終更新は最近ですから放置されてるわけでもないのに どうして?
私みたいに superagent にするなら request でいいやという人が多かったのでしょうか

最後の phin は一番最近ですし 軽さのみに重点を当てたようなものなので こんなものだろうと思ってました
結局 1 番上と 1 番下以外は予想が外れていて自分の読みがあまり当てにならないことがわかりました

package phobia

npmtrends でもサイズは見れますが minify + zip したサイズです
ブラウザに送るときの通信量を考えるなら参考になりますが Node.js で単にロードするときは minify もしてない生のソースコードなのであまり当てになりません
request なんかは特に依存ファイルが重くて 実行環境が低スペックな VM だとロードだけで時間がかかるので実行時の待ち時間が目に見えて伸びます
あとインストールするときの待ち時間も地味に長いです
node_modules が大きくなるとその後の処理にも影響するので 必要ないなら小さめで依存も少ないパッケージがベストです

パッケージ自体のサイズと依存パッケージのサイズを知るには package phobia のほうが見やすいのでこっちを見てみます
結果を表にまとめました
minzip size は参考用で npmtrends  (bundle phobia) に載ってるものです

namepackage sizeinstall sizeminzip size
request203 KB4.46 MB179.8 KB
superagent415 KB1.48 MB6.2KB
needle195 KB706 KB163.8 KB
got84.4 KB302 KB16.0 KB
node-fetch153 KB153 KB282 B
axios323 KB409 KB4.3 KB
phin7.80 KB17.7 KB688 B

minify と比べるとほんとにあってるの?と思うところもありますね
コメントの量や変数の長さやタブかスペースかでも minify 後との差は変わりますが それでも
request の 4.46 MB → 179.8 KB

superagent の 1.48 MB → 6.2 KB
は差がありすぎます

それに
node-fetch の 153 KB → 282 B

phin の 17.7 KB → 688 B
もなんかおかしい気がします

実際インストールしてサイズを見た感じは package phobia と基本同じでした
ただ package size の方は一致してますが 依存パッケージに変化があったのか install size のほうは少し違ってるのもありました
サイズの違いは minify サイズを調べたタイミングの依存パッケージのバージョンの違いにも影響してそうです
それと minify の設定で doc comment や copyright を残すかでも変わってきそうです

とりあえずサイズは install size を見て比べます

やっぱり request は重すぎます
superagent も結構重いですが request に比べるとマシな方でした
needle も結構サイズがあります
古いものほど非効率な依存パッケージがいっぱいあったりするのですかね

node-fetch は外部依存もなく 153 KB と軽量特化の phin を除けば一番小さいです
got はシンプルさが売りなのに node-fetch の倍くらいありました
got が重いというよりは node-fetch が思った以上にサイズが小さいのだと思います
依存パッケージがある場合 それ専用に作ったわけでもないと 必要ない機能もあったりしますから重くなりやすいのですよね
サイズを減らすなら外部依存をなくすのが一番簡単なんで効果あるのに すでにある機能をわざわざ作り直したくないからと既存パッケージを使うので npm 周りはパッケージが重くなりがちです

axios は逆でもうちょっと重いのかなって思っていたので予想より軽めでした
phin は機能の少なさもありますがサイズの小ささはダントツです
依存パッケージが 1 つ centra というのがありますが 同じ作者で phin のコア部分を切り出してるみたいで 直接これを使うことは基本なさそうです

まとめ

調べてみると思ったより node-fetch がいい感じになってたので 基本は node-fetch を使おうと思います
ただ機能が足りないこともあると思うのでその場合に axios か got で これらでも足りてないなら request という感じでしょうか