Express style path to RegExp utility for URL routing and parameter extraction
npx @tessl/cli install tessl/npm-path-to-regexp@8.3.0Path-to-RegExp is a comprehensive TypeScript library that converts Express-style path strings (like /user/:name) into regular expressions for URL matching and parameter extraction. It provides a complete API for path parsing, matching, compilation, and transformation with full TypeScript support.
npm install path-to-regexp// Main functions
import {
match,
pathToRegexp,
compile,
parse,
stringify
} from "path-to-regexp";
// Classes and errors
import { TokenData, PathError } from "path-to-regexp";
// Types (import as needed)
import type {
MatchFunction,
PathFunction,
MatchResult,
Match,
Key,
Keys,
Token,
Text,
Parameter,
Wildcard,
Group,
Encode,
Decode,
Path,
ParamData,
ParseOptions,
MatchOptions,
CompileOptions,
PathToRegexpOptions
} from "path-to-regexp";For CommonJS:
const {
match,
pathToRegexp,
compile,
parse,
stringify
} = require("path-to-regexp");import { match, compile, parse } from "path-to-regexp";
// Create a match function for URL testing
const matchUser = match("/users/:id");
const result = matchUser("/users/123");
// Result: { path: '/users/123', params: { id: '123' } }
// Create a path generator function
const generateUserPath = compile("/users/:id");
const userUrl = generateUserPath({ id: "456" });
// Result: "/users/456"
// Parse a path into tokens
const tokens = parse("/users/:id/posts/:postId");
// Result: TokenData with parsed parameter and text tokensPath-to-RegExp is built around several key components:
Convert path strings into structured token data for analysis and processing.
/**
* Parse a path string into tokenized data structure
* @param str - Path string to parse (e.g., "/users/:id")
* @param options - Parsing configuration (default: {})
* @returns TokenData instance containing parsed tokens
*/
function parse(str: string, options: ParseOptions = {}): TokenData;
interface ParseOptions {
/** Function for encoding input strings */
encodePath?: Encode;
}
class TokenData {
constructor(
public readonly tokens: Token[],
public readonly originalPath?: string
);
}Usage Examples:
import { parse } from "path-to-regexp";
// Parse a simple path with parameters
const simpleTokens = parse("/users/:id");
// Parse a path with optional segments
const optionalTokens = parse("/users{/:id}/posts");
// Parse a path with wildcards
const wildcardTokens = parse("/files/*path");
// Parse with custom encoding
const encodedTokens = parse("/files/:name", {
encodePath: (str) => encodeURIComponent(str)
});Create functions that test strings against path patterns and extract parameters.
/**
* Transform a path into a match function for testing strings
* @param path - Path string, TokenData object, or array of paths
* @param options - Matching and parsing configuration (default: {})
* @returns Function that matches input strings and extracts parameters
*/
function match<P extends ParamData>(
path: Path | Path[],
options: MatchOptions & ParseOptions = {}
): MatchFunction<P>;
interface MatchOptions extends PathToRegexpOptions {
/** Function for decoding strings for params, or false to disable (default: decodeURIComponent) */
decode?: Decode | false;
}
interface PathToRegexpOptions {
/** Matches the path completely without trailing characters (default: true) */
end?: boolean;
/** Allows optional trailing delimiter to match (default: true) */
trailing?: boolean;
/** Match will be case sensitive (default: false) */
sensitive?: boolean;
/** The default delimiter for segments (default: '/') */
delimiter?: string;
}
type MatchFunction<P extends ParamData> = (path: string) => Match<P>;
type Match<P extends ParamData> = false | MatchResult<P>;
interface MatchResult<P extends ParamData> {
path: string;
params: P;
}Usage Examples:
import { match } from "path-to-regexp";
// Basic parameter matching
const matchUser = match("/users/:id");
const userResult = matchUser("/users/123");
// Result: { path: '/users/123', params: { id: '123' } }
// Multiple parameters
const matchPost = match("/users/:userId/posts/:postId");
const postResult = matchPost("/users/123/posts/456");
// Result: { path: '/users/123/posts/456', params: { userId: '123', postId: '456' } }
// Wildcard matching
const matchFiles = match("/files/*path");
const fileResult = matchFiles("/files/documents/report.pdf");
// Result: { path: '/files/documents/report.pdf', params: { path: ['documents', 'report.pdf'] } }
// Optional segments
const matchOptional = match("/users{/:id}/profile");
const optResult1 = matchOptional("/users/profile");
// Result: { path: '/users/profile', params: {} }
const optResult2 = matchOptional("/users/123/profile");
// Result: { path: '/users/123/profile', params: { id: '123' } }
// Case-sensitive matching
const matchCase = match("/Users/:id", { sensitive: true });
const caseResult = matchCase("/users/123"); // false (case mismatch)
// Custom decoding
const matchDecoded = match("/files/:name", {
decode: (value) => decodeURIComponent(value)
});Create template functions that generate URLs from parameter data.
/**
* Compile a path into a template function for reverse path generation
* @param path - Path string or TokenData object
* @param options - Compilation and parsing configuration (default: {})
* @returns Function that generates paths from parameter data
*/
function compile<P extends ParamData>(
path: Path,
options: CompileOptions & ParseOptions = {}
): PathFunction<P>;
interface CompileOptions {
/** Function for encoding input strings for output, or false to disable (default: encodeURIComponent) */
encode?: Encode | false;
/** The default delimiter for segments (default: '/') */
delimiter?: string;
}
type PathFunction<P extends ParamData> = (data?: P) => string;Usage Examples:
import { compile } from "path-to-regexp";
// Basic path generation
const generateUser = compile("/users/:id");
const userPath = generateUser({ id: "123" });
// Result: "/users/123"
// Multiple parameters
const generatePost = compile("/users/:userId/posts/:postId");
const postPath = generatePost({ userId: "123", postId: "456" });
// Result: "/users/123/posts/456"
// Wildcard paths
const generateFile = compile("/files/*path");
const filePath = generateFile({ path: ["documents", "report.pdf"] });
// Result: "/files/documents/report.pdf"
// Optional segments
const generateOptional = compile("/users{/:id}/profile");
const optPath1 = generateOptional({}); // "/users/profile"
const optPath2 = generateOptional({ id: "123" }); // "/users/123/profile"
// Custom encoding
const generateEncoded = compile("/files/:name", {
encode: (value) => encodeURIComponent(value).replace(/%20/g, '+')
});
const encodedPath = generateEncoded({ name: "my file.txt" });
// Result: "/files/my+file.txt"Generate regular expressions and capture keys for direct pattern matching.
/**
* Convert path to RegExp and extract capture keys
* @param path - Path string, TokenData object, or array of paths
* @param options - Regex generation and parsing configuration (default: {})
* @returns Object with regexp (RegExp) and keys (Keys array)
*/
function pathToRegexp(
path: Path | Path[],
options: PathToRegexpOptions & ParseOptions = {}
): { regexp: RegExp; keys: Keys };
type Keys = Array<Key>;
type Key = Parameter | Wildcard;Usage Examples:
import { pathToRegexp } from "path-to-regexp";
// Generate RegExp for direct matching
const { regexp, keys } = pathToRegexp("/users/:id");
const match = regexp.exec("/users/123");
// match: ["/users/123", "123"]
// keys: [{ type: "param", name: "id" }]
// Multiple paths (alternative routes)
const { regexp: multiRegexp, keys: multiKeys } = pathToRegexp([
"/users/:id",
"/user/:id"
]);
// Case-sensitive RegExp
const { regexp: sensitiveRegexp } = pathToRegexp("/Users/:id", {
sensitive: true
});
// Non-ending RegExp (allows additional characters)
const { regexp: partialRegexp } = pathToRegexp("/api/:version", {
end: false
});Convert tokenized path data back to path strings.
/**
* Convert tokenized path data back to path string
* @param data - TokenData instance to stringify
* @returns Path string representation
*/
function stringify(data: TokenData): string;Usage Examples:
import { parse, stringify } from "path-to-regexp";
// Parse and stringify round-trip
const tokens = parse("/users/:id/posts/:postId");
const pathString = stringify(tokens);
// Result: "/users/:id/posts/:postId"
// Stringify complex paths
const complexTokens = parse("/users{/:id}/posts/*path");
const complexString = stringify(complexTokens);
// Result: "/users{/:id}/posts/*path"type Encode = (value: string) => string;
type Decode = (value: string) => string;
type Path = string | TokenData;
type ParamData = Partial<Record<string, string | string[]>>;type Token = Text | Parameter | Wildcard | Group;
interface Text {
type: "text";
value: string;
}
interface Parameter {
type: "param";
name: string;
}
interface Wildcard {
type: "wildcard";
name: string;
}
interface Group {
type: "group";
tokens: Token[];
}class PathError extends TypeError {
constructor(
message: string,
public readonly originalPath: string | undefined
);
}The PathError class is thrown when there are syntax errors in path strings, such as:
/users{/:id)/users/:)/users/:123)Usage Examples:
import { parse, match, compile, PathError } from "path-to-regexp";
// Parsing errors
try {
const tokens = parse("/users{/:id"); // Unterminated group
} catch (error) {
if (error instanceof PathError) {
console.log(error.message); // Includes helpful error info
console.log(error.originalPath); // "/users{/:id"
}
}
// Parameter validation in compile
try {
const generatePath = compile("/users/:id");
const path = generatePath({}); // Missing required parameter
} catch (error) {
console.log(error.message); // "Missing parameters: id"
}
// Type errors in wildcard parameters
try {
const generateWildcard = compile("/files/*path");
const path = generateWildcard({ path: "not-an-array" }); // Invalid type
} catch (error) {
console.log(error.message); // 'Expected "path" to be a non-empty array'
}Match against multiple possible path patterns:
import { match } from "path-to-regexp";
const matchMultiple = match([
"/users/:id",
"/user/:id",
"/u/:id"
]);
const result = matchMultiple("/u/123");
// Result: { path: '/u/123', params: { id: '123' } }import { match, compile } from "path-to-regexp";
// Custom decoding for match
const matchCustom = match("/files/:name", {
decode: (value) => {
// Custom decoding logic
return decodeURIComponent(value).replace(/\+/g, ' ');
}
});
// Custom encoding for compile
const compileCustom = compile("/files/:name", {
encode: (value) => {
// Custom encoding logic
return encodeURIComponent(value).replace(/%20/g, '+');
}
});import { match, compile, type MatchResult } from "path-to-regexp";
// Type-safe parameter interfaces
interface UserParams {
id: string;
}
interface PostParams {
userId: string;
postId: string;
}
const matchUser = match<UserParams>("/users/:id");
const matchPost = match<PostParams>("/users/:userId/posts/:postId");
const compileUser = compile<UserParams>("/users/:id");
const compilePost = compile<PostParams>("/users/:userId/posts/:postId");
// Type-safe usage
const userResult = matchUser("/users/123"); // MatchResult<UserParams> | false
if (userResult) {
console.log(userResult.params.id); // TypeScript knows this is string
}