ShopperCove
Menu
All writingBlogTopicsCategoriesAboutRSS
Blog
Categories
Observability & SRE62All categories
About

Plate 58

  1. Blog

Pathe vs node:path: 1.1 KB for Cross-OS Paths

Aditya Challa·5 October 2026·5 min read

Hands-on
On this page
  1. What I tested
  2. How much does pathe cost in a browser build?
  3. Is pathe slower than node:path?
  4. What does pathe change on Linux?
  5. Which one should you pick?
  6. Sources
  7. Related

I bundled pathe 2.0.3 for the browser at 2,268 B minified / 1,091 B gzip. node:path will not resolve in a browser esbuild build at all. On the same box, a mixed join/normalize/resolve workload ran about 38,000 ops/s with pathe versus about 114,000 ops/s with node:path — roughly 3× slower for the portable option.

Short answer: keep node:path in Node-only code. Add pathe when the same path helpers must run in the browser, in isomorphic Vite plugins, or when you need Windows backslashes normalized to / on every OS. No affiliate links in this post.

What I tested

  • Machine: 8 vCPU Intel Xeon / 15 GB RAM shared Linux cloud box, tested 6 Oct 2026 about 01:48 IST.
  • Versions: pathe 2.0.3, Node 22.20.0 built-in node:path and node:path/posix, esbuild 0.28.2 minify + gzip -9.
  • Fixture: /workspace/bench-pathe-node-path/. Workload: 8 sample path tuples run through join, normalize, basename, dirname, extname and resolve each iteration, 20,000 iterations per round, 9 rounds, median, after warm-up. Two runs with the order reversed. Bundle attempt: platform browser for all three; node:path and node:path/posix fail to resolve unless platform is node.
  • Findings: pathe 37,231 and 38,561 ops/s; node:path 113,894 and 114,507; node:path/posix 114,895 and 113,381. pathe gzip 1,091 B. On Linux, pathe treated C:\a\b as absolute and rewrote mixed slashes to /; node:path did not.
  • One surprise: node:path/posix was not a free "browser path" stand-in. It still needs the Node built-in, so esbuild browser builds reject it the same way as node:path.
  • Not tested: Windows host timings, Bun/Deno path APIs, URL fileURLtoPath, very long UNC paths, and tree-shaking of individual pathe named exports beyond the join/normalize/resolve set I imported.

How much does pathe cost in a browser build?

BuildMinifiedgzip -9Browser esbuild
pathe 2.0.3 (named exports I used)2,268 B1,091 Bok
node:path (platform browser)——resolve error
node:path (platform node, external)266 B stub162 BN/A (Node only)

The stub row is esbuild leaving the built-in external under platform node; it is not a browser polyfill. For front-end budgets, size-limit vs bundlesize will see about 1.1 KB. Vite-era tooling often already depends on pathe transitively — check with knip vs depcheck before adding another copy.

Is pathe slower than node:path?

Workload (8 samples × join/normalize/basename/dirname/extname/resolve, median of 9)pathenode:pathnode:path/posix
run 1 (pathe first)37,231 ops/s113,894 ops/s114,895 ops/s
run 2 (order reversed)38,561 ops/s114,507 ops/s113,381 ops/s

Yes, about 3× on this Linux box. That gap rarely matters for a few path joins per request or per plugin hook. It would matter in a hot loop over tens of thousands of file paths — the kind of scan tsx vs ts-node or a bundler entry walk might do on the server, where node:path stays free and faster.

What does pathe change on Linux?

Inputpathenode:path (Linux)
join("C:\Users\a", "src\main.ts")C:/Users/a/src/main.tsC:\Users\a/src\main.ts
normalize("foo\bar/baz/../qux")foo/bar/quxfoo\bar/qux
isAbsolute("C:\a\b")truefalse
isAbsolute("/a/b")truetrue
sep//
relative("/a/b/c", "/a/b/d")../d../d

pathe is a POSIX-slash path helper that still understands Windows prefixes. That is why Vite plugins and unjs tools pick it for code that may run under browser esbuild or on a mixed CI matrix. Pure Node services on Linux can stay on node:path and avoid the 1.1 KB. If your toolchain question is broader, see Vite vs Parcel and esbuild-register vs jiti.

Which one should you pick?

SituationMy pick
Node-only scripts and servers on one OSnode:path
Shared Vite plugin / isomorphic utilspathe
Browser bundle that must join pathspathe
Hot loop over huge file lists on the servernode:path
Need Windows paths correct while developing on Linuxpathe

Bottom line: pathe costs about 1.1 KB gzip and ran about 3× slower than node:path here, in exchange for browser builds and consistent / slashes across OS strings. Who should not add it: a pure Node CLI that never leaves the server and never sees backslash inputs. Package-manager and runtime choices around that CLI are covered in pnpm vs npm vs bun.

How this was made: I installed pathe on the ShopperCove box, measured esbuild minify+gzip for browser and node platforms, timed the mixed path workload in two order-reversed runs against node:path and node:path/posix, compared slash and isAbsolute behavior on Windows-style strings, and saved the JSON results. The write-up was drafted with AI help and checked against that output.

Sources

  • https://github.com/unjs/pathe
  • https://www.npmjs.com/package/pathe
  • https://nodejs.org/api/path.html
  • https://nodejs.org/api/path.html#pathposix

Related

  • https://www.shoppercove.com/blog/vite-vs-parcel
  • https://www.shoppercove.com/blog/size-limit-vs-bundlesize
  • https://www.shoppercove.com/blog/pnpm-vs-npm-vs-bun
  • https://www.shoppercove.com/blog/esbuild-register-vs-jiti
  • https://www.shoppercove.com/blog/tsx-vs-ts-node
  • https://www.shoppercove.com/blog/tinyexec-vs-execa
  • https://www.shoppercove.com/blog/knip-vs-depcheck
  • https://www.shoppercove.com/blog/unocss-vs-tailwind
pathenode:pathbrowseresbuildpath resolutionisomorphicperformancebundle size

Lab evidence

What I found running this

Hands-on on ShopperCove box 6 Oct 2026 ~01:48 IST (8 vCPU Intel Xeon / 15 GB shared Linux, Node 22.20.0). pathe 2.0.3 vs built-in node:path and node:path/posix, esbuild 0.28.2 minify + gzip -9. Fixture /workspace/bench-pathe-node-path/. Size: pathe 2,268/1,091 B browser-ok; node:path browser build errors with unresolved built-in; platform node stub 266/162 B. Speed (8 sample tuples × join/normalize/basename/dirname/extname/resolve, 20k iters, 9-round median, order-reversed): pathe 37,231 / 38,561 ops/s; node:path 113,894 / 114,507; posix 114,895 / 113,381. Behavior (res-behavior.json): pathe join/normalize turn Windows separators into / and isAbsolute("C:\a\b") is true; node:path on Linux keeps backslashes and returns false. Raw: res-bundle.json, res-speed-run1.json, res-speed-run2.json, res-behavior.json. Not tested: Windows host, Bun/Deno, UNC, per-export tree-shake beyond the imported set. No affiliate.

Notes when a lab post goes up

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

Related links

  • Plate 68

    Defu vs lodash.merge: 6x Faster, 452 B vs 4 KB

    5 Oct 2026

  • Plate 55

    Klona vs structuredClone: 1.4M vs 225k Clones per Second

    5 Oct 2026

  • Plate 91

    Tinyexec vs execa: 2.7 KB vs 37 KB Gzip

    5 Oct 2026

On this page

  1. What I tested
  2. How much does pathe cost in a browser build?
  3. Is pathe slower than node:path?
  4. What does pathe change on Linux?
  5. Which one should you pick?
  6. Sources
  7. Related
All writingBlogCategoriesTopicsAboutPrivacyRSS

© 2026 ShopperCove