Summary
generateRouteTypes() emits a RouteMap of every route in the project, and nothing in the source tree declares or imports the module it augments. The declaration parses, ships, and constrains nothing. Typed route navigation does not exist today despite the file that claims to provide it.
This is the same shape as #1879 (PageMeta.layout declared and never read), one level up — found while fixing that one.
Evidence
packages/router/src/codegen.ts:6-26 writes .stx/route-types.d.ts:
declare module "stx/routes" {
interface RouteMap {
'/about': { }
'/posts/:slug': { slug: string }
}
}stx/routes is not a real module. Grepping the workspace for who declares or imports it:
$ grep -rn "RouteMap" packages/stx/src packages/router/src --include="*.ts" | grep -v codegen.ts
packages/stx/src/dev-server/serve-multi.ts:29:interface RouteMapping { # unrelated name collisionNothing. And the navigation API it is supposed to constrain is plain string — packages/stx/stx.d.ts:127:
declare function navigate(_url: string, _options?: StxNavigateOptions): voidSo navigate('/dashbaord') type-checks, <StxLink to="/dashbaord"> type-checks, and the failure surfaces as a 404 at runtime.
Because declare module "stx/routes" names a specifier that does not resolve, TypeScript treats it as an ambient module declaration rather than an augmentation — which is exactly why it produces no error and no diagnostic about being unused.
Why it matters
Route names are load-bearing strings that no compiler currently checks, and the same generator's sibling output (.stx/routes.ts) is consumed. The typed half is the half that silently does nothing.
Nuxt types navigateTo against generated route names; TanStack Router and Next's typedRoutes both make an unknown route a build error.
Constraint
There are ~87 navigate( and ~115 StxLink references in this repo's own tests and docs alone. Many pass template literals, query strings, hashes or variables. A naive union would reject valid code, so the fix has to catch typos on static string literals without rejecting computed URLs.
Prior art in this repo
#1879 landed a working precedent — packages/stx/src/layout-types.ts + KnownLayouts/LayoutName in head.ts. It augments the real package (@stacksjs/stx), is referenced by a real signature, and degrades to string when the interface is empty so projects without generated types are unaffected. Verified by compiling a real project with tsc, precisely because a string-shaped assertion would have passed for the dangling version too.
Ask
- Make the generated declaration augment the real package and be referenced by a real signature, so it can actually produce an error.
- Type
navigate()and<StxLink to>so a static-literal typo errors while computed URLs still compile. - Degrade to
stringwhen no declaration has been generated. - Test it by compiling a real project, not by asserting on the emitted string — that assertion passes for the dangling version too.
- Either fix or delete
declare module "stx/routes". A declaration that constrains nothing is worse than none.
Related: #1879, #1798, #1849 (same class: typed and never read).