Open source · Agent-first · Next.js + Drizzle + Postgres

The foundation for your data syncs.

khotan-data is shadcn × better-auth, but for data. Move data service-to-service, run ETL pipelines, or sync an external API into your Postgres — typed, debugged connections your coding agent defines and you own.

GitHubRead the docs
Say you want to sync a bank

The same integration, two very different days.

You need transactions from a bank's API flowing into your Postgres. Here is the work — with and without khotan.

Without khotan~a sprint
  • Dump the bank’s API docs into your agent’s context and hope it reads them.
  • Hand-write an HTTP client: auth, retries, pagination, error handling.
  • Hand-edit your Drizzle schema to match the API by eye.
  • Get the agent to write throwaway scripts to hit your DB — or stand up an MCP.
  • Paste curl commands back and forth to figure out the real response shape.
  • Re-wire cron, idempotency, and retries from scratch — every single time.
Bespoke glue code nobody owns — and it breaks silently when the API drifts.
With khotan~an afternoon
  1. 1
    Install
    npm i khotan-data
  2. 2
    Add the schema
    npx khotan add schema

    Typed tables for plugs, flows, runs — migrated for you.

  3. 3
    Add a plug
    npx khotan add plug bank

    An HTTP client scaffold with auth, retry, and pagination built in.

  4. 4
    Agent defines typed endpoints

    Your agent writes Zod-typed endpoints on the plug — the contract for the API.

  5. 5
    Debug & probe
    npx khotan plug bank --compare

    Fire the live API and diff the real response against your types until they line up.

  6. 6
    Add an inflow
    npx khotan add inflow

    A scheduled, durable sync that loads straight into your Postgres.

Then it just works — durable, retried, observable.
What you actually ship

A typed pipeline, end to end.

Every connection is the same shape: a typed plug talks to the API, a flow moves the data on Vercel Workflow, and it lands in your own Drizzle tables.

Bank API
external · REST
Plug
typed · auth · retry
Inflow
Vercel Workflow
Your Postgres
Drizzle tables
app/api/khotan/[...all]
one catch-all route
Hub & Runs
toggle, run, trace every flow
Plug Debugger
probe live responses vs. types
Architecture

One route. The same handler from anywhere in your app.

Just like better-auth, khotan installs a single catch-all route in your app. Your client calls it over HTTP. Your server code skips the HTTP entirely. Both end up in the same typed handler — which talks to your Drizzle schema and external APIs for you. Extremely narrow, fully extensible.

Install onceapp/api/khotan/[...all]/route.ts
// One catch-all route. All components route through here.
import { khotanData } from '@/lib/khotan'
import { toNextJsHandler } from 'khotan-data/next-js'
export const { GET, POST } = toNextJsHandler(khotanData.handler)
Use everywhereany client, server, or route file
// From the frontend → goes over HTTP
'use client'
await khotanClient
.plug.create({ provider: 'stripe' })
// From the server → skips HTTP, direct call
await khotanData.api
.plug.create({ provider: 'stripe' })
// From another handler → same direct call
await khotanData.api
.inflow.run({ source: 'stripe' })
1Configure

List the components you want in khotan.config.ts. The package wires up the handler.

2Route

The CLI drops a single catch-all route. You never edit it.

3Call

Typed API surface, same on client and server. Handler hits Drizzle and external APIs for you.

Agent-first

khotan comes with skills.

khotan-data ships built-in agent skills — focused SKILL.md guides that teach your coding agent how to do one integration job well. On khotan init, they install straight into Cursor, Claude Code, Codex, Copilot, Kiro, and Roo. Purpose-built for integration and syncing.

khotan-build

The orchestrator. Run the end-to-end integration workflow — docs to working sync — with the consent gates that keep an agent safe. Start here.

$ npx khotan add skill-build
khotan-setup

Stand up khotan in a Next.js + Drizzle + Postgres project — factory config, schema, migrations, env vars, and recovery when setup is incomplete.

$ npx khotan add skill-setup
khotan-plug

Author plugs — HTTP clients with auth strategies, runtime vars, hooks, and Zod-typed endpoints. The contract for any external API.

$ npx khotan add skill-plug
khotan-probe

Debug plugs from the CLI. Fire live requests and diff the real payload against your typed endpoints until the schema matches reality.

$ npx khotan add agent-skill
khotan-flow

Build and run inflows, outflows, and relays on Vercel Workflow — pull data in, push it out, or move it plug-to-plug, then trigger and schedule.

$ npx khotan add skill-flow
khotan-webhook

Receive and process webhooks with Wires, Catch, and Pass — subscriptions, signature verification, durable processing, and forwarding.

$ npx khotan add skill-webhook
khotan-cache

Add durable, named caches to flows and webhooks for upstream snapshots, run checkpoints, and dedupe markers with optional TTL.

$ npx khotan add skill-cache
khotan-mappings

Define resources and match records across services with a canonical connect key plus per-plug refs, keeping upserts idempotent.

$ npx khotan add skill-mappings
khotan-frontend

Suggest the right drop-in components and page blocks — Hub, debugger, logs, mappings — and never inject UI or add routes unprompted.

$ npx khotan add skill-frontend
Agent router

Installs every skill into Cursor, Claude Code, Codex, Copilot, Kiro, and Roo, and drops an AGENTS.md router at your project root.

$ npx khotan init --yes
Install them all at once:npx khotan init --yesBrowse every skill

Every pattern, the same shape.

Same retry contract. Same idempotency story. Same observability surface. Stack them like LEGO.

add wire <service>

Wire

Wire your app to an external API — encrypted creds, typed client, optional connect-account UI. The foundation every other component sits on.

add plug

Plug

One-way HTTP client to an external API — auth strategies, retry with backoff, pagination, and optional typed endpoints with Zod.

add catch <source>

Catch

Catch a webhook and write it to your Postgres. Signed verification, idempotent, raw body capture. Writes to your Drizzle tables.

add pass <source> <destination>

Pass

Catch a webhook and pass it through to another service. Signed in, signed out, retried delivery. No staging in your DB.

add inflow <source>

Inflow

External service → your Postgres. Pull from a SaaS API, transform, load into your Drizzle tables.

add outflow <destination>

Outflow

Your Postgres → external service. Push audiences, scores, enrichments to Salesforce, HubSpot, Intercom.

add relay <source> <destination>

Relay

External → external. Transit data between two SaaS systems without staging in your DB.

add hub

Hub

Config card listing every Flow with toggles and a manual Run-now button. Backed by the standard khotan_flows table.

add runs

Runs

Drop-in shadcn data table of every flow run — status, stats, full step-by-step trace per row. Reads from the standard khotan_runs table.

One stack. Drizzle + Postgres + Next.js.

We are intentionally narrow. Drizzle ORM is the only adapter today — because that constraint lets us guarantee every schema patch is correct. App Router native. Vercel Workflow for durability. Zod for validation. Every generated file looks like code your team would have written, because it is.

Next.js App Router
Drizzle ORM
Postgres
Vercel Workflow