Skip to content

xil

A typed router, a per-request context, unified errors, and optional modules for auth, uploads, rate limiting, and OpenAPI — all fully typed, none of it hidden behind magic.
import { createApp, NotFound, Router } from "@architectine/xil";
import { z } from "zod";
const orders = new Router("/orders");
orders.get("/:id").handle((ctx) => {
const order = db.orders.get(ctx.params.id); // ctx.params.id: string, inferred from ":id"
if (!order) throw new NotFound(`Order ${ctx.params.id} does not exist`);
return order; // -> 200 JSON
});
orders
.post("/")
.body(z.object({ total: z.number().positive() }))
.handle((ctx) => db.orders.create({ total: ctx.body.total })); // ctx.body.total: number, validated
// -> 201 JSON
const app = createApp();
app.mount(orders);
await app.listen(3000);

Every thrown error and every validation failure renders through the same shape:

{ "code": "VALIDATION", "message": "Invalid body", "details": { "in": "body", "issues": [] }, "requestId": "" }

Continue with Your first app for the full walkthrough.