ADR 0004: @arachnejs/config typed loader
- Status: Accepted
- Date: 2026-09-27
- Deciders: Arachne core
Context #
Apps need 12-factor configuration: a typed file (arachne.config.ts),
environment overrides, and optional CLI flags — validated at boot with clear
errors.
Decision #
@arachnejs/config provides:
- A schema built from plain TypeScript validators (Standard Schema–
compatible shape:
{ "~standard": { validate, version, vendor } }) plus a small built-in schema DSL (string,number,boolean,object,optional,defaulted) so Phase 0 does not depend on@arachnejs/schema. - Load order (later wins): defaults → config file → env (
ARACHNE_*or custom prefix, nested via__) → explicit overrides / CLI. - Fail-fast: invalid config throws
ConfigErrorwith a path-keyed message list. Required secrets missing at boot are errors, not warnings. - Runtime-agnostic file loading via injected
readFile/importConfighooks so Bun, Node, and tests share one path.
Depends only on @arachnejs/core (for ConfigError base / logger optional).
Alternatives considered #
- zod / valibot only — fine, but we want Standard Schema from day one and a zero-dep path for the kernel.
- cosmicconfig — overkill; we own the file name and load rules.
Consequences #
- Apps call
loadConfig(schema, options)once at boot. @arachnejs/schemawill later implement the richer DSL; config keeps its thin built-in validators for bootstrap.