Type-Safe File-Based REST API Router
Define schemas once.
Let types cascade everywhere.
File-based routing for TypeScript REST APIs. Compose scoped directory middleware with full type inference, enforce compile-time return contracts, and eliminate type assertions forever.
import { json } from '@taserjs/router/reply'import { z } from 'zod'import { t } from '@taserjs/router'const GET = t.get('/dashboard/users') .query(z.object({ page: z.coerce.number().default(1), limit: z.coerce.number().default(10), }))export type RouteContext = typeof GET.$Infer.Contextexport default GET.handler(async (ctx) => { const sub = ctx.state.jwtPayload.sub const { page, limit } = ctx.query const users = await ctx.db.getUsers(page, limit) return json({ sub, users })})The Problem & Solution
Why traditional Node.js routing breaks at scale
Traditional routers force trade-offs between clean folder structures and real type safety. Taser eliminates the type assertion trap and guarantees runtime correctness from middleware to client.
// Middleware attaches data to reqapp.use((req, res, next) => { req.user = getUser(req); // untyped assignment next();});// Downstream handler has NO type inferenceapp.post("/private", validateBody(schema), (req, res) => { const user = req.user as User; // ⚠️ manual typecast const body = req.body as PostBody; // ⚠️ manual typecast const query = req.query as Query; // ⚠️ manual typecast res.send({ ok: true });});// Middleware validates and passes state to next()export default t.layout("/admin/*").use(async (ctx, next) => { const token = ctx.headers.get("authorization"); const user = await verifyUser(token); if (!user) throw new Error("Unauthorized"); return next({ user }); // Merges into ctx.state});// Handler receives fully-inferred ctx automaticallyconst POST = t.post("/admin/reports").body(ReportInputSchema);export default POST.handler(async (ctx) => { const user = ctx.state.user; // ✓ Inferred User from next({ user }) const body = ctx.body; // ✓ Inferred ReportInput return json({ created: true, by: user.id });});Mental Model
Inspired by TanStack Router. Engineered for REST APIs.
TanStack Router revolutionized client routing with file-system layouts and type inference. Taser brings that same intuition to backend HTTP servers: HTTP verb files for handlers, non-verb files for cascading directory middleware.
How the mental model translates to the backend
In Taser Router, files are treated differently depending on their suffix:
Endpoints are segregated by method suffixes: .get.ts, .post.ts, .put.ts, .delete.ts, .patch.ts, and all standard HTTP verbs.
Files without a verb (e.g. $.ts, posts.ts, _auth.ts) act as scoped middleware. They run before child handlers and cascade typed context down the folder tree.
Quick Start
Scaffold your stack in seconds
Interactive CLI with batteries included: pick your framework, Nitro preset, database ORM, Standard Schema validator, and logger.
Configure Your Stack
Run this command to bypass interactive prompts and generate your project instantly in CI or your terminal.
Integrations
Framework Agnostic. Runtime Universal.
Build standalone APIs with Vite and Nitro, embed inside Next.js or TanStack Start, or layer onto Express, Fastify, and Web Standard hosts without rewriting a single handler.
Vite Plugin
Virtual route modules, ambient types, and instant HMR.
TanStack Start
Fullstack React apps with TanStack Router loaders & Query.
Next.js
Embed inside App Router with @taserjs/router-plugin/next.
Nitro Module
Universal server engine for edge, serverless, and cloud.
Standalone API
High-throughput, zero-host API built on web standards.
Web Standard Hosts
Pass-through for Hono, Elysia, HatTip, and Web Fetch.
Express
Layer file routing onto existing Express servers.
Fastify
Coexist with Fastify plugins and lifecycle hooks.
Deployment Presets
Cloudflare Workers, Vercel, Node, Docker, Bun, and AWS Lambda.
Validation
Standard Schema First
Zero vendor lock-in. Validate params, headers, query, and payload schemas with any library conforming to the Standard Schema spec.
Roadmap
What the future looks like
We're actively building the next generation of type-safe backend tooling. Here is what is on our horizon.
OpenAPI Specification Generation
Auto-generate OpenAPI 3.1 YAML and JSON endpoints directly from your file routes, Standard Schema definitions, and return contracts. Zero manual Swagger spec writing.
ESLint Plugin for Router Rules
Dedicated @taserjs/eslint-plugin to enforce HTTP verb suffixes (.get.ts, .post.ts), catch invalid param patterns, and validate route exports right in your editor.
WebSockets & Server-Sent Events
Realtime streaming routes (.ws.ts, .sse.ts) with typed event schemas, connection lifecycle hooks, and bi-directional type safety for live updates.
Distributed Rate Limiting & Observability
Distributed Redis sliding-window rate limiting, OpenTelemetry distributed tracing spans, Prometheus metrics exporters, and automated ETag cache middleware.
Open Source & Independent
Backed by the community. Built for everyone.
Taser is 100% open source. Sponsoring funds continuous performance optimizations, runtime adapter development, codegen tooling, and long-term maintenance.
Sponsor Taser Development
Support sustainable open source tooling. Contributions directly support new runtime adapters, compiler features, instant watch-mode codegen, and Standard Schema integrations.
Get Started
Ready to ship type-safe REST APIs?
Explore the documentation, pick your framework adapter, and build handlers with zero manual route registries and zero type casting.

Kazi Ahmed
CreatorCrafting type-safe developer tools, runtime adapters, and deterministic routing engines for TypeScript.