unstale

npm / rou3

rou3

What changed in rou3 0.10 to 0.12, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-20.

34 breaking1 security2 deprecations1 new APIs and options1 performance1 behavior and defaults7 fixes and other

See which of these apply to your code, ranked, in your agent:

npx @unstale/cli init

@unstale/cli on npm

rou3 0.1223 changes

Breaking changes 16

  • Literal pattern text is percent-encoded once when a route is added; lookup paths are neither decoded nor encoded.

    0.12.0release notes

  • Dot segments, including %2e forms, are resolved when routes are added and removed; lookup paths are unchanged unless normalize: true.

    0.12.0release notes

  • The wildcard is now a greedy catch-all that spans segments, so trailing * rules apply at every depth.

    0.12.0release notes

  • A written (.*) is now a greedy catch-all like *; :name(.*) is keyed by the name, and both match across segments.

    0.12.0release notes

  • A bare ** is now an unnamed capture keyed by its numbered position; a zero-segment match omits the key, and params._ is deprecated.

    0.12.0release notes

  • An optional parameter following a capture in the same segment is matched in place, while the preceding capture is greedy.

    0.12.0release notes

  • A regex group after a {…} group ending in a parameter is now an unnamed capture next to the parameter, rather than that parameter's constraint.

    0.12.0release notes

  • A pattern starting with a {/…} group is now absolute and no longer receives an extra / in front.

    0.12.0release notes

  • /a/* and /a/** now compare as equal; named catch-all comparisons also have updated equality and subset results.

    0.12.0release notes

  • Named catch-alls :name+, :name* and **:name no longer accept empty segments; affected paths fall through to a less specific route or no match.

    0.12.0release notes

  • It reads an unnamed catch-all back as ** while still accepting old _ groups, and throws for literals or patterns that routes cannot represent.

    0.12.0release notes

  • A route can contain only one catch-all among *, **, :x+, :x*, (.*) or :x(.*); routes with more than one throw.

    0.12.0release notes

  • Raw tabs, LF and CR in patterns now throw; -- and && in a constraint character class also throw.

    0.12.0release notes

  • A * route node is keyed as /**, and parameter segments use numbered keys such as :_0 and :_1.

    0.12.0release notes

  • Generated regexes use percent-encoded literal text, name ** groups _0, _1, …, and use URLPattern-style named catch-all expressions.

    0.12.0release notes

  • On engines without duplicate named groups, patterns requiring an uninlinable group around a trailing * now throw.

    0.12.0release notes

Security 1

  • Generated regexes for parameters sharing a segment no longer backtrack polynomially, closing the stated ReDoS class.

    0.12.0release notes

Deprecations 1

  • The _ parameter key for a bare ** capture is deprecated; read params["0"] ?? "" instead or name the capture.

    0.12.0release notes

Performance 1

  • Segments with several parameters now match in linear time in findRoute and compiled matchers.

    0.12.0release notes

Behavior and default changes 1

  • Constrained and literal in-segment parameters now rank above plain ones on the same node, regardless of registration order.

    0.12.0release notes

Fixes and other changes 3

  • Each addRoute call is listed once; duplicate variants are replaced by the variant findRoute picks.

    0.12.0release notes

  • Trailing whole-segment catch-alls are typed string | undefined; **<text> is one key, and the ** key has a deprecated _?: string alternative.

    0.12.0release notes

  • With normalization enabled, a trailing . or .. keeps its trailing slash, matching WHATWG URL behavior.

    0.12.0release notes

rou3 0.1117 changes

Breaking changes 12

  • Generated route data now passes through JSON.stringify, producing valid code for JSON-serializable data and throwing a rou3 error for functions, symbols, or bigints.

    0.11.0release notes

  • Method-agnostic routes are always considered alongside method routes; the more specific route wins, with method routes winning ties. findAllRoutes and compiled matchAll return both.

    0.11.0release notes

  • The package now declares Node.js >=20.19.0 as its engine requirement.

    0.11.0release notes

  • Hand-written regexes must be anchored, and regexes with u or v flags are rejected because they cannot be represented as whole-path routes or equivalent constraints.

    0.11.0release notes

  • Required params no longer match empty segments; use *, **, :name*, or a constraint that allows empty when empty values are needed.

    0.11.0release notes

  • Falsy route data such as 0, false, and an empty string is returned as-is instead of null; missing data remains null.

    0.11.0release notes

  • Regex constraints now throw for anchors, look-arounds, backreferences, and capturing groups because constraint and whole-path matching otherwise disagree.

    0.11.0release notes

  • Outside regex constraints, any \x means a literal x; \ is a literal backslash, while \/ and a trailing \ throw.

    0.11.0release notes

  • When a segment has several params, the first now matches as little as possible, which can change how values are split.

    0.11.0release notes

  • A ? on a param that does not start its segment makes only that param optional; use a group to make the whole segment optional.

    0.11.0release notes

  • Param names now follow [A-Za-z_]\w*; -, {, and } end a name. InferRouteParams reads names the same way, so runtime params and inferred types may change.

    0.11.0release notes

  • addRoute and routeToRegExp now throw rou3 errors for syntax that previously had surprising or unclear meanings, including invalid modifiers, names, duplicate params, and malformed groups.

    0.11.0release notes

Deprecations 1

  • RouterCompilerOptions is deprecated in favor of CompileRouterToStringOptions and CompileRouterOptions.

    0.11.0release notes

New APIs and options 1

  • The compiler now accepts an options object with functionName, matchAll, and serialize; the old positional form still works but is deprecated.

    0.11.0release notes

Fixes and other changes 3

  • Calling compileRouter with matchAll: true is now typed as returning an array.

    0.11.0release notes

  • Each call returns fresh match objects, so mutating one result no longer affects later lookups.

    0.11.0release notes

  • Each call returns a fresh { data, params } object, including static matches and params: false results, so mutating one result no longer affects later lookups.

    0.11.0release notes

rou3 0.107 changes

Breaking changes 6

  • Wildcards can have following segments, which are matched from the end of the path; only one ** is allowed, and routes with following segments affect match ranking.

    0.10.0release notes

  • Lookup ignores at most one trailing slash; repeated trailing slashes no longer match, and a route with an empty parameter can match /users//.

    0.10.0release notes

  • With normalize: true, path normalization drops .. segments that would go above the root.

    0.10.0release notes

  • Removing a route removes only the given pattern, rather than every route on the same node and method.

    0.10.0release notes

  • Generated regexes now match exactly the paths findRoute matches, retain segments after **, and may have different text; some routes no longer use look-behind.

    0.10.0release notes

  • Duplicate param names now produce a rou3: error instead of a raw SyntaxError; optional groups followed by more route content no longer emit duplicate group names on Node 22.

    0.10.0release notes

Fixes and other changes 1

  • Optional params and a trailing bare * can be string | undefined; inferred param names now omit constraints and modifiers.

    0.10.0release notes