Introduction
The @aura-stack/router package is a modern, TypeScript-first router and endpoint definition library for TypeScript backends, supporting runtimes like Next.js, Nuxt, SvelteKit, and more.
It allows building fully typed APIs with declarative endpoints, automatic parameter inference, and first-class middleware support—return native Response objects for seamless compatibility with the Fetch API and modern web standards.
The package is built entirely in TypeScript, providing strong type safety and type inference for an enhanced coding experience.
Contents
This quick start guide covers the basics of creating endpoint definitions and setting up a router.
Getting Started
This guide walks through installation, setup, and the fundamental building blocks needed to create type-safe endpoints and routers in a TypeScript project.
Installation
Install the package and its peer dependency:
npm install @aura-stack/router zodzod is an optional peer dependency used for schema validation via createEndpoint and createEndpointConfig. It should be
installed if schema-based validation is required.
Endpoints
Endpoints are the foundation of the API. Each endpoint maps an HTTP method and route to a handler function.
Creating Endpoints
The createEndpoint function defines an endpoint. It requires three arguments:
HTTPMethod: The HTTP method for the endpoint.Route: The route pattern.Route Handler: The function that executes when the route is matched.
import { createEndpoint } from "@aura-stack/router"
const getUsers = createEndpoint("GET", "/users", async (ctx) => {
return Response.json({ users: [] })
})
const getUser = createEndpoint("GET", "/users/:userId", async (ctx) => {
const { userId } = ctx.params
return Response.json({ id: userId, name: "John" })
})Router
Routers group multiple endpoints and generate type-safe HTTP handlers for the runtime.
Creating a Router
The createRouter function combines endpoint definitions:
import { createRouter } from "@aura-stack/router"
import { getUser, getUsers } from "@/api/users.ts"
export const router = createRouter([getUser, getUsers])Router Configuration
Base Path
A prefix can be added to all routes in the router using basePath:
import { createRouter } from "@aura-stack/router"
import { getUser, getUsers } from "@/api/users.ts"
export const router = createRouter([getUser, getUsers], {
basePath: "/api/v1",
})Global Middlewares
The middlewares option registers logic that runs before every endpoint:
import { createRouter } from "@aura-stack/router"
import { getUser, getUsers } from "@/api/users.ts"
export const router = createRouter([getUser, getUsers], {
middlewares: [
(ctx) => {
console.log(`[debug]: ${ctx.request.url}`)
return ctx
},
],
})Catching Errors
The onError option allows catching and customizing unexpected errors:
- Internal router errors.
- Handler exceptions.
- Middleware errors.
import { createRouter } from "@aura-stack/router"
import { getUser, getUsers } from "@/api/users.ts"
export const router = createRouter([getUser, getUsers], {
onError: (error, request) => {
return Response.json({ message: "Unexpected Error" })
},
})HTTP Handlers
Once the router is defined, the generated handlers can be exported for use in web standard Response and Request web APIs.
The HTTP Handlers export the methods based on the methods defined in the endpoints passed to the router.
import { router } from "@/index.ts"
export const { GET } = routerClient API
A client API is provided to offer type-safe access to the endpoints defined via the createRouter function.
import { createClient } from "@aura-stack/router/client"
import { router } from "@/router.ts"
export const client = createClient<typeof router>({
baseURL: "http://localhost:3000",
})
await client.get("/users/:userId", {
params: {
userId: 1,
},
})