TS-Rex is a zero-dependency TypeScript library that lets you construct complex regular expressions through a chainable API and automatically infers the exact shape of named capturing groups at compile time. Instead of writing opaque regex strings and manually casting match results, you chain human-readable methods — and TypeScript knows the type of every capture before you run a single line. The library was built to eliminate three classes of bugs that plague nativeDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/fajarnugraha37/ts-rex/llms.txt
Use this file to discover all available pages before exploring further.
RegExp usage: silent type mismatches on named captures, lastIndex mutation bugs introduced by the global flag, and malformed patterns caused by unescaped special characters. TS-Rex solves all three through its architecture, not through runtime checks.
Key features
Static type inference
Named captures are inferred directly from your builder chain at compile time. No type assertions, no
as string, no surprises.Stateless execution
Every
.exec() call creates a fresh RegExp instance, making global-flag iteration safe and free of lastIndex bugs.Automatic escaping
.literal() and .anyOf() auto-escape special characters. You cannot accidentally inject a malformed pattern through these methods.Immutable builder
Every method call returns a new
RegexBuilder instance. You can safely branch a base pattern into multiple variations without side effects.Deep optionality
Quantifiers like
.optional() and .zeroOrMore() automatically mark inner capture types as string | undefined in the result.Zero dependencies
Built entirely on standard TypeScript and native
RegExp. Nothing extra is installed at runtime.Core entities
To use TS-Rex effectively, you work with four objects that form a pipeline from pattern definition to typed match result.rx() is the factory function that initializes a fresh, empty builder. Every pattern starts here.
RegexBuilder is the immutable builder class. It exposes dozens of chainable, strictly-typed methods — .literal(), .digit(), .capture(), .optional(), .or(), and more. Each method appends an AST node internally and returns a new instance, carrying accumulated type state forward in its generic parameters.
CompiledRegex is the object returned by calling .compile() on a finished builder. It exposes:
pattern— the raw string representation of the compiled regexnative— the native JavaScriptRegExpinstance for inspection and interopexec(string)— the type-safe extractor that returns aMatchResult
MatchResult is the discriminated union returned by .exec(). On failure it is { isMatch: false, match: null }. On success it is { isMatch: true, match: string, ...yourCaptures }. When the .global() flag is set, .exec() returns an IterableIterator of successful matches instead.
The
MatchResult discriminant lets TypeScript narrow the type automatically inside an if (result.isMatch) block, giving you direct access to all capture properties without extra assertions.Architecture pillars
TS-Rex is built on four architectural decisions that work together to deliver both safety and zero runtime cost. AST generation. Instead of concatenating strings that can silently become malformed, every chained method appends a typed AST node to an internal array. The pattern string is only assembled once, when you call.compile().
Immutability. Each method call creates and returns a completely new RegexBuilder instance. This means you can save a base pattern into a variable and extend it multiple times without unintended side effects.
Phantom type state. As you chain methods like .capture(), .optional(), or .or(), TypeScript infers and records the resulting group names and their optionality in the builder’s generic parameters. This type tracking happens entirely at compile time, with zero runtime memory overhead.
Runtime compilation. Calling .compile() collapses the AST into a native JavaScript RegExp instance, binds the execution-context flags, and returns a strictly typed CompiledRegex wrapper with stateless .exec() semantics.
Auto-escaping and safety
TS-Rex enforces automatic escaping on all character inputs. If you call.literal('http://'), the library escapes the special characters for you. If you call .anyOf('a-z'), the result is [a\-z] — matching the literal characters “a”, ”-”, and “z” — not the range [a-z].
To compose character ranges safely, use the type-safe builder methods: