url-pattern

A tiny, dependency-free library for matching and generating URL-like string patterns without regex.

Library
npm
v1.0.3
587stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
33/100Needs Attention
Development Activity0
Maintenance0
Community52
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
68/100Good
Architecture72
Code Quality70
Innovation78
Learning Curve50

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 UrlPattern class 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.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search