Conduit

Connect anything. Handle everything.

A connector framework built on Yella Engine. Standard interface for Slack, Discord, email, webhooks, cron: with crash-safe event processing, durable effects, and auth built in. Define send and receive. The framework handles the rest.

One Interface for Everything

Every connector follows the same pattern: declare events, declare config, implement setup. Webhooks, websockets, polling: doesn't matter. The framework normalises them all into events your handlers can process.

Connectors manage their own lifecycle. They report health, reconnect on failure, and shut down gracefully. You write the adapter, Conduit runs it.

const webhook = defineConnector({
  name: 'webhook',
  events: {
    received: { description: 'Webhook payload received' },
  },
  config: {
    secret: { required: false, secret: true },
  },
  setup(ctx) {
    ctx.routes.post('/inbound', async (c) => {
      ctx.emit('received', await c.req.json())
      return c.json({ ok: true })
    })
    return {
      start() { ctx.status('healthy') },
    }
  },
})
flowchart TD S["slack:message"] --> H["handle-message"] T["telegram:message"] --> C["classify-intent"] C -->|urgent| H2["escalate"] C -->|routine| H3["auto-reply"] H2 -->|ctx.effect| E["notify-oncall"] H3 -->|emit| F["log-response"] CR["cron:hourly"] --> P["poll-inbox"] P -->|new mail| T2["telegram:message"]

Events Flow, Handlers React

Connector events arrive prefixed: slack:message, cron:hourly, webhook:received. Your handlers pick them up, do work, and emit new events to chain workflows together.

Need to call a connector from a handler? ctx.connector('slack') gives you typed methods. Post a message, send a reply, upload a file: all through the same interface.

Auth Without the Ceremony

Three surfaces, each with its own middleware: public health checks, webhook ingress with HMAC verification, and operator routes for the dashboard. All opt-in: open by default for development, locked down when you're ready.

Outbound auth handles API keys, OAuth2 client credentials with automatic token refresh, HTTP Basic, or fully custom schemes. Credentials are stored encrypted in SQLite alongside your app state.

flowchart LR subgraph Public A["/livez"] B["/readyz"] end subgraph Ingress C["/connectors/*"] D["/hooks/*"] end subgraph Operator E["/dashboard"] F["/api/*"] end

Built on Engine

Conduit is a superset of Yella Engine. Every guarantee Engine provides: at-least-once delivery, durable effects, crash recovery, SQLite persistence: comes with Conduit for free. You get a connector framework and a workflow runtime in one package.

Quick Start
const app = createConduit({
  store: { type: 'sqlite', path: './app.db' },
})

await app.connector(slack, {
  auth: { token: process.env.SLACK_TOKEN },
})

app.process({
  name: 'handle-message',
  on: 'slack:message',
  run: async (ctx) => {
    const slack = ctx.connector('slack')
    await slack.postMessage({
      channel: ctx.payload.channel,
      text: `Got it: ${ctx.payload.text}`,
    })
    return ctx.ok()
  },
})

await app.listen(3000)

Also See

Yella Engine

The durable runtime underneath Conduit. Use it directly when you don't need connectors: just event processing with crash safety. Get started with Engine.

Yella

The full platform. Describe what you want, paste the docs into Claude, and let it build the whole thing. We host it for a fiver. Front door.