Adding a server doesn't mean adding a second framework.

Page routes, actions, HTTP APIs, and auth policies meet at one application composition root — no parallel backend project to keep in sync.

Forms submit to actions. Actions are just handlers.

A page action is a POST handler that returns a redirect or a field-level error — it works with JavaScript disabled, and the same Request/Response primitives back your JSON APIs.

  1. Pages

    Routes and loaders

  2. Actions

    Forms and mutations

  3. APIs

    Request and Response

Composition root

Policies + dependencies

Schemas, auth contracts, and application services meet here.

One schema, checked twice

Define an input schema once with @askrjs/schema and it validates the request at runtime and generates the matching OpenAPI operation — so a CI check can catch the day your handler and your published API contract disagree.

Auth is a policy function you attach to a route, plus whatever identity provider you plug in — Askr doesn't ship its own user database or decide who counts as logged in.

View the server foundation

Add the server when a route actually needs one.