Repository navigation
Brainstorm: url.parse() -> new url #92
Copy link
Copy link
Labels
Description
Description
This codemod should migrate url.parse() to new url.
- It's should handle both
require()function andimportstatement. - It's should support both
urlnode:urlspecifier. - If the url module isn't use elsewhere we should remove the importation.
authproperty should be replaced by${modernURL.username}:${modernURL.password}pathproperty should be replaced by${modernURL.pathname}${modernURL.search}hostnameproperty should be replaced bymodernURL.hostname.replace(/^\[|\]$/, '')to remove the brackets for IPv6 addresses.
Example
In these example we use
legacyURLto refer to the object returned byurl.parse(), andmodernURLto refer to the object created withnew URL().
In the codemod implementation, it' will be the name of the variable that is used by the user so it's shouldn't be changed.
Case 1: Basic usage
Before:
const url = require('node:url');
const legacyURL = url.parse('https://example.com/path?query=string#hash');After:
const modernURL = new URL('https://example.com/path?query=string#hash');Case 2: auth property
Before:
const url = require('node:url');
const legacyURL = url.parse('https://user:pass@example.com/path');
const { auth } = legacyURL;
const urlAuth = legacyURL.auth;After:
const modernURL = new URL('https://user:pass@example.com/path');
const auth = `${modernURL.username}:${modernURL.password}`;
const urlAuth = `${modernURL.username}:${modernURL.password}`;Case 3: path property
Before:
const url = require('node:url');
const legacyURL = url.parse('https://example.com/path?query=string#hash');
const { path } = legacyURL;
const urlPath = legacyURL.path;After:
const modernURL = new URL('https://example.com/path?query=string#hash');
const path = `$(modernURL.pathname}${modernURL.search}`;
const urlPath = `${modernURL.pathname}${modernURL.search}`;Case 4: hostname property with IPv6 address
Before:
const url = require('node:url');
const legacyURL = url.parse('https://[2001:db8::1]/path');
const { hostname } = legacyURL;
const urlHostname = legacyURL.hostname;After:
const modernURL = new URL('https://[2001:db8::1]/path');
const hostname = modernURL.hostname.replace(/^\[|\]$/, '');
const urlHostname = modernURL.hostname.replace(/^\[|\]$/, '');Case 5: cjs url module elsewhere
Before:
const { parse, foo } = require('node:url');
const legacyURL = parse('https://example.com/path?query=string#hash');
foo(); // does something elseAfter:
const { foo } = require('node:url');
const modernURL = new URL('https://example.com/path?query=string#hash');
foo(); // does something elseCase 6: import statement
Before:
import { parse } from 'node:url';
const legacyURL = parse('https://example.com/path?query=string#hash');After:
import { URL } from 'node:url';
const modernURL = new URL('https://example.com/path?query=string#hash');Case 7: import statement with other named exports
Before:
import { parse, foo } from 'node:url';
const legacyURL = parse('https://example.com/path?query=string#hash');
foo(); // does something elseAfter:
import { URL, foo } from 'node:url';
const modernURL = new URL('https://example.com/path?query=string#hash');
foo(); // does something elseREFS
https://nodejs.org/dist/docs/api/url.html
https://url.spec.whatwg.org
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fields✅ Done
Activity
AugustinMauroy commentedon Jun 24, 2025
I had make some research on the topic, here a test suite that compare both and highlights the points that could be blocked
Test Suite
mcollina commentedon Jun 24, 2025
A codemod could handle maybe 80% of the cases - which I think would be plenty.
Maybe we could have a url.parseWithNative that emits the same data structure but with the new behavior.
AugustinMauroy commentedon Jun 24, 2025
I would like to know the 20% so I can figure out how to shape it.
We agree that this idea has nothing to do with codemod; it's just for node-core, right?
alexbit-codemod commentedon Jun 24, 2025
@AugustinMauroy, i used Codemod AI to generate this: https://app.codemod.com/studio?share_id=512f5c98241325a2756d71
maybe you can help me take it to the next level for tricker cases.
btw, there are two tabs in the studio link above:
Query: ast-grep YAML rule, great for pattern detection and simple transformations.
Codemod: ast-grep JS/napi, great for more sophisticated transformations.
ping me if you have follow up questions on this.
styfle commentedon Sep 4, 2025
The biggest difference is that
url.parse()supports relative urls andnew URL()does not.That alone makes the codemod challenging.
styfle commentedon Oct 21, 2025
@AugustinMauroy Per my previous message, this codemod will cause apps to crash at runtime.
I also commented here:
node url to whatwg url) #172 (comment)