Skip to content

Configuration

Why Flare uses typed config tokens, how flare.json and env overrides merge at build(), and where resolved values live on the host.

AI generated, pending review Updated 10 days ago · Flare 0.3

Flare config is typed, sectioned, and validated at host.build(). You declare a flareConfig token for each top-level flare.json section your app cares about, register those tokens with host.cfg(), list them on classes that read config, and resolve values with this.config(token) or scope.config(token). After build, the merged result also appears on host.config (for example host.config.db).

This page is the why and the flow. For step-by-step registration, see Configure your app. For flare.json, schema, and FLARE__* env keys, see flare.json reference.

A flareConfig("db", { url: str, … }) call creates a config token: a small object keyed to one section name. The same object reference must flow through host.cfg(), static config, and this.config(). That gives you three things at once:

  • Compile-time types inferred from your descriptor map.
  • Build-time validation that required fields exist and match schema primitives.
  • Explicit wiring: a class cannot read a section it never declared, and the host cannot skip registering a section a class needs.

Without this, the same values come from process.env read inline wherever they are needed. Each read is a string | undefined, so a number or boolean is re-parsed at every call site, a required variable nobody set reads as undefined at whichever line happens to touch it first, and the precedence between a file, an env override, and a default is whatever each read site coded. A typed section states the fields and their types once, fixes the file-then-env-then-default merge order, and turns a missing or mistyped value into a build() failure that names the section instead of an undefined surfacing in a handler on the request that first reaches it.

HOST_CONFIG, LOG_CONFIG, COOKIES_CONFIG, and WEBSOCKETS_CONFIG are built-in tokens for the host, log, cookies, and websockets sections. The FlareHost constructor registers all four automatically. Every other section is yours to declare.

At host.build(), the runtime adapter loads config in layers:

  1. flare.json from disk (Node) or bundled JSON (Workers with buildCf), or {} when the file is missing.
  2. FLARE__section__field environment overrides merged into that raw object.
  3. Empty {} inserted for any registered section still absent after merge.
  4. Development defaults for unset log.level / log.format when host.env is set to "development". The dev branch reads the raw host.env before schema defaults apply, so an unset host.env doesn’t trigger it.
  5. Schema validation per registered descriptor. The result becomes host.config.

Only sections whose tokens you registered with host.cfg() appear on host.config after build, even if the same keys exist in flare.json or env. Unregistered keys are ignored during parse.

Full resolution order, field tables, and env path rules: flare.json reference.

ConsumerHow
Services, controllers, middleware, error handlersstatic config = [Token, …] and this.config(Token)
Inline HTTP handlersscope.config(Token) (no static config array)
Transports and boot codethis.config(Token) when listed in static config, or host.config after build

Referential identity matters: the Token argument must be the same object you passed to host.cfg() and listed in static config. A fresh object with the same shape is rejected.

The FlareHost constructor registers four sections every app gets:

TokenSectionRole
HOST_CONFIGhostListen address, timeouts, body limits, env
LOG_CONFIGlogLevel, format, context, per-transport overrides
COOKIES_CONFIGcookiesSigning secret for signed cookies
WEBSOCKETS_CONFIGwebsocketsMessage limits, keep-alive, and timeouts for WebSockets

See Host for how host settings apply at runtime and Logging for the logger surface.

Missing fields, wrong types, or unregistered tokens surface during host.build(). Config schema parse failures throw a plain Error with Config validation failed: …. UNREGISTERED_CONFIG_TOKEN fires for a token a class reads but you never registered with host.cfg(). MISSING_CONFIG_FIELD fires when a registered section is missing a required descriptor field after merge. Both surface as FlareValidationError entries. Catalog: Failure modes.