v0.3

A TypeScript framework validated before traffic

Compose one host graph. host.build() validates it. Same app on Node or Cloudflare Workers.

Flare composes routes, services, contracts, and state into one graph, then validates and compiles it before traffic.

NODE · WORKERS RUNTIMES

Same app, two runtimes.

Routes, services, contracts, and state stay on one host. Swap the adapter, then call run() on Node or export the app to Workers.

the deployment boundary
NODE · node.ts
const host = new FlareHost(node);
const app = host.build();
app.run();
WORKERS · worker.ts
const host = new FlareHost(cf);
const app = host.build();
export default app.export();

Bun and Deno adapters ship before v1.

BEFORE TRAFFIC BUILD

Broken wiring never reaches traffic.

Typed handlers are not a validated application. host.build() walks providers, contracts, state, and adapter constraints before the server starts.

Missing DI, unprovided state, and dead wiring fail together at composition time, where they are still cheap to fix.

REGISTRATIONS Services, config tokens, routes, middleware, contracts, and request state enter one host graph.
VALIDATION Service graph, HTTP and WebSocket, and config validators report wiring errors before compilation.
COMPILATION Flare builds DI registries, the router, response serializers, and one execution pipeline per route.
tsx src/main.ts
[flare] Build failed with 1 validation error:

  1. [CONTROLLER_UNREGISTERED_DEP] Controller OrphanController depends on unregistered service MissingSvc.
     Hint: Register MissingSvc with host.scoped() or host.singleton() before calling host.build().
AS NEEDED DEPTH

Start with a route. Add depth in place.

An inline handler is a complete app. Grow the same registration with contracts, request state, and services only when the surface needs them.

CONTRACTSCoerce route, query, and body before the handler runs.
STATECarry typed request truth from middleware; routes declare what they require.
SERVICESInject scoped or singleton deps when a handler needs collaborators.
src/users.ts
host.http.get("/users/:id", { route: { id: int } },
  (_ctx, scope) => new FlareResponse(200, {
    id: scope.input.route.id,
  }),
);
47.6K REQ/S HOT PATH

What the framework adds per request.

This bench measures framework overhead on a simple GET / returning {"hello":"world"}. We run fastify/benchmarks on GitHub Actions with Flare added to the package list, then take the median across 5 sweeps.

It does not model a real application. It shows what each framework adds before your handler runs. Flare compiles per-route pipelines at build(), so the request path does not rebuild the graph.

measured results
frameworkreq/slatencyCV
node-http 47.9k 20.38 ms 0.75%
flare 47.6k 20.52 ms 0.92%
fastify 46.7k 20.87 ms 0.98%
hono 40.0k 24.51 ms 1.18%
express 27.7k 35.60 ms 1.16%
relative requests / second
node
flare
fastify
hono
express

flare-bench · 5 sweeps · v24.18.0 · 2026-07-20 · simple framework-overhead test

ONE HOST BEYOND

One host, more than routes.

WebSockets live beside HTTP on the same composition graph. Host extensions stamp capabilities onto host.*, so packages add surface area without adding a second stack.

Zero runtime dependencies. Core and schema stay in-tree, with no plugin chain on the hot path.