path.win32

Provides Windows-rule implementations of every path method, identical on every platform.

Signature
path.win32
  • Added in Node.js v0.11.15

Return value

<Object>An object exposing the same methods and properties as the `node:path` module, but always applying Windows rules: `\` as the separator, `;` as the delimiter, and drive-letter, UNC and namespaced-path handling.

Errors

Nothing by itself; individual methods on it throw TypeError (ERR_INVALID_ARG_TYPE) when given a non-string path.

Changelog

  • PHP v15.3.0Also exposed as its own module, so require('node:path/win32') returns the same object.

path.win32 is the whole path API frozen to Windows rules. It treats both \ and / as separators but emits \, uses ; as the PATH delimiter, understands drive letters (C:), UNC shares (\\server\share) and namespaced paths (\\?\C:\) — on Linux and macOS just as much as on Windows.

When to reach for it

Reach for it when a POSIX machine has to reason about paths belonging to a Windows machine: a build server producing Windows installer manifests, a CI job on Linux validating paths from a Windows agent, log or crash-dump analysis, a test suite that must assert Windows behaviour without a Windows runner, or splitting a Windows PATH string on path.win32.delimiter.

What trips people up

The plain platform default is the trap this exists to solve: path.basename('C:\temp\myfile.html') returns the entire string on Linux, because there is no separator in it under POSIX rules. Switch to path.win32.basename() and it returns myfile.html everywhere.

Two methods are still host-dependent. path.win32.resolve() falls back to the real process.cwd() for relative input, so on Linux it produces a rootless, backslash-mangled string; pass an absolute Windows path as the first argument to keep it deterministic. And relative() across drives cannot produce a relative result, so it returns the target unchanged.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Parsing Windows paths out of logs or crash dumps on a Linux server
  • Generating Windows installer or shortcut manifests from a macOS or Linux build
  • Unit-testing Windows path handling without a Windows CI runner
  • Splitting a Windows %PATH% string on ; and joining each entry with an executable name

Frequently asked questions

How do I parse a Windows path on Linux or macOS?

Use path.win32 instead of path — path.win32.parse(), .basename(), .dirname() and the rest apply Windows rules on any host. The plain path module aliases path.posix off Windows, so it sees C:\\temp\\file.txt as one long filename with no separators in it.

Why does path.basename return the whole string for a Windows path?

Because on a non-Windows host path is path.posix, and POSIX rules treat \\ as an ordinary filename character, so the string contains no separator to split on. Call path.win32.basename() for the Windows-rule answer, which is the same on every platform.

Does path.win32 work on Linux?

Yes — it is pure string manipulation and never touches the filesystem, so every method returns the Windows answer regardless of host. The two exceptions are resolve(), which falls back to the real process.cwd() when no absolute path is supplied, and toNamespacedPath(), which resolves relative input against that same cwd before doing anything else: on Linux or macOS it hands back the resolved working-directory path with its separators flipped to backslashes and no namespace prefix added, not the string you passed in.

More examples

Taking a Windows path apart

parse() reports root C:\\, dir C:\\Users\\manu, base notes.tar.gz, ext .gz and name notes.tar — only the final extension counts. The three isAbsolute() calls print true, true, false: a drive-rooted path and a UNC share are absolute, a bare relative one is not. normalize() accepts the forward slashes as separators and still emits C:\\Users\\manu\\app.exe, and toNamespacedPath() prints \\\\?\\C:\\foo\\bar.

Example · javascript
const path = require('node:path');

console.log(JSON.stringify(path.win32.parse('C:\\Users\\manu\\notes.tar.gz')));
console.log(path.win32.isAbsolute('C:\\temp'));
console.log(path.win32.isAbsolute('\\\\server\\share\\file'));
console.log(path.win32.isAbsolute('temp\\file'));
console.log(path.win32.normalize('C:/Users//manu/docs/../app.exe'));
console.log(path.win32.toNamespacedPath('C:\\foo\\bar'));

Splitting a Windows PATH on a Linux host

Splitting on path.win32.delimiter (;) rather than path.delimiter (: on Linux) is what makes this work off Windows — a colon split would tear C: away from its path. The joins print the three candidate node.exe locations, the first relative() prints ..\\..\\impl\\bbb, and the cross-drive one prints D:\\data because no relative path can cross from C: to D:.

Example · javascript
const path = require('node:path');

const PATH = 'C:\\Windows\\system32;C:\\Windows;C:\\Program Files\\nodejs\\';
for (const dir of PATH.split(path.win32.delimiter)) {
  console.log(path.win32.join(dir, 'node.exe'));
}

console.log(path.win32.relative('C:\\orandea\\test\\aaa', 'C:\\orandea\\impl\\bbb'));
console.log(path.win32.relative('C:\\app', 'D:\\data'));

Choosing a rule set explicitly

The first two lines print true: node:path/win32 (v15.3.0) is the same object as path.win32, and each variant links back to the other. The loop shows the pattern for cross-compiling output paths — pick the rule set by target platform instead of letting the host decide — printing build\\out\\app.exe and build/out/app from one code path.

Example · javascript
const path = require('node:path');
const win32 = require('node:path/win32');

console.log(win32 === path.win32);
console.log(win32.posix === path.posix);

const rules = { windows: path.win32, linux: path.posix };
for (const [target, p] of Object.entries(rules)) {
  console.log(target, p.join('build', 'out', 'app' + (target === 'windows' ? '.exe' : '')));
}

Discussion

  • Be the first to comment on this lesson.