URI.js - URL Manipulation Library
URI.js is a robust JavaScript library designed for parsing, manipulating, and constructing URLs (Uniform Resource Locators) and URIs (Uniform Resource Identifiers). Its current stable version is 1.19.11, with development focused on security patching and maintenance rather than new feature additions. The library has historically seen frequent updates to address various parsing vulnerabilities, particularly concerning malformed URLs, which highlights its commitment to secure URI handling. While it provides a comprehensive and fluent API for complex URL transformations, the project explicitly recommends developers leverage native browser APIs like `URL` and `URLSearchParams` for modern web environments, suggesting URI.js is most suitable for legacy projects, environments lacking native URL APIs, or for advanced scenarios such as URI template expansion. It differentiates itself by offering a mutable, chaining API for intricate URL modifications that can be cumbersome with standard string methods or even native APIs for older browser targets.
Common errors
-
ReferenceError: URI is not defined
cause The URI.js library was not correctly imported or required in the current scope.fixFor Node.js, ensure `const URI = require('urijs');` is at the top of your file. For ESM, use `import URI from 'urijs';`. In a browser, ensure the `<script src=".../URI.min.js"></script>` tag is present and loaded before your script. -
Error: Cannot find module 'uri.js' (or 'urijs/src/URITemplate')
cause Incorrect package name used in `require()` or `import` statement, or an optional module path is wrong.fixVerify the package name is `urijs`. For optional modules, ensure the path is correct, e.g., `require('urijs/src/URITemplate')` or `import URITemplate from 'urijs/src/URITemplate';`. -
URL parsing yields unexpected segments (e.g., path, authority, query string appears malformed)
cause Prior to recent security updates (v1.19.3-v1.19.11), URI.js might have parsed certain malformed URLs differently due to vulnerabilities in handling special characters or structures.fixUpgrade to the latest version of `urijs` (1.19.11 or newer). These versions include fixes that align parsing with modern security standards and browser behavior, which might change how previously malformed URLs are interpreted.
Warnings
- deprecated The project explicitly advises that modern browsers (and Node.js v10+) offer native `URL` and `URLSearchParams` APIs that may negate the need for URI.js. Developers should evaluate if native APIs suffice before adopting URI.js for new projects.
- breaking Multiple security fixes between versions 1.19.3 and 1.19.11 address vulnerabilities in `URI.parse()`, `URI.parseQuery()`, and `URI.parseAuthority()` related to handling malformed URLs. These fixes correct behavior for excessive slashes, colons, leading whitespace, CR/LF/TAB characters, scheme case-insensitivity, and backslash normalization. While enhancing security, these corrections may alter parsing results for previously 'accepted' malformed URLs, potentially breaking applications that relied on the prior, insecure parsing logic.
- breaking Version 1.19.7 included a security fix for `URI.parseQuery()` to prevent `__proto__` overwriting, which could lead to prototype pollution. This change might subtly affect how query parameters are parsed if they contained specific key names like `__proto__`.
- gotcha The npm package name for URI.js is `urijs` (all lowercase, no dot), not `uri.js`. Using the incorrect package name in `package.json` or `npm install` commands will result in an error or installation of a different package.
Install
-
npm install urijs -
yarn add urijs -
pnpm add urijs
Imports
- URI
const URI = require('uri.js');import URI from 'urijs';
- URI
const URI = require('urijs'); - URITemplate
import { URITemplate } from 'urijs';import URITemplate from 'urijs/src/URITemplate';
Quickstart
import URI from 'urijs';
const originalUrl = "http://example.org/foo.html?hello=world";
// Create a new URI object
const url = new URI(originalUrl);
// Perform a series of fluent manipulations
const modifiedUrl = url
.username("rodneyrehm") // Add a username
.directory("bar") // Change directory segment
.suffix("xml") // Change file extension
.query({ foo: "bar", hello: ["world", "mars"] }) // Set multiple query parameters
.tld("com"); // Change top-level domain
console.log(`Original URL: ${originalUrl}`);
console.log(`Modified URL: ${modifiedUrl.toString()}`);
// Example of cleaning up query strings
const messyQueryUrl = URI("?&foo=bar&&foo=bar&foo=baz&").normalizeQuery();
console.log(`Cleaned Query: ${messyQueryUrl.toString()}`);
// Example of URI Templates
const expandedUri = URI.expand("/foo/{dir}/{file}", {
dir: "bar",
file: "world.html"
});
console.log(`Expanded URI: ${expandedUri}`);