---
title: How it works
description: One catch-all route, generated component files in your repo, and a shared runtime for flows, wires, catches, passes, and runs.
section: Get Started
url: /docs/how-it-works
---

# 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

The CLI writes real files into your app:

- `khotan.config.ts`
- `src/khotan/` or `khotan/` builders like `plug.ts`, `inflow.ts`, `wire.ts`, `catch.ts`, `pass.ts`
- React components in `src/components/khotan/`
- ready-made route blocks in `src/app/` or `app/`
- the catch-all route at `src/app/api/khotan/[...all]/route.ts` or `app/api/khotan/[...all]/route.ts`

### 2. Factory registration

Your `khotan.ts` file registers:

- resources
- plugs
- flows
- wires
- catch handlers
- pass handlers

The factory config is the source of truth that tells khotan what should exist.

### 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

This is the modern high-level pattern:

```ts
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;
```

```ts
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 uses a standard relational model:

- `khotan_plugs` for registered external service clients
- `khotan_resources` for cross-system logical entities
- `khotan_flows` for configured inflows, outflows, relays, and other tracked flow records
- `khotan_wires` for webhook subscription state
- `khotan_webhook_handlers` for catch and pass registrations
- `khotan_webhook_events` for captured inbound deliveries
- `khotan_runs` for durable execution records
- `khotan_mappings` for cross-system identity mapping

That shared schema is what lets the dashboard, CLI, and runtime all talk about the same objects.

## 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 not a separate product tier. 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

Use JSON-friendly commands:

- `khotan plug`
- `khotan plug vars`
- `khotan wire`
- `khotan flows`

### 2. UI

Use generated components or blocks:

- `hub`
- `runs`
- `logs`
- `plug-debugger`
- `config-page-1`
- `logs-page-1`
- `graph`
- `debug-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

The catch-all route is important because it avoids scattered endpoints and keeps the operational model consistent:

- 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`. That means:

- 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 machine-readable 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

The docs site mirrors the rendered pages with `.md` routes on purpose so agents can crawl the docs without scraping the UI.

## Next steps

- Read [Configuration](/docs/configuration) for env vars and registration details.
- Read [CLI Reference](/docs/cli) for machine-friendly operational commands.
- Read [Components](/docs/components) and [Blocks](/docs/blocks) for scaffolding coverage.
