Environment Configuration
Use environment configuration with the current published Askr packages.
@askrjs/askr0.0.59
How to use environment configuration
Read and validate environment values once in the server composition root; pass a typed config object to services instead of reading globals throughout the application.
- Import the published @askrjs/askr entrypoint.
- Keep environment configuration 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.
export const config = Object.freeze({
apiUrl: requireUrl(process.env.API_URL, 'API_URL'),
oidcIssuer: requireUrl(process.env.OIDC_ISSUER, 'OIDC_ISSUER'),
port: requireInteger(process.env.PORT ?? '3000', 'PORT'),
});
const app = createApplication({ config });Goal and architecture
Askr splits configuration along the same boundary as the rest of the framework: build-time and browser config comes from Vite's `import.meta.env`, and server process configuration is plain `process.env` read where you construct your server app. There's no Askr-specific config-loading module — `listen(app, { port, host, backlog, signal })` and `serve(app, { assets, signals })` from `@askrjs/node` take their settings as plain options objects, and you're expected to populate those options from `process.env` yourself.
Implementation
Read server settings once at startup — `const port = Number(process.env.PORT) || 3000` — and pass them into `listen(app, { port, host })` or `serve(app, { port, assets: { root } })` rather than reading `process.env` scattered through route handlers. Client-exposed values must go through Vite's `VITE_`-prefixed `import.meta.env` variables so the bundler statically replaces them at build time; anything without that prefix stays server-only and never reaches the browser bundle, which is the actual security boundary here, not a convention you have to enforce by hand.
Failure states
Fail fast on missing required configuration — validate `process.env` at startup (a required `DATABASE_URL` or JWKS URL that's absent should throw before `listen()` is called, not produce a cryptic runtime error on the first request). A misconfigured `VITE_API_BASE_URL` that's silently `undefined` will make every `@askrjs/fetch` client call fail with a network error that looks unrelated to configuration, so validate build-time env vars in your Vite config rather than discovering the problem in production logs.
Verification
Test config parsing as a pure function — given a `process.env`-shaped object, assert it produces the expected typed config or throws for each missing/invalid required key. Confirm your `.env` files for different environments (development, staging, production) don't leak server-only secrets into `VITE_`-prefixed names, since anything with that prefix ships to the browser. Run a build with a deliberately incomplete environment in CI to catch missing required variables before they reach a deploy.