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.
- Import the published @askrjs/askr entrypoint.
- Keep platform services configuration next to the component, route, or server composition root that owns it.
- 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.