Askr
Server & APIs

Server

Build a context-first HTTP application with explicit routing, middleware, actions, realtime, and probes.

  • @askrjs/server0.0.3

How to use server

Build the HTTP surface from a router and context-first handlers; bind input and return an explicit response helper from the same boundary.

  1. Import the published @askrjs/server entrypoint.
  2. Keep server configuration next to the component, route, or server composition root that owns it.
  3. Handle pending, unavailable, cancellation, and failure states, then verify the production path.
import { createRouter, created } from '@askrjs/server';

export const router = createRouter().post('/projects', async (context) => {
  const input = await context.bind<CreateProjectInput>();
  const project = await context.dependencies.projects.create(input);
  return created(project);
});

Application and router

createServerApp() takes either a Router instance directly or a ServerAppOptions object listing router, routes, middleware, auth, fallback, a websocket adapter, probes, and telemetry. Either shape produces a ServerApp whose only contract is fetch(request): Promise<Response> — nothing Node-, Bun-, or Deno-specific leaks into the return type. The router itself owns path matching, per-route middleware, and WebSocket upgrade wiring; the app wraps it with cross-cutting options like error handling and probe checks.

Context-first handlers

Every handler and every Middleware receives a single ServerContext argument instead of separate request/response objects — request, url, params, headers, query, state, auth, and an AbortSignal all live on ctx. Dependencies like a database client are deliberately not part of that context; the README shows creating them at your composition root and passing them into route registration functions, keeping ctx reserved for request-scoped data. Because the context also carries every response helper (ctx.ok, ctx.notFound, and so on), a handler can build its whole response without importing anything else.

Response helpers

ctx.ok(), ctx.notFound(), ctx.created(), ctx.problem(), and the rest of the status-code helpers are methods on ServerContext, so a handler returns a Response by calling ctx.<name>(value) rather than constructing new Response(...) by hand. The same functions — json, text, redirect, setCookie, clearCookie, challenge, and friends — are also exported standalone from @askrjs/server for use outside a request context, such as inside an onError handler. setCookie() and clearCookie() take a Response and return a modified one; per the README they only touch response headers and have no opinion on session storage or credential validation.

Production boundary

ServerAppOptions accepts an onError(error, context) hook that runs when a handler throws, so you control exactly what an unhandled exception turns into instead of leaking a stack trace to the client. The OpenAPI layer defaults to validateResponses: false and only turns response validation on when you explicitly opt in outside production, because checking every response against its schema costs real time on every request. The package itself is still 0.0.x and pre-release — the README notes it isn't published to npm yet and its public contract can still move before 1.0.