😎

npm, yarn(v1, v4), pnpmの初回パッケージインストールをベンチマークしてみた at 2025-08-13

に公開

結果まとめ

  • npm 11.5.2: 55.31 secs
  • yarn 1.22.22: 73.16 secs
  • yarn 4.9.2: 15.31 secs
  • pnpm 10.14: 29.29 secs

はじめに

会社でパッケージマネージャの話になったので、採用観点の一つとして初回インストール時(キャッシュや既存のnode_modulesが無い状態)のインストール時間を計測しました。

測り方はこちらの記事を参考にしました。

https://zenn.dev/minedia/articles/2023-08-30-pnpm

なおパッケージの初回インストールはあまり発生するものではないので、実際の判断基準にはパッケージの追加・削除の時間や、他ツールとの互換性なども考慮した上で、採用を検討してください。

実験環境

2025-08-13 時点の eslint のリポジトリを用います。

https://github.com/eslint/eslint/tree/7093cb8f590ec2a1b5364d7b5687e9b5f4e06f8a
https://github.com/eslint/eslint/blob/7093cb8f590ec2a1b5364d7b5687e9b5f4e06f8a/package.json

> ~/p/s/n/eslint on main ◦ node -v> ~/p/s/n/eslint on main ◦ which node
/Users/pc386/.local/share/mise/installs/node/22.18.0/bin/node

余談ですが eslint は package.json#packageManager も任意の lock ファイルも無いことを知りました。無くても何とかなるのかー。

使用するパッケージマネージャは以下です。

  • npm 11.5.2
  • yarn 1.22.22
  • yarn 4.9.2
  • pnpm 10.14

corepack だと事前にパッケージマネージャのみをインストールしておく方法がいまいち分からなかったので、mise を使用します。

また効果があるかはよくわかりませんが、一応変なキャッシュが効かないように毎回別名で git clone し直します。

npm

.github/workflows/ を見る限りは npm をデフォのパッケージマネージャーとしていそう。

> ~/p/s/n/eslint-npm on main ◦ time npm install
... ログ省略
________________________________________________________
Executed in   55.31 secs    fish           external
   usr time   11.00 secs    0.22 millis   11.00 secs
   sys time   10.43 secs    1.26 millis   10.43 secs
ログ全部
> ~/p/s/node-pm-track git clone https://github.com/eslint/eslint eslint-npm 
Cloning into 'eslint-npm'...
... ログ省略
⋊> ~/p/s/node-pm-track ./eslint-npm/
⋊> ~/p/s/n/eslint-npm on main ◦ mise use npm@11.5.2
⋊> ~/p/s/n/eslint-npm on main ◦ npm -v
11.5.2
⋊> ~/p/s/n/eslint-npm on main ◦ time npm install
npm warn deprecated inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
npm warn deprecated readdir-scoped-modules@1.1.0: This functionality has been moved to @npmcli/fs
npm warn deprecated debuglog@1.0.1: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
npm warn deprecated lodash.get@4.4.2: This package is deprecated. Use the optional chaining (?.) operator instead.
npm warn deprecated read-package-json@2.1.2: This package is no longer supported. Please use @npmcli/package-json instead.
npm warn deprecated lodash.pick@4.4.0: This package is deprecated. Use destructuring assignment syntax instead.
npm warn deprecated rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm warn deprecated glob@7.2.3: Glob versions prior to v9 are no longer supported
npm warn deprecated read-installed@4.0.3: This package is no longer supported.
npm warn deprecated sinon@11.1.2: 16.1.1

added 1182 packages, and audited 1184 packages in 55s

208 packages are looking for funding
  run `npm fund` for details

12 vulnerabilities (10 high, 2 critical)

To address all issues possible (including breaking changes), run:
  npm audit fix --force

Some issues need review, and may require choosing
a different dependency.

Run `npm audit` for details.

________________________________________________________
Executed in   55.31 secs    fish           external
   usr time   11.00 secs    0.22 millis   11.00 secs
   sys time   10.43 secs    1.26 millis   10.43 secs

yarn v1

> ~/p/s/n/eslint-yarn-v1 on main ◦ time yarn install
yarn install v1.22.22
... ログ省略
________________________________________________________
Executed in   73.16 secs    fish           external
   usr time   13.34 secs    0.23 millis   13.34 secs
   sys time   22.28 secs    1.06 millis   22.27 secs
ログ全部
> ~/p/s/node-pm-track git clone https://github.com/eslint/eslint eslint-yarn-v1
Cloning into 'eslint-yarn-v1'...
... ログ省略
⋊> ~/p/s/node-pm-track ./eslint-yarn-v1/
⋊> ~/p/s/n/eslint-yarn-v1 on main ◦ mise use yarn@1.22.22
mise ~/projects/sandbox/node-pm-track/mise.toml tools: yarn@1.22.22
⋊> ~/p/s/n/eslint-yarn-v1 on main ◦ yarn -v
1.22.22
⋊> ~/p/s/n/eslint-yarn-v1 on main ◦ time yarn install
yarn install v1.22.22
warning ../../../package.json: No license field
info No lockfile found.
[1/5] 🔍  Validating package.json...
[2/5] 🔍  Resolving packages...
warning c8 > rimraf@3.0.2: Rimraf versions prior to v4 are no longer supported
warning c8 > rimraf > glob@7.2.3: Glob versions prior to v9 are no longer supported
warning c8 > test-exclude > glob@7.2.3: Glob versions prior to v9 are no longer supported
warning c8 > rimraf > glob > inflight@1.0.6: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
warning cheerio > lodash.pick@4.4.0: This package is deprecated. Use destructuring assignment syntax instead.
warning npm-license > read-installed@4.0.3: This package is no longer supported.
warning npm-license > read-installed > debuglog@1.0.1: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
warning npm-license > read-installed > readdir-scoped-modules@1.1.0: This functionality has been moved to @npmcli/fs
warning npm-license > read-installed > readdir-scoped-modules > debuglog@1.0.1: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.
warning npm-license > read-installed > read-package-json@2.1.2: This package is no longer supported. Please use @npmcli/package-json instead.
warning npm-license > read-installed > read-package-json > glob@7.2.3: Glob versions prior to v9 are no longer supported
warning sinon@11.1.2: 16.1.1
warning sinon > @sinonjs/samsam > lodash.get@4.4.2: This package is deprecated. Use the optional chaining (?.) operator instead.
[3/5] 🚚  Fetching packages...
[4/5] 🔗  Linking dependencies...
[5/5] 🔨  Building fresh packages...
success Saved lockfile.
✨  Done in 72.99s.

________________________________________________________
Executed in   73.16 secs    fish           external
   usr time   13.34 secs    0.23 millis   13.34 secs
   sys time   22.28 secs    1.06 millis   22.27 secs

余談

corepack を使ってないのに corepack が yarn を呼び出そうとして、謎のバージョンを使うエラーが起こっていた。
issue があったので見てみたら、SKIP_YARN_COREPACK_CHECK というバグ解消専用ぽいオプションの情報があったので、設定したらいけた。
corepack じゃなくて yarn 側の問題なのかな。

https://github.com/yarnpkg/yarn/issues/9015

yarn v4

> ~/p/s/n/eslint-yarn-v4 on main ◦ time yarn install
➤ YN0000: · Yarn 4.9.2
... ログ省略
________________________________________________________
Executed in   15.31 secs    fish           external
   usr time   13.33 secs    0.20 millis   13.33 secs
   sys time    6.19 secs    1.07 millis    6.19 secs
ログ全部
> ~/p/s/node-pm-track git clone https://github.com/eslint/eslint eslint-yarn-v4
Cloning into 'eslint-yarn-v4'...
... ログ省略
⋊> ~/p/s/node-pm-track ./eslint-yarn-v4/
⋊> ~/p/s/n/eslint-yarn-v4 on main ◦ mise use yarn@4.9.2
mise yarn@4.9.2         ✓ installed                                          mise ~/projects/sandbox/node-pm-track/mise.toml tools: yarn@4.9.2
⋊> ~/p/s/n/eslint-yarn-v4 on main ◦ yarn -v
4.9.2
⋊> ~/p/s/n/eslint-yarn-v4 on main ◦ time yarn install
➤ YN0000: · Yarn 4.9.2
➤ YN0000: ┌ Resolution step
➤ YN0085: │ + @arethetypeswrong/cli@npm:0.18.2, @babel/core@npm:7.28.0, @babel/preset-env@npm:7.28.0, and 1117 more.
➤ YN0000: └ Completed in 6s 751ms
➤ YN0000: ┌ Post-resolution validation
➤ YN0086: │ Some peer dependencies are incorrectly met by dependencies; run yarn explain peer-requirements for details.
➤ YN0000: └ Completed
➤ YN0000: ┌ Fetch step
➤ YN0013: │ 479 packages were added to the project (+ 298.94 MiB).
➤ YN0000: └ Completed in 2s 919ms
➤ YN0000: ┌ Link step
➤ YN0000: │ ESM support for PnP uses the experimental loader API and is therefore experimental
➤ YN0007: │ core-js@npm:3.45.0 must be built because it never has been before or the last one failed
➤ YN0007: │ cypress@npm:14.5.4 must be built because it never has been before or the last one failed
➤ YN0007: │ es5-ext@npm:0.10.64 must be built because it never has been before or the last one failed
➤ YN0007: │ re2@npm:1.22.1 must be built because it never has been before or the last one failed
➤ YN0007: │ yorkie@npm:2.0.0 must be built because it never has been before or the last one failed
➤ YN0007: │ oxc-resolver@npm:11.6.1 must be built because it never has been before or the last one failed
➤ YN0000: └ Completed in 5s 29ms
➤ YN0000: · Done with warnings in 14s 800ms

________________________________________________________
Executed in   15.31 secs    fish           external
   usr time   13.33 secs    0.20 millis   13.33 secs
   sys time    6.19 secs    1.07 millis    6.19 secs

pnpm

> ~/p/s/n/eslint-pnpm on main ◦ time pnpm install
... ログ省略
Done in 29s using pnpm v10.14.0

________________________________________________________
Executed in   29.29 secs    fish           external
   usr time   10.40 secs    0.23 millis   10.40 secs
   sys time   18.68 secs    1.23 millis   18.68 secs
ログ全部
> ~/p/s/node-pm-track git clone https://github.com/eslint/eslint eslint-pnpm
Cloning into 'eslint-pnpm'...
... ログ省略
⋊> ~/p/s/n/eslint-pnpm on main ◦ mise use pnpm@10.14
mise pnpm@10.14.0       ✓ installed
mise ~/projects/sandbox/node-pm-track/mise.toml tools: pnpm@10.14.0
⋊> ~/p/s/n/eslint-pnpm on main ◦ pnpm -v
10.14.0
⋊> ~/p/s/n/eslint-pnpm on main ◦ time pnpm install
 WARN  deprecated sinon@11.1.2: 16.1.1
 WARN  9 deprecated subdependencies found: debuglog@1.0.1, glob@7.2.3, inflight@1.0.6, lodash.get@4.4.2, lodash.pick@4.4.0, read-installed@4.0.3, read-package-json@2.1.2, readdir-scoped-modules@1.1.0, rimraf@3.0.2
Packages: +1087
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Progress: resolved 1110, reused 2, downloaded 1090, added 1087, done

dependencies:
+ @eslint-community/eslint-utils 4.7.0
+ @eslint-community/regexpp 4.12.1
+ @eslint/config-array 0.21.0
+ @eslint/config-helpers 0.3.1
+ @eslint/core 0.15.2
+ @eslint/eslintrc 3.3.1
+ @eslint/js 9.33.0
+ @eslint/plugin-kit 0.3.5
+ @humanfs/node 0.16.6
+ @humanwhocodes/module-importer 1.0.1
+ @humanwhocodes/retry 0.4.3
+ @types/estree 1.0.8
+ @types/json-schema 7.0.15
+ ajv 6.12.6 (8.17.1 is available)
+ chalk 4.1.2 (5.5.0 is available)
+ cross-spawn 7.0.6
+ debug 4.4.1
+ escape-string-regexp 4.0.0 (5.0.0 is available)
+ eslint-scope 8.4.0
+ eslint-visitor-keys 4.2.1
+ espree 10.4.0
+ esquery 1.6.0
+ esutils 2.0.3
+ fast-deep-equal 3.1.3
+ file-entry-cache 8.0.0 (10.1.3 is available)
+ find-up 5.0.0 (7.0.0 is available)
+ glob-parent 6.0.2
+ ignore 5.3.2 (7.0.5 is available)
+ imurmurhash 0.1.4
+ is-glob 4.0.3
+ json-stable-stringify-without-jsonify 1.0.1
+ lodash.merge 4.6.2
+ minimatch 3.1.2 (10.0.3 is available)
+ natural-compare 1.4.0
+ optionator 0.9.4

devDependencies:
+ @arethetypeswrong/cli 0.18.2
+ @babel/core 7.28.0
+ @babel/preset-env 7.28.0
+ @cypress/webpack-preprocessor 6.0.4 (7.0.0 is available)
+ @eslint/json 0.13.1
+ @trunkio/launcher 1.3.4
+ @types/esquery 1.5.4
+ @types/node 22.17.1 (24.2.1 is available)
+ @typescript-eslint/parser 8.39.1
+ babel-loader 8.4.1 (10.0.0 is available)
+ c8 7.14.0 (10.1.3 is available)
+ chai 4.5.0 (5.2.1 is available)
+ cheerio 0.22.0 (1.1.2 is available)
+ common-tags 1.8.2
+ core-js 3.45.0
+ cypress 14.5.4
+ ejs 3.1.10
+ eslint 9.33.0
+ eslint-config-eslint 11.0.0
+ eslint-plugin-eslint-plugin 6.5.0 (7.0.0 is available)
+ eslint-plugin-expect-type 0.6.2
+ eslint-plugin-yml 1.18.0
+ eslint-release 3.3.0
+ eslint-rule-composer 0.3.0
+ eslump 3.0.0
+ esprima 4.0.1
+ fast-glob 3.3.3
+ fs-teardown 0.1.3 (0.3.2 is available)
+ glob 10.4.5 (11.0.3 is available)
+ globals 16.3.0
+ got 11.8.6 (14.4.7 is available)
+ gray-matter 4.0.3
+ jiti 2.5.1
+ jiti-v2.0 <- jiti 2.0.0 (2.5.1 is available)
+ jiti-v2.1 <- jiti 2.1.2 (2.5.1 is available)
+ knip 5.62.0
+ lint-staged 11.2.6 (16.1.5 is available)
+ markdown-it 12.3.2 (14.1.0 is available)
+ markdown-it-container 3.0.0 (4.0.0 is available)
+ marked 4.3.0 (16.1.2 is available)
+ metascraper 5.49.1
+ metascraper-description 5.49.1
+ metascraper-image 5.49.1
+ metascraper-logo 5.49.1
+ metascraper-logo-favicon 5.49.1
+ metascraper-title 5.49.1
+ mocha 11.7.1
+ node-polyfill-webpack-plugin 1.1.4 (4.1.0 is available)
+ npm-license 0.3.3
+ pirates 4.0.7
+ progress 2.0.3
+ proxyquire 2.1.3
+ recast 0.23.11
+ regenerator-runtime 0.14.1
+ semver 7.7.2
+ shelljs 0.10.0
+ sinon 11.1.2 (21.0.0 is available) deprecated
+ typescript 5.9.2
+ webpack 5.101.1
+ webpack-cli 4.10.0 (6.0.1 is available)
+ yorkie 2.0.0

╭ Warning ──────────────────────────────────────────────────────────────────────────────╮
│                                                                                       │
│   Ignored build scripts: core-js, cypress, es5-ext, oxc-resolver, re2, yorkie.        │
│   Run "pnpm approve-builds" to pick which dependencies should be allowed to run       │
│   scripts.                                                                            │
│                                                                                       │
╰───────────────────────────────────────────────────────────────────────────────────────╯

Done in 29s using pnpm v10.14.0

________________________________________________________
Executed in   29.29 secs    fish           external
   usr time   10.40 secs    0.23 millis   10.40 secs
   sys time   18.68 secs    1.23 millis   18.68 secs

余談

2週前の最新バージョンで nodejs 自体のインストールにも対応してた。これ minor changes でいいの?

https://github.com/pnpm/pnpm/releases/tag/v10.14.0

エアークローゼットテックブログ

Discussion