Replit enforces a limit of account storage, so I’m investigating which Node.js package manager is most disk-efficient for a single project.
Disk usage is measured with gdu 5.13.2 on macOS 12.3, using the following command to prepare environment:
$ env HOME=$(mktemp -d) bash --init-file <(echo cd)
$ mkdir test && cd test
Contents
$ npm -v
8.5.5
$ npm i -D vite solid-js vite-plugin-solid typescript
$ gdu -n
**97.4 MiB /node_modules**
88.0 KiB package-lock.json
4.0 KiB package.json
$ gdu -n node_modules | head -n 10
**62.4 MiB /typescript**
8.7 MiB /esbuild
6.3 MiB /rollup
5.2 MiB /@babel
4.6 MiB /vite
3.3 MiB /caniuse-lite
1.1 MiB /ts-toolbelt
952.0 KiB /solid-js
800.0 KiB /source-map
644.0 KiB /resolve
# Global cache
$ gdu -ns ~/.npm/_cacache
43.4 MiB _cacache
nodeLinker: pnp
)<aside> ℹ️ Yarn also supports global hard links, but I won’t cover it here.
</aside>
$ npx yarn set version berry
$ npx yarn -v
3.2.0
$ npx yarn add -D vite solid-js vite-plugin-solid typescript
$ gdu -n
**52.9 MiB /.yarn**
624.0 KiB .pnp.cjs
64.0 KiB yarn.lock
12.0 KiB .pnp.loader.mjs
4.0 KiB .yarnrc.yml
4.0 KiB package.json
$ gdu -n .yarn
31.9 MiB /cache
18.9 MiB /unplugged
2.1 MiB /releases
152.0 KiB install-state.gz
$ gdu -n .yarn/cache | head -n 10
**10.9 MiB typescript-patch-30b732d1e2-6bf45caf84.zip
10.9 MiB typescript-npm-4.6.3-1493ebc82b-255bb26c8c.zip**
3.3 MiB esbuild-darwin-64-npm-0.14.28-5a7ada9fb8-8.zip
1.1 MiB rollup-npm-2.70.1-13154f7180-06c62933e6.zip
1.0 MiB vite-npm-2.8.6-60b9dced78-4b02d13389.zip
688.0 KiB caniuse-lite-npm-1.0.30001320-e77e9fa553-d1f52e9d8e.zip
500.0 KiB node-gyp-npm-9.0.0-0eccfca4d1-4d8ef8860f.zip
404.0 KiB @babel-parser-npm-7.17.8-667f8971e5-1771808491.zip
196.0 KiB source-map-npm-0.5.7-7c3f035429-5dc2043b93.zip
192.0 KiB iconv-lite-npm-0.6.3-24b8aae27e-3f60d47a5c.zip
$ gdu -n .yarn/unplugged
8.2 MiB /esbuild-npm-0.14.28-c2ae07b619
8.1 MiB /esbuild-darwin-64-npm-0.14.28-5a7ada9fb8
2.3 MiB /node-gyp-npm-9.0.0-0eccfca4d1
180.0 KiB /fsevents-patch-3340e2eb10
# Global cache
$ gdu -ns ~/.yarn/berry/cache
31.9 MiB cache
$ npx pnpm -v
6.32.3
$ npx pnpm i -D vite solid-js vite-plugin-solid typescript
$ gdu -n
**97.7 MiB /node_modules**
32.0 KiB pnpm-lock.yaml
4.0 KiB package.json
$ gdu -n node_modules/.pnpm | head -n 10
**62.5 MiB /typescript@4.6.3**
8.2 MiB /esbuild@0.14.28
6.4 MiB /rollup@2.70.1
4.6 MiB /vite@2.8.6
3.3 MiB /caniuse-lite@1.0.30001320
1.7 MiB /@babel+parser@7.17.8
1.4 MiB /@babel+types@7.17.0
1.1 MiB /ts-toolbelt@9.6.0
932.0 KiB /solid-js@1.3.13
772.0 KiB /source-map@0.5.7
$ gdu -n ~
96.5 MiB /.pnpm-store # Global store
20.4 MiB /Library # Global cache (~/Library/Caches/pnpm)
**2.9 MiB /test # node_modules sans hard links**
First of all, this only tests a common scenario (Vite + TypeScript + random framework). Results may vary wildly depending on the actual needs.
We see Yarn (PnP) is the clear winner here. Due to its usage of compressed modules, the biggest offender a.k.a typescript
only consumes 1/3 space compared to npm or pnpm.
However, the symlink approach pnpm takes is certainly going to take off on your own machine, which typically hosts multiple projects at the same time.
That said, you will want to keep using npm on Replit: