ufo
Lightweight, dependency-free URL utilities for parsing, joining, normalizing, and manipulating URLs across Node, browser, and Deno.
Repository Health
Technical Analysis
ufo is a small, dependency-free utility library for working with URLs in JavaScript and TypeScript. It provides a comprehensive set of pure functions for parsing, encoding, joining, normalizing, and comparing URLs, covering edge cases like protocol-relative URLs, repeated query keys, punycode hostnames, and dangerous script protocols that the native URL API handles inconsistently or not at all.
Maintained by the unjs ecosystem (the team behind Nuxt, Nitro, and h3), ufo is used as a foundational primitive across many unjs packages and is downloaded tens of millions of times a week. It ships as a tiny, side-effect-free ESM/CJS dual package with full TypeScript types, making it a common building block for routers, HTTP clients, and static site generators that need consistent, predictable URL handling in Node.js, browsers, and Deno.
What You Get
- Parsing utilities - parseURL, parsePath, parseAuth, parseHost, and parseFilename break a URL string into protocol, auth, host, pathname, search, and hash components without throwing on partial or relative input.
- Encoding/decoding helpers - encode, encodePath, encodeHost, encodeQueryKey/Value, and their decode counterparts handle percent-encoding and punycode consistently across path, query, and hash segments.
- Query string utilities - parseQuery and stringifyQuery convert between query strings and plain objects, correctly handling repeated keys as arrays.
- URL manipulation helpers - joinURL, joinRelativeURL, resolveURL, withQuery, withProtocol, withBase/withoutBase, and slash/fragment helpers (withTrailingSlash, withoutHost, etc.) let you compose and rewrite URLs without manual string surgery.
- Safety checks - isScriptProtocol flags dangerous blob:/data:/javascript:/vbscript: protocols, and hasProtocol/isRelative/isEqual support validating and comparing arbitrary URL-like strings.
Common Use Cases
- Normalizing user-supplied or third-party URLs before storing or rendering them, including query string re-encoding and double-slash cleanup.
- Building routers, middleware, or static-site generators (as used internally by Nuxt, Nitro, and h3) that need to join base paths with relative segments correctly.
- Rewriting or redirecting URLs - swapping protocols, adding/removing trailing slashes, or stripping hosts - without pulling in the full WHATWG URL object.
- Sanitizing links against script-injection protocols (javascript:, data:, vbscript:) in user-generated content pipelines.
Under The Hood
Architecture The package is organized as a flat set of five focused modules (encoding.ts, parse.ts, query.ts, url.ts, utils.ts) re-exported from a single index.ts, each exposing pure, stateless functions that operate on plain strings and a handful of small interfaces (ParsedURL, ParsedPath, ParsedAuth, ParsedHost, QueryObject) defined in parse.ts and query.ts. There is no class hierarchy or dependency injection beyond a deprecated $URL wrapper in url.ts, which itself composes the functional parse/encode/query utilities rather than introducing new state. Data flows one-directionally - a raw string goes in, a parsed or encoded string (or plain object) comes out - with no internal caching or shared global state, consistent with the package’s declared sideEffects: false. This makes any single module (for example, the regex-based parseURL) safely replaceable without rippling through the rest of the codebase.
Tech Stack Written in TypeScript targeting ESNext modules, built with unbuild (a Rollup-based bundler) into dual ESM (.mjs) and CJS (.cjs) outputs with generated .d.ts declarations, and using automd to keep the README’s function reference in sync with JSDoc comments in src. There are zero runtime dependencies; devDependencies cover linting (eslint plus eslint-config-unjs), formatting (prettier), testing (vitest with @vitest/coverage-v8 and compile-time assertions via a dedicated types.test-d.ts), and release automation (changelogen). The project uses pnpm as its package manager and runs CI on GitHub Actions (Node 20), executing lint, build, and a coverage-instrumented vitest run uploaded to Codecov on every push.
Code Quality Tests are extensive, spanning thirteen test files that each target a specific module (parsing, encoding, joining, normalizing, punycode, query strings, trailing slashes, and more), largely written as table-driven cases that enumerate many edge-case inputs per function rather than one-off assertions. Functions favor returning sensible defaults over throwing on malformed input (parseURL, parseHost, and parseAuth all degrade gracefully), naming is consistent and verb-first (parseX/encodeX/decodeX/withX/withoutX), and the entire surface is written in strict TypeScript with exported interfaces giving callers full type safety. ESLint and Prettier enforce style, and the test script chains linting, type-checking, and the vitest suite together in CI.
API Design ufo’s core idea is treating a URL as a set of small composable pure functions rather than a stateful object, which lets it parse malformed, relative, and protocol-relative strings that would throw with the native new URL() constructor. It fills real gaps in the WHATWG URL API with purpose-built helpers like joinRelativeURL, isScriptProtocol, and withBase/withoutBase. Naming stays highly consistent across roughly thirty exports, which keeps the learning curve manageable despite the surface area, and JSDoc comments carry runnable examples that automd re-injects directly into the README, keeping docs and code from drifting apart. It is a pragmatic ergonomics layer over existing URL parsing rules rather than an invention of new URL semantics.
Used by 5 apps in this directory
likec4
Developer Tools · Devops
Define your software architecture as code and get always up-to-date, interactive C4 diagrams generated automatically from a DSL.
RSSHub
Automation · Social Media
Turn any website into an RSS feed — social media, streaming platforms, and niche sites all become subscribable in seconds.
Sink
Bookmarks Archiving · Analytics
Serverless link shortener with real-time analytics, powered by Cloudflare
Unlighthouse
Developer Tools
An open-source CLI that scans your entire website with Google Lighthouse, using smart sampling and a modern dashboard UI to audit every page instead of one URL at a time.
Vikunja
Project Management
Self-hosted task management with natural-language quick-add, multiple views, and a fully documented REST API — your tasks, your infrastructure, zero lock-in.