url-pattern
A tiny, dependency-free library for matching and generating URL-like string patterns without regex.
Repository Health
Technical Analysis
url-pattern is a minimal JavaScript library that turns strings like /api/users/:id into compiled matchers, letting you extract named segments, wildcards, and optional groups from URLs or other delimited strings without writing raw regular expressions by hand. It exposes a single UrlPattern class with two methods — match() to parse a string into a plain object of captured values, and stringify() to do the reverse and build a string from a pattern and a set of values — making it equally useful for routing incoming requests and generating outgoing links.
Under the hood, patterns are parsed once into an abstract syntax tree using a small set of hand-rolled parser combinators, then compiled into a single native RegExp for matching, so repeated calls to .match() are just a regex exec with essentially no runtime parsing overhead. The library ships as compiled CommonJS/AMD/browser-global output built from a single CoffeeScript source file, has zero runtime dependencies, and includes hand-written TypeScript typings, making it a lightweight drop-in for routing, path parsing, or domain/URL matching in both Node.js and browser environments.
What You Get
- Compiled-once regex matching via the
UrlPatternclass for fast repeated.match()calls - Named segments (
:id), wildcards (*), and optional groups ((...)) in a single pattern syntax - Reverse generation of strings from a pattern plus a values object via
.stringify() - Support for building patterns directly from a native RegExp plus an array of capture-group names
- Fully customizable syntax (escape char, segment delimiters, wildcard char, allowed charsets) via an options object
- Ready-to-use CommonJS, AMD, and browser-global builds, plus bundled TypeScript typings
Common Use Cases
- Matching and extracting parameters from request paths in a custom router or middleware
- Generating canonical URLs or links from a route pattern and a data object
- Parsing structured, delimiter-based strings that aren’t standard URLs (e.g.
.user.:userId.task.:taskId) - Validating and destructuring domain/subdomain strings without writing a bespoke regex
Under The Hood
Architecture
The library is a single self-contained file structured in four sequential sections: generic helpers (escapeForRegex, concatMap, keysAndValuesToObject), a small hand-rolled parser-combinator toolkit (P.regex, P.sequence, P.firstChoice, P.many1, explicitly noted in the source as copied from the author’s separate pcom project), a url-pattern-specific parser built from those combinators (newParser, producing wildcard/optional/named/static token parsers), and finally the UrlPattern constructor and prototype, which parses a pattern string into an AST once at construction time and compiles it into a single cached native RegExp; .match() is then just a regex exec, while .stringify() walks the cached AST directly against supplied values. It’s a clean, well-commented monolith rather than a layered system — there’s no separation to break because there’s essentially one module.
Tech Stack
Source is written in CoffeeScript (src/url-pattern.coffee) and compiled via coffee --bare --compile into the shipped lib/url-pattern.js UMD build (CommonJS/AMD/browser-global); runtime dependencies are zero. Dev tooling is coffee-script/coffeeify for the build, tape plus coffeetape for tests, istanbul and codecov.io for coverage reporting, and zuul for cross-browser testing via Sauce Labs — all wired through plain npm scripts rather than a bundler. Hand-written TypeScript typings (index.d.ts) are shipped separately via the typings field for consumers, distinct from the CoffeeScript implementation itself.
Code Quality
An extensive test suite spans multiple CoffeeScript test files covering matching, stringifying, AST parsing, error conditions, and even the literal code examples from the README, all run through tape assertions. Error handling is explicit — the constructor throws typed errors for invalid patterns (whitespace, empty strings, mismatched regex group counts) rather than failing silently. There’s no static typing in the implementation itself (CoffeeScript is dynamically typed) and no linter is configured, though CI was historically wired up via Travis and Sauce Labs across multiple Node versions and browsers — that pipeline is stale given the project’s last commit.
API Design
The public surface is deliberately minimal — one class, two methods (match/stringify) — with a pattern syntax that reads close to a real path rather than a full regex, and the same pattern object supports both directions (string-to-object via match, object-to-string via stringify), keeping route definitions in one place. Getting started requires nothing more than a single constructor call with no configuration, while power users get a fully customizable syntax (escape/segment/wildcard characters) via an options object without touching the core parser combinators. Naming is consistent and the README doubles as executable documentation, validated by its own test file.
Used by 4 apps in this directory
AnythingLLM
Developer Tools · Automation · AI Assistants
The all-in-one AI platform for private document chat, no-code agents, and local LLMs with zero setup friction.
Chaskiq
CRM · Customer Support
Self-hosted live chat, video calls, help center, and marketing automation — a full-stack Intercom alternative you run on your own infrastructure.
Omnivore
Knowledge Management · Bookmarks Archiving · Note Taking
Self-hosted read-it-later platform with highlights, newsletters, PDFs, and seamless Obsidian and Logseq integration.
TinaCMS
CMS
An open-source, Git-backed headless CMS that gives editors a live visual editing UI over Markdown, MDX, JSON, and YAML content while developers keep everything in version control.