Skip to main content
@ooneex/url wraps the native URL with a friendlier, typed API. It parses a URL into its parts (protocol, subdomain, domain, port, path, queries, fragment), coerces query values to their natural types, and exposes helpers for common parameters like lang, page, limit, and order. A chainable Url class lets you mutate and rebuild URLs, while ReadonlyUrl offers the same read accessors without mutation.

Installation

Add the package with Bun.
bun add @ooneex/url

Usage

Construct a Url from a string (or a native URL) and read its parts. Query values are automatically parsed: "true"/"false" become booleans and numeric strings become numbers.
import { Url } from "@ooneex/url";

const url = new Url("https://app.ooneex.com/articles?page=2&limit=20&active=true#section");

url.getProtocol();  // "https"
url.getSubdomain(); // "app"
url.getDomain();    // "ooneex.com"
url.getHostname();  // "app.ooneex.com"
url.getPath();      // "/articles"
url.getFragment();  // "section"
url.getQueries();   // { page: 2, limit: 20, active: true }
url.getQuery("active"); // true
Typed convenience accessors return sensible defaults when a parameter is missing, which is handy for list/pagination endpoints.
const url = new Url("https://ooneex.com/posts?lang=fr&order=DESC&orderBy=createdAt&q=hello");

url.getLang();    // "fr" (falls back to "en" if not a known locale)
url.getPage();    // 1   (default when absent)
url.getLimit();   // 100 (default when absent)
url.getOrder();   // "DESC" (defaults to "ASC")
url.getOrderBy(); // "createdAt"
url.getSearch();  // "hello" (the `q` param)
The Url class is chainable: every setter returns the instance and rebuilds the underlying URL, so you can read the result with toString().
const url = new Url("https://ooneex.com/")
  .setPath("articles/latest")
  .addQuery("page", 1)
  .addQuery("limit", 20)
  .setFragment("top");

url.toString(); // "https://ooneex.com/articles/latest?page=1&limit=20#top"

url.removeQuery("limit");
url.setQueries({ q: "search", lang: "en" });
url.clearQueries();
When you only need to read a URL and want to prevent mutation, use ReadonlyUrl, which exposes all the getters but none of the setters.
import { ReadonlyUrl } from "@ooneex/url";

const url = new ReadonlyUrl("https://api.ooneex.com:8080/v1/users?limit=50");

url.getPort();    // 8080
url.getBase();    // "https://api.ooneex.com:8080"
url.getOrigin();  // "https://api.ooneex.com:8080"
url.getNative();  // the underlying native URL instance

When to use it

  • You need to read URL query parameters already coerced to their natural types (numbers, booleans) instead of raw strings.
  • You handle list endpoints and want typed accessors with defaults for page, limit, order, orderBy, lang, and search (q).
  • You want to build or modify URLs fluently with a chainable API that handles path normalization, default ports, and query rebuilding for you.
  • You want a read-only view of a URL (ReadonlyUrl) to pass around without risk of mutation.
  • You don’t need it for trivial cases where the native URL and URLSearchParams already cover what you do.