How it works
khotan-data combines generated source files in your repo with a runtime that lives behind one catch-all route.
The generated files describe what your app wants to do. The runtime handles storage, orchestration, wiring, and operational APIs.
The three layers
1. Scaffolded files in your repo
khotan.config.tssrc/khotan/orkhotan/builders likeplug.ts,inflow.ts,wire.ts,catch.ts, andpass.ts- React components in
src/components/khotan/ - ready-made route blocks in
src/app/orapp/ - the catch-all route at
src/app/api/khotan/[...all]/route.tsorapp/api/khotan/[...all]/route.ts
2. Factory registration
Your khotan.ts file registers:
- resources
- plugs
- flows
- wires
- catch handlers
- pass handlers
3. Runtime tables and APIs
At runtime, khotan upserts that registration data into its standard tables and exposes operational APIs under /api/khotan/*.
The runtime shape
import { khotan, drizzleAdapter } from "khotan-data/factory";
import { db } from "@/db";
import { sourcePlug } from "./plugs/source";
import { targetPlug } from "./plugs/target";
import { sourceWire } from "./wires/source-wire";
import { sourceCatch } from "./webhooks/source-catch";
import { sourcePass } from "./webhooks/source-pass";
import { sourceInflow } from "./flows/source-inflow";
const khotanData = khotan({
adapter: drizzleAdapter(db),
resources: [
{ name: "products", mapping: { connectField: "sku" } },
],
plugs: [
{
name: "source",
plug: sourcePlug,
flows: [sourceInflow],
wires: [sourceWire],
catches: [sourceCatch],
passes: [sourcePass],
},
{
name: "target",
plug: targetPlug,
},
],
});
export default khotanData;import { toNextJsHandler } from "khotan-data/factory";
import khotanData from "@/khotan/khotan";
export const { GET, POST, PUT, PATCH, DELETE } = toNextJsHandler(
khotanData.handler,
);What gets persisted
khotan_plugskhotan_resourceskhotan_flowskhotan_wireskhotan_webhook_handlerskhotan_webhook_eventskhotan_runskhotan_mappings
How components fit together
Plug
Defines how your app talks to an external API. It can declare auth, vars, hooks, and endpoint metadata.
Flow
Defines durable data movement. Inflow, Outflow, and Relay are the main flow types. Each run gets tracked in khotan_runs.
Wire
Defines how khotan subscribes and unsubscribes from a source system's webhook API, and optionally how to verify signatures on inbound deliveries.
Catch
Processes a verified inbound event inside your app with durable workflow steps.
Pass
Processes a verified inbound event and forwards it to another plug, with destination vars injected automatically.
Dashboard and logs
Hub, Runs, Logs, and Plug Debugger sit on top of the same runtime data and APIs. They are generated UI components that operate on the khotan runtime already in your app.
The operational surfaces
You can interact with khotan three ways.
1. CLI
khotan plugkhotan plug varskhotan wirekhotan flows
2. UI
hubrunslogsplug-debuggerconfig-page-1logs-page-1graphdebug-page-1
3. Direct runtime route
Everything is mounted under /api/khotan/*, so the same state is visible to your app code, CLI tooling, and UI.
Why one route works
- plug metadata and debug endpoints live in one namespace
- wire connect and disconnect actions live in one namespace
- flow listing, triggering, runs, and cancellation live in one namespace
- generated UI components can rely on a stable runtime surface
Runs are the unifying record
Every durable unit of work writes to khotan_runs.
- flows can be listed and re-triggered
- webhook executions can be traced
- the Runs and Logs UIs can show one consistent execution history
- agents and scripts can inspect the same records the UI uses
Built for agents too
khotan ships built-in skills and an AGENTS.md router. After installation, an agent should:
- read the project-root
AGENTS.md - read
/docs/agents - prefer the raw markdown docs routes when extracting documentation
Next steps
- Read
/docs/configurationfor env vars and registration details. - Read
/docs/clifor machine-friendly operational commands. - Read
/docs/componentsand/docs/blocksfor scaffolding coverage.