pathe
A drop-in, dependency-free replacement for Node.js's path module that normalizes every path to POSIX slashes, on any platform.
Repository Health
Technical Analysis
pathe re-implements Node.js’s built-in path module from scratch so that path handling behaves identically on Windows, macOS, and Linux. Node’s own path module silently switches behavior based on the host OS — using backslashes on Windows and forward slashes everywhere else — which causes code that works on a developer’s Mac to fail once it runs in a Windows CI runner or a Windows-hosted deployment. pathe exports the exact same function signatures as node:path (join, resolve, normalize, relative, dirname, basename, extname, parse, format, isAbsolute, plus posix/win32 namespaces) but always normalizes to /, so a single code path works everywhere.
Unlike node:path, pathe has zero runtime dependencies and is written entirely in modern TypeScript/ESM, which means it also runs unmodified in browsers, edge runtimes, and other non-Node JavaScript environments where the built-in path module isn’t available at all. It ships an extra pathe/utils subpath with utilities not found in Node’s module — filename() for extension-free basenames, and resolveAlias()/reverseResolveAlias()/normalizeAliases() for resolving TypeScript-style path aliases (@/foo → ./src/foo) — plus a built-in matchesGlob() glob matcher ported from zeptomatch.
Built and maintained by the UnJS team (the group behind Nitro, h3, and other Vite/Nuxt-ecosystem tooling), pathe is a foundational dependency pulled in by Vite, Vitest, Nuxt, and dozens of other build tools specifically to get consistent, cross-platform path handling without pulling in Node’s platform-dependent behavior.
What You Get
- A complete, drop-in replacement for every function in
node:path—join,resolve,normalize,relative,dirname,basename,extname,parse,format,isAbsolute,sep,delimiter— with matching TypeScript signatures. - Consistent POSIX-style forward-slash output regardless of the host operating system, eliminating the Windows-vs-POSIX behavior split baked into Node’s own module.
- Zero runtime dependencies and no reliance on Node.js APIs, so the same code runs in Node, browsers, and edge/serverless runtimes.
- Extra utilities via the
pathe/utilssubpath:filename()for extension-stripped basenames,matchesGlob()for glob-pattern matching against a path, andresolveAlias()/reverseResolveAlias()/normalizeAliases()for resolving import-alias mappings (e.g.@/style aliases) in either direction.
Common Use Cases
- Build tools and bundlers (Vite, Vitest, Nuxt, Nitro) that need to manipulate file paths consistently across contributors’ operating systems and CI runners.
- Libraries that must work identically whether they’re executed under Node.js or bundled into a browser/edge runtime that has no
pathmodule at all. - Resolving TypeScript/webpack-style path aliases (
@/components/Button→src/components/Button) back and forth between alias and real filesystem paths. - Matching file paths against glob patterns (e.g. include/exclude lists in a bundler or file watcher) without pulling in a separate glob-matching dependency.
Under The Hood
Architecture
pathe is organized into a small set of single-responsibility modules: _path.ts holds the core reimplementation of every node:path function (ported from and kept in sync with Node’s own lib/path.js, per the sync-date comment at the top of the file), _internal.ts holds a single normalizeWindowsPath() helper used throughout for backslash-to-slash conversion, _glob.ts is a self-contained glob-to-regex matcher ported from zeptomatch’s parser-combinator approach, and utils.ts layers alias-resolution and filename helpers on top of join. index.ts ties it together with a Proxy-based mix() function that produces the posix/win32/default namespace objects without materializing separate copies of every function — a tree-shaking-friendly pattern that avoids the object-spread overhead Node’s own module pays for the same posix/win32 split. Because normalizeString() (the ported core normalization algorithm) underpins normalize, join, and resolve, it is the one abstraction the rest of the library is most sensitive to changes in.
Tech Stack
Written entirely in TypeScript and shipped as ESM-only ("type": "module"), with builds produced by obuild and zero runtime dependencies declared in package.json. Linting and formatting run through oxlint/oxfmt, the Rust-based tooling from the Oxc project, rather than ESLint/Prettier. Type-checking uses tsgo (the TypeScript native-preview compiler), and tests run under Vitest with @vitest/coverage-v8 for coverage reporting. Releases are cut with changelogen, and the package is managed inside a pnpm workspace.
Code Quality
The test suite is extensive relative to the library’s surface area: a single glob-matching spec file runs thousands of lines of pattern-matching cases, cross-checked against Node’s own glob test fixtures in a dedicated file, alongside separate specs for the core path API and the alias/filename utilities. CI (GitHub Actions) runs linting, the build, tsgo type-checking, and the full Vitest suite with coverage on every push and pull request to main, so regressions in cross-platform behavior are caught before release. Public functions are typed directly against typeof path.X from node:path, which mechanically enforces signature parity with the module this library replaces.
API Design
The entire public API is a byte-for-byte name match with Node’s built-in path module, so there is effectively no learning curve for anyone who already knows path.join/path.resolve/etc. — adoption is a single import swap. The extra pathe/utils subpath keeps non-standard additions (alias resolution, glob matching) cleanly separated from the core drop-in surface, so consumers who only need standard path behavior never see the extended API. Documentation is concise but sufficient: the README states the rationale plainly and shows the two import forms (default ESM import and CommonJS require) up front.
Used by 6 apps in this directory
Kimi Code CLI
AI Code Assistants · AI Agents · Developer Tools
A single-binary, terminal-native coding agent that reads, edits, and runs code end to end, built by Moonshot AI for Kimi models but pluggable with Anthropic, OpenAI, and Google providers too.
likec4
Developer Tools · Devops
Define your software architecture as code and get always up-to-date, interactive C4 diagrams generated automatically from a DSL.
LobeHub
AI Assistants · Productivity · Automation
Your Chief Agent Operator — build, schedule, and collaborate with an entire AI team in one self-hostable workspace.
Notesnook
Note Taking · File Storage · Security
End-to-end encrypted, open-source note-taking where your data stays yours — even from the server.
Scalar
Developer Tools
Beautiful, interactive OpenAPI documentation with a built-in offline-first API client and multi-language code generation — all in one open-source platform.
Unlighthouse
Developer Tools
An open-source CLI that scans your entire website with Google Lighthouse, using smart sampling and a modern dashboard UI to audit every page instead of one URL at a time.