Skip to content

Host

FlareHost is the composition root for registration, build(), adapters, app entrypoints, and host.state.

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

FlareHost is the composition root: one object that holds your config tokens, services, routes, and runtime adapter. You register everything on it, then call build() to compile a runtime-specific app.

This page covers the registration surface and entrypoints. For how the graph is validated, see Build-time validation and What build() does. Signatures and validator codes live in the API Reference.

import { FlareHost, FlareResponse } from "@flare-ts/core";
import { node } from "@flare-ts/core/node";
const host = new FlareHost(node);
host.http.get("/ping", () => new FlareResponse(200, { ok: true }));
const app = host.build();
app.run();

Pass a runtime adapter and an optional array of host extensions. Register config, services, and arcs before the first build(). A second build() returns the cached app, and host.cfg, host.scoped, or host.singleton after build() throws: composition is closed once the host is built.

MethodPurpose
host.cfg(...tokens)Register flareConfig sections. Every token in a class’s static config must be registered here.
host.scoped(Service)Per-request service: new instance per request, disposed when the request ends.
host.singleton(Service)Process-lifetime service on Node: built at build(), onStart/onStop at app lifecycle. Not on Workers.
host.build()Validate the graph, compile arcs and DI, return the app. Idempotent.

Arc surfaces on the host:

ArcSurfaceDocs
HTTPhost.httpHTTP
WebSockethost.wsWebSockets
Durable Objectshost.durableObject(Class) (Workers)Durable Objects

Logger transports register on host.logging. See Logging.

AccessorWhenWhat
host.configAfter build()Resolved config from flare.json, env, defaults. {} before build.
host.loggerAfter build()Bootstrapped logger. Throws if read before build.
host.stateAny timeLifecycle: "starting" | "ready" | "draining" | "stopped". See Lifecycle.
host.scopedServices / host.singletonServicesAfter build()Compiled DI registries.

The adapter selects the runtime and config source.

AdapterImportUse
node@flare-ts/core/nodeNode.js: reads flare.json from cwd, process.env.
cf@flare-ts/core/cloudflareWorkers: empty bundled config; FLARE__* from env.
buildCf(json)@flare-ts/core/cloudflareWorkers with bundled flare.json at build time.
bun, deno@flare-ts/core/bun, .../denoStubs: build() throws today.

See Install and Runtimes.

host.build() returns an app. Call the entrypoint that matches your runtime:

MethodRuntimeWhat it does
app.run(options?)NodeBinds HTTP server; returns NodeRunHandle with stop().
app.export()WorkersRuns startup hooks; returns WorkerExportedHandle with fetch.
app.test(options?)Test (FLARE_MODE=test)Returns TestAppHandle with fetch, stop, reset.
import { FlareHost, FlareResponse } from "@flare-ts/core";
import { node } from "@flare-ts/core/node";
const host = new FlareHost(node);
host.http.get("/ping", () => new FlareResponse(200, { ok: true }));
const app = host.build();
const handle = app.run({ port: 3000, shutdownTimeout: 10_000 });
await handle.stop();
// Workers: export default app.export();
// Test (FLARE_MODE=test): const testHandle = await app.test();

See Testing for replace and reset.

host.state is read-only. Use it in readiness probes:

import { FlareHost, FlareResponse } from "@flare-ts/core";
import { node } from "@flare-ts/core/node";
const host = new FlareHost(node);
host.http.get("/ready", { isolated: true }, () =>
host.state === "ready"
? new FlareResponse(200, { state: host.state })
: new FlareResponse(503, { state: host.state }),
);
const app = host.build();
app.run();

Full state machine: Lifecycle.

When validators report errors, build() throws FlareValidationError with an errors array before anything binds a port or exports a handler. Catalog: Failure modes.