ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 73

  1. Blog

volta vs fnm: Should You Switch? 14ms vs 17ms

volta 2.0.2 vs fnm 1.39.0 switching Node 20.19.2 ↔ 22.14.0: session A-then-B median 13.9 ms vs 17.0 ms; steady node -v 7.4 ms vs 6.4 ms (direct 4.7 ms).

Aditya Challa·5 October 2026·5 min read

Hands-on
On this page
  1. What I tested
  2. Is volta faster than fnm when switching projects?
  3. How much overhead does each add to node -v?
  4. Should you switch from fnm to volta (or the other way)?
  5. Sources
  6. Related

On two Node pins (20.19.2 and 22.14.0), a volta 2.0.2 session that cds project A then B and runs node -v took a median 13.9 ms. The same A-then-B path with fnm 1.39.0 (fnm use in each directory) took 17.0 ms (~1.22x). Steady node -v overhead was 7.4 ms for the volta shim and 6.4 ms for fnm exec, against 4.7 ms for the direct Node 20 binary.

Short answer: pick volta if you want package.json pins and automatic shims with no shell hook. Pick fnm if you prefer .node-version files, a lighter Rust binary, and fnm env in your shell. Speed is not a reason to migrate either way on this box. No affiliate links in this post.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM Linux cloud box, tested 5 Oct 2026 (about 23:20 to 23:26 IST). Runner for the harness was system /usr/bin/node v20.19.2 so Volta's _VOLTA_TOOL_RECURSION session pin could not skew child shells.
  • Fixture: two project directories. proj-a pinned Node 20.19.2; proj-b pinned 22.14.0. volta via package.json volta.node; fnm via .node-version.
  • Tools: volta 2.0.2 and fnm 1.39.0. Both already had both Node versions installed before timing (no download in the timed path).
  • Timing: two warmups, then nine interleaved rounds for switch/session paths and eleven for steady node -v. Wall clock via process.hrtime.
  • Findings: session A-then-B medians 13.93 ms (volta) vs 16.97 ms (fnm). Single-directory switch after visiting A: volta cd 8.42 ms, fnm exec 7.39 ms, fnm use 10.56 ms, volta run --node 7.60 ms. Re-running install for an already-present 20.19.2: volta 3.3 ms, fnm 2.9 ms.
  • One surprise: Volta children inherit _VOLTA_TOOL_RECURSION=1 from a parent started through its shim, so a nested harness must use a non-Volta Node or the pin looks stuck. Real interactive shells do not hit that trap.
  • Not tested: cold first-time downloads of Node, Windows/macOS, nvm, asdf, Corepack-only workflows, package-manager pins beyond Node.

Is volta faster than fnm when switching projects?

VariantMedian wallRuns (ms)
volta: bash cd A then B, node -v each13.9 ms14.5 / 13.5 / 14.3 / 14.7 / 13.9 / 13.8 / 15.3 / 13.5 / 13.0
fnm: fnm use A then B in one shell17.0 ms17.0 / 17.3 / 17.1 / 17.9 / 16.6 / 16.8 / 15.4 / 17.3 / 16.8
volta: resolve B after A (fresh shell each)8.4 ms8.6 / 9.4 / 8.6 / 8.3 / 8.0 / 8.0 / 8.4 / 7.6 / 8.8
fnm: fnm exec --using B after A7.4 ms7.5 / 8.1 / 8.0 / 6.9 / 7.1 / 6.7 / 7.6 / 7.4 / 6.4
fnm: fnm use B after A10.6 ms9.7 / 11.3 / 11.6 / 10.5 / 10.4 / 10.0 / 11.0 / 10.6 / 10.6

Slightly. The realistic "open project A, then project B" session favored volta by about 3 ms. fnm exec alone was the fastest single switch, but the common fnm use shell-hook path was the slowest of the four. Absolute times are tiny next to install or test suites; if you also care about which Node ships with which package manager, read the pnpm vs npm vs Bun post.

How much overhead does each add to node -v?

PathMedian wallRuns (ms)
Direct Node 20.19.2 binary4.7 ms4.8 / 4.4 / 4.6 / 4.5 / 5.4 / 5.1 / 5.2 / 4.9 / 4.6 / 4.6 / 4.7
volta shim via cd + node -v7.4 ms7.4 / 8.1 / 7.2 / 7.3 / 7.4 / 7.6 / 7.2 / 7.0 / 7.7 / 7.4 / 7.0
fnm exec --using 20.19.2 -- node -v6.4 ms6.1 / 6.5 / 7.1 / 6.9 / 6.4 / 6.2 / 6.9 / 5.8 / 6.4 / 6.0 / 5.8

About 2–3 ms over a direct binary. Neither shim is a problem for interactive work. For long-running tools the shim cost is paid once at process start; see the tsx vs ts-node post if the next question is how you launch TypeScript, and the Node.js 26 LTS schedule post if the question is which version to pin.

Should you switch from fnm to volta (or the other way)?

SituationMy pick
You want the pin inside package.json next to enginesvolta
You already standardize on .node-version / .nvmrcfnm (or stay)
You hate shell eval hooksvolta shims
You want the smallest Rust version managerfnm
Sub-20 ms switch times are "fast enough"Do not switch for speed
You are also changing TypeScript majorsDecide the Node pin first; then read TypeScript 7: Should You Upgrade?​

Bottom line: volta's A-then-B session was 13.9 ms vs fnm's 17.0 ms; steady shim overhead was 7.4 ms vs 6.4 ms. Who should not switch yet: anyone whose current manager already pins the right Node for every repo. Who should try volta: teams that want package.json-owned pins without a shell hook. Who should try fnm: teams that already live in .node-version land and want a fast Rust CLI.

How this was made: I installed both managers, pinned Node 20.19.2 and 22.14.0 in two fixture dirs, ran interleaved switch and overhead timings from a non-Volta harness Node, and kept the JSON; the write-up was drafted with AI help and checked against that output.

Sources

  • https://docs.volta.sh/
  • https://github.com/volta-cli/volta
  • https://github.com/Schniz/fnm
  • https://fnm.vercel.app/
  • https://nodejs.org/en/download

Related

  • https://www.shoppercove.com/blog/pnpm-vs-npm-vs-bun
  • https://www.shoppercove.com/blog/nodejs-26-lts-october-2026-schedule-change
  • https://www.shoppercove.com/blog/tsx-vs-ts-node
  • https://www.shoppercove.com/blog/typescript-7-should-you-upgrade
  • https://www.shoppercove.com/blog/turbo-vs-nx
  • https://www.shoppercove.com/blog/knip-vs-depcheck
  • https://www.shoppercove.com/blog/tsup-vs-unbuild
  • https://www.shoppercove.com/blog/c8-vs-nyc
voltafnmnode.jsversion managerbenchmarklinuxperformance

Lab evidence

What I found running this

Hands-on on ShopperCove box 5 Oct 2026 ~23:20-23:26 IST (8 vCPU Intel Xeon / 15 GB shared Linux). Harness runner: system /usr/bin/node v20.19.2 (avoids Volta _VOLTA_TOOL_RECURSION in children). Fixture: proj-a Node 20.19.2, proj-b Node 22.14.0 (volta package.json pin; fnm .node-version). Versions: volta 2.0.2, fnm 1.39.0; both Node versions pre-installed. 2 warmups; 9 interleaved switch/session rounds; 11 steady node -v rounds. Session A-then-B medians: volta 13.93 ms; fnm use 16.97 ms. Switch B after A: volta cd 8.42 ms; fnm exec 7.39 ms; fnm use 10.56 ms; volta run 7.60 ms. Steady node -v: direct 4.72 ms; volta shim 7.38 ms; fnm exec 6.36 ms. Reinstall existing 20.19.2: volta 3.3 ms; fnm 2.9 ms. Raw: /workspace/bench-volta-fnm/res-volta-fnm.json. Not tested: cold Node downloads, nvm/asdf, Windows/macOS, Corepack-only. No affiliate.

Notes when a lab post goes up

Occasional email for new hands-on reviews. No sequence and no sponsors.

Related links

  • Plate 90

    Path.read_text vs open().read: Localhost Lab

    1 Oct 2026

  • Plate 36

    lefthook vs husky: Should You Switch? 615ms vs 478ms

    husky 9.1.7 + lint-staged 16.2.3 vs lefthook 1.13.6 on a 40-file prettier pre-commit: local-bin medians 478 ms vs 615 ms (~1.29x); npx path 651 ms vs 765 ms; install 283 ms vs 256 ms.

    5 Oct 2026

  • Plate 68

    pnpm vs npm vs Bun: Which Installs Fastest? 14s, 3.1s, 1.5s

    npm 12.2.0 vs pnpm 12.9.1 vs Bun 1.4.2 on one 24-dependency React + Vite app: from scratch 14.2 s / 3.1 s / 1.5 s; lockfile + warm cache 2.9 s / 0.28 s / 0.27 s; lockfile + empty cache 3.9 s / 2.3 s / 0.45 s. Disk, lockfile size and the pnpm phantom-dependency catch.

    5 Oct 2026

On this page

  1. What I tested
  2. Is volta faster than fnm when switching projects?
  3. How much overhead does each add to node -v?
  4. Should you switch from fnm to volta (or the other way)?
  5. Sources
  6. Related
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove