url.pathToFileURL()

Converts a filesystem path into an absolute file: URL with control characters correctly escaped.

Signature
url.pathToFileURL(path[, options])
  • Added in Node.js v10.12.0

Parameters

ParameterTypeDescription
$pathstringThe path to convert to a File URL.
$optionsoptionalObjectOptions controlling how the path is interpreted.
$options.windowsoptionalboolean | undefined= undefinedtrue if the path should be treated as a windows filepath, false for posix, and undefined for the system default.

Return value

URLThe file URL object.

Errors

Throws a TypeError when path is not a string.

Changelog

  • PHP v22.1.0, v20.13.0The options argument can now be used to determine how to return the path value, including forcing Windows or POSIX rules.

pathToFileURL() is the inverse of fileURLToPath(). It resolves the path to an absolute one against the current working directory, then percent-encodes the characters that would otherwise change the URL's meaning.

When to reach for it

Use it any time a path has to cross into an API that expects a URL. The common case is await import(pathToFileURL(file).href) — dynamic import() of a plain absolute path fails on Windows and is unreliable elsewhere, whereas a file: URL always works. It is also the right input for new URL(relative, base) when the base is a file on disk, and for loader hooks and source-map tooling that key on URLs.

What trips people up

The whole reason to use it instead of 'file://' + path is escaping. A filename containing # would otherwise start a fragment and a ? would start a query, silently truncating the path; pathToFileURL encodes them as %23 and %3F, so the resulting URL has empty hash and search. Spaces become %20.

Because the result is always absolute, a relative input is resolved against process.cwd() at call time — not against the calling module. If you mean "next to this file", build from import.meta.url instead.

Example

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

When to use it

  • Dynamically import a module found by scanning a directory
  • Build a base URL for resolving relative references against a file on disk
  • Hand a local file to an API that only accepts URLs, such as a loader hook
  • Produce the file: URL a stack trace or source map will report

Frequently asked questions

Why does dynamic import fail with an absolute path?

import() expects a URL specifier, and a bare path is ambiguous — on Windows it is not a valid URL at all. Wrap it: await import(pathToFileURL(p).href).

What does pathToFileURL do that 'file://' + path does not?

It resolves the path to absolute and percent-encodes characters such as space, #, and ? that would otherwise be read as URL syntax and truncate the path. Concatenation also produces the wrong number of slashes for Windows drive letters.

Is the result relative to my module or to the working directory?

To the working directory — relative paths are resolved with process.cwd(). To get a URL relative to the current module, use new URL('file.txt', import.meta.url) instead.

More examples

Dynamically importing a file found on disk

import() takes a URL string, not a path. The space is encoded as %20 so the specifier is valid, and the module loads; passing the raw path would work by accident on POSIX and fail on Windows.

Example · javascript
import { pathToFileURL } from 'node:url';
import fs from 'node:fs';

fs.writeFileSync('plugin one.mjs', 'export const name = "one";\n');

const href = pathToFileURL('plugin one.mjs').href;
console.log(href.endsWith('/plugin%20one.mjs'));

const mod = await import(href);
console.log('loaded plugin:', mod.name);

fs.unlinkSync('plugin one.mjs');

Using a file URL as a base for relative references

URL resolution replaces the last segment, so 'database.json' lands beside app.json and '../shared.json' climbs one level. Converting back with fileURLToPath gives a real path once you are done resolving.

Example · javascript
const { pathToFileURL, fileURLToPath } = require('node:url');

const base = pathToFileURL('config/app.json');
console.log(new URL('database.json', base).pathname.split('/').slice(-2).join('/'));
console.log(new URL('../shared.json', base).pathname.split('/').slice(-2).join('/'));

const resolved = new URL('database.json', base);
console.log(fileURLToPath(resolved).endsWith('/config/database.json'));

Forcing Windows path rules

With windows: true the drive letter becomes /C:/ and backslashes become forward slashes, while a UNC path turns into a file URL with the server as the host. This lets a tool generate URLs for the other platform without running on it.

Example · javascript
const { pathToFileURL } = require('node:url');

console.log(pathToFileURL('C:\\Users\\carol\\a b.txt', { windows: true }).href);
console.log(pathToFileURL('\\\\server\\share\\file.txt', { windows: true }).href);
console.log(pathToFileURL('/srv/app/a b.txt', { windows: false }).href);

Discussion

  • Be the first to comment on this lesson.