NodeJSThe url Module

The url Module

Parsing URLs by hand with string splitting is a reliable source of bugs. node:url — and specifically the WHATWG URL class, the same one browsers use — does it correctly: percent-encoding, ports, query strings, and relative resolution all handled to spec. Modern Node makes URL a global, so you usually don't even import it.

The URL class

JS
// URL is a global — no import needed
const u = new URL('https://user:pass@example.com:8080/path/page?q=node&n=2#sec')

u.protocol   // 'https:'
u.hostname   // 'example.com'
u.port       // '8080'
u.pathname   // '/path/page'
u.search     // '?q=node&n=2'
u.hash       // '#sec'
u.username   // 'user'

Property

Holds

href

The full URL string (also what toString() returns)

origin

protocol + host — e.g. https://example.com:8080

protocol

Scheme with trailing colon — https:

host / hostname

With port / without port

pathname

The path, percent-decoded for display

search / searchParams

Raw query string / parsed URLSearchParams

hash

The #fragment

Parsing the query string

url.searchParams is a live URLSearchParams object — iterate it, read, add, and delete params, with encoding handled automatically:

JS
const u = new URL('https://api.example.com/search?q=node+js&page=2&tag=a&tag=b')

u.searchParams.get('q')        // 'node js'   (decoded)
u.searchParams.get('page')     // '2'
u.searchParams.getAll('tag')   // ['a', 'b']  (repeated keys)
u.searchParams.has('page')     // true

u.searchParams.set('page', '3')
u.searchParams.append('tag', 'c')
console.log(u.href)            // ...&page=3&tag=a&tag=b&tag=c
URLSearchParams handles encoding for you
Never build a query string by concatenating — special characters like spaces, `&`, and `=` must be percent-encoded or they corrupt the URL. `searchParams.set('q', 'a&b=c')` encodes the value correctly; manual string-building does not. You can also construct one standalone: `new URLSearchParams({ q: 'node', page: 2 }).toString()`.
Resolving relative URLs

Pass a base as the second argument and URL resolves relative references exactly like a browser following a link:

JS
new URL('/about', 'https://example.com/blog/').href
// → 'https://example.com/about'   (absolute path replaces)

new URL('../faq', 'https://example.com/blog/posts/').href
// → 'https://example.com/blog/faq'   (relative climbs)

new URL('page.html', 'https://example.com/blog/').href
// → 'https://example.com/blog/page.html'
`new URL(relative)` without a base throws
A relative string alone — `new URL('/path')` — throws `ERR_INVALID_URL`, because a URL is only complete with a scheme and host. You must supply the base: `new URL('/path', 'https://example.com')`. This catches bugs early, but surprises people coming from the old, lenient `url.parse`.
Converting between file paths and URLs

ESM gives you import.meta.url as a file:// URL, not a path. url provides the conversions — essential for the __dirname reconstruction pattern:

JS
import { fileURLToPath, pathToFileURL } from 'node:url'
import { dirname } from 'node:path'

const __filename = fileURLToPath(import.meta.url)   // → '/home/app/index.js'
const __dirname = dirname(__filename)               // → '/home/app'

pathToFileURL('/home/app/data.json').href           // 'file:///home/app/data.json'
Don't slice `file://` URLs by hand
Stripping `file://` with `.replace()` or `.slice(7)` breaks on Windows (drive letters, leading slash) and on paths with spaces (percent-encoded as `%20`). `fileURLToPath` handles every platform correctly. This pairs with [The Module Wrapper Function](/nodejs/module-wrapper).
The legacy url.parse — avoid it
`url.parse()` is legacy
The old API — `url.parse()`, `url.format()`, `url.resolve()` — predates the WHATWG standard. It is lenient in unsafe ways (it has been the source of SSRF and parsing-mismatch vulnerabilities) and is now considered legacy. Use the `URL` class for all new code; only touch `url.parse` when maintaining old code that depends on its exact quirks.
Next
The dedicated tool for query-string encoding and decoding: [The querystring Module](/nodejs/querystring-module).