@stacksjs/router (in stacksjs/stacks at storage/framework/core/router/) is a thin wrapper around @stacksjs/bun-router that adds Stacks-specific glue. With the recent bun-router additions — string action handlers (Actions/Foo), file-based routing, class handlers — most of @stacksjs/router is now a re-export. Only two things remain genuinely missing from bun-router. Filing this to propose absorbing them upstream so @stacksjs/router can be deprecated.
What @stacksjs/router still provides that bun-router doesn't
1. AsyncLocalStorage request context
A runWithRequest() wrapper around route handlers and a request() / getCurrentRequest() accessor that lets any code in the request lifecycle (services, helpers, model hooks) reach the active request without explicit threading.
// User code anywhere in the request lifecycle
import { request } from '@stacksjs/bun-router'
async function logActivity() {
const req = request()
console.log(`${req.method} ${req.url}`)
}Today implemented as ~40 lines using node:async_hooks. The Router itself wires runWithRequest() automatically around handler invocation; users only ever touch request() / getCurrentRequest().
2. Named-route URL generation, Laravel-style
The chainable route.get(...).name('users.show') pattern already exists in the bun-router fluent API — the resolver is what's missing.
route.get('/users/{id}', handler).name('users.show')
url('users.show', { id: 42 }) // → 'https://app.example/users/42'Today implemented as a small Map<name, path> plus a parameter substituter (~30 lines). Path placeholders like {id} get filled from the params object; leftover keys become query string.
Suggested API additions
// 1. Request context — Router wires runWithRequest internally
import { request, getCurrentRequest } from '@stacksjs/bun-router'
// 2. Named-route URLs
import { url } from '@stacksjs/bun-router'
router.get('/users/{id}', handler).name('users.show')
url('users.show', { id: 42 })Why land these in bun-router
- They're general-purpose, not Stacks-specific. Anyone building a Laravel-style app on Bun benefits.
- They're small (~70 LOC combined) and have no new runtime dependencies (
node:async_hooksis built-in). - They unblock a clean deprecation of the wrapper package, removing duplicate exports and the "which
routedo I import?" confusion that's tripped up users on fresh app installs (see stacksjs/stacks#1835).
What stays out (intentionally)
- Routes-registry-as-object loader (
Routes.tsmap → file imports with auto-prefix). bun-router already ships file-based routing; pushing a second routing-config pattern upstream is opinionated and bigger to land. Can stay as a tiny app-side helper. - Action
validationsschema hook — overlaps with bun-router's existing validation paths; tightly coupled to the Stacks Action class. Stays in Stacks. trackQuery— debug-page query tracking. Framework-specific. Stays in Stacks.
Cross-reference
Companion deprecation/removal tracker to be filed in stacksjs/stacks after this lands.