Askr
Server & APIs

Platform Services

Use platform services with the current published Askr packages.

  • @askrjs/askr0.0.59

How to use platform services

Create the platform service at the application composition root and pass its provider-neutral contract into routes or components.

  1. Import the published @askrjs/askr entrypoint.
  2. Keep platform services 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 { createI18n } from '@askrjs/i18n';

export const i18n = createI18n('en', {
  en: { greeting: (name: string) => 'Hello, ' + name },
  fr: { greeting: (name: string) => 'Bonjour, ' + name },
});

<i18n.Scope locale="en">
  {i18n.text('greeting', 'Askr')}
</i18n.Scope>

Node runtime

@askrjs/node wires an Askr `ServerApp` into a real Node process: `createNodeHandler` turns it into a plain `(req, res, next)` function, `listen` binds a raw `http.Server`, and `serve` wraps both together with signal handling and an asset root. Nothing here depends on a specific host — the same app can run behind a reverse proxy, inside a container, or from a local script. If you're deploying to a serverless platform instead, you'll use that platform's adapter rather than this package.

Internationalization

@askrjs/i18n gives you `createI18n(sourceLocale, catalogs)`, where catalogs are ordinary TypeScript functions rather than a message-key DSL. The source locale's function signatures become the required shape for every other locale, so a French catalog missing an argument or a key fails at compile time, not in production. Locale selection itself — reading a cookie, a URL prefix, a header — is left entirely to your application code.

Telemetry

@askrjs/otel's `createTelemetry` produces a `Telemetry` object with typed span helpers — `request`, `loader`, `action`, `routeMatch`, and more — each scoped to one of a fixed set of `askr.*` operation names. It talks to whatever OpenTelemetry provider your app installs via the standard `@opentelemetry/api`, and does nothing observable if you haven't installed one. Fields passed into spans are limited to a small allowlisted shape: request IDs, routes, status codes, durations — no request bodies or user data.

Composition

These three packages are independent and none of them requires the others — you can use `@askrjs/i18n` without touching telemetry, or run under `@askrjs/node` without ever calling `createTelemetry`. In practice most apps construct them once in a composition root alongside the server app, then thread the resulting `i18n` and `telemetry` instances through as plain values wherever loaders and actions need them.