Stop gluing APIs, jobs, and queues into one backend. One law collapses them — client, Console, and infra come free. Yours to host.
Select a line — each number is exact.
eight elements
irreducible physics only
New infrastructure is a driver — never a ninth element.
OKE is the batteries-included TypeScript backend for the Bun era: contract-first APIs with end-to-end type safety, declarative infrastructure primitives, an OpenTelemetry-native Console, secure-by-default auth and ABAC — pure TypeScript, Web-Standards portable, MIT-licensed, self-hostable with zero cloud lock-in.
All world access goes through fx. That one rule is why effects, cache keys, capability matrices, and traces are inferred instead of annotated by hand.
bunx create-oke@latest my-app --from-example notes
Router, queue, cron, websockets, cache, secrets, mailer, model calls — the §5 table names forty such concerns, each arriving with its own config, client, and failure mode, and you own every seam between them. The eight elements exist to collapse that graph.
+ model calls, prompts, embeddings, agents and RAG — 23 new seams to keep in sync, 136 in total.
Change delay and all 4 of its seams have to be re-checked.
All 40 concerns the eight elements replace, straight off the unified theory's §5 table — each its own tool, client, and config.
An edge is drawn only where two concerns genuinely meet: a credential, an invalidation, an ordering, a delivery. That is still 136 seams you own, and a trace that stops at every one of them.
There are no separate species called endpoints, handlers, consumers, jobs, or workflows. There is one species — and triggers are typed values.
export const create = on(http.post("/notes"), flow({
in: NewNote,
out: NoteId,
do: async (input, fx) => {
const [note] = await fx.store(db).insert(notes).values(input).returning();
return { id: note.id };
},
}));
// effects → writes[sql:notes]An element earns its place only if it has irreducible physics. New infrastructure becomes a driver for an existing element — never a ninth element.
Flowbehavior
Endpoints, jobs, consumers, and workflows — one species.
Signaldata in motion
Queues, pub/sub, and streams — delivery is a property.
Storedata at rest
SQL, KV, files, and search index as one store surface.
Clocktime
Cron, delays, timeouts, and durable sleep.
Gatepermission to act
Auth, ABAC, rate limits, and feature flags at the trigger.
Vaultprotected knowledge
Secrets and config with typed contracts.
Channelreaching humans
Email, SMS, WhatsApp, push — consent and locale built in.
AIreaching machine intelligence
Models, prompts, agents, and RAG with cost and PII rules.
The entire public vocabulary fits on one line. Everything else in the docs is derived from these ten names.
import { on, flow, signal, store, clock, gate, vault, channel, ai, plugin } from "okengine";on01bind a trigger to a flow
flow02define behavior + contracts
signal03data in motion
store04data at rest
clock05time
gate06permission to act
vault07secrets and config
channel08reach humans
ai09reach models and agents
plugin10extend without a ninth element
Code dies and frameworks die, but data formats survive. So the real product is the Manifest: a runtime-neutral description of your system, extracted from your TypeScript at build time — and everything downstream is derived from it.
src/flows/**on(trigger)triggersflow({ in, out, errors })contractsfx.store · fx.emit · fx.vault · fx.askeffects.gate(…)permissionsNothing to annotate by hand: fx is the only door to the world, so the compiler can see every read, write, emit, and secret.
manifest.oke.jsonA machine-readable description of the whole system, versioned independently of the runtime ("oke": "1.0").
8 surfacesclient & docs
console & agents
build & runtime
oke dev starts your app, the Console, and the MCP endpoint from the same Manifest. Mnemonic: O·K·E = 6·5·3.
:6530AppYour flows, served from the Manifest.
:6533ConsolePanels, traces, and the effect graph.
:6535MCPThe same Manifest, for agents.
The Console is Manifest-derived — flows, contracts, effects, traces, and an architecture diagram are already there. Read the Console docs.
One law → one mental model → one documentation path → one trace shape → one thing for an AI agent to learn.