Skip to main content
Three host surfaces ship from packages/server, each a tighter fit for a different deployment.
  • startServer: a self-contained HTTP server with REST routes for run lifecycle, SSE event streams, and approvals. One server, many workflows by path. Reach for it when you want a plain HTTP API and no client SDK.
  • createServeApp: a Hono app bound to one already-loaded workflow and run. This is what bunx smithers-orchestrator up --serve mounts. Compose it into a larger Hono app or call app.fetch in tests.
  • Gateway: the headless control plane. Authenticate once, stream events over WebSocket with resume-on-reconnect, decide approvals, inject signals, run cron schedules, and serve many registered workflows. This is the surface the Gateway client and custom UIs talk to.
import { startServer, createServeApp, Gateway } from "smithers-orchestrator";
createServeApp needs a SmithersDb adapter and a loaded SmithersWorkflow; both come from your workflow module (new SmithersDb(workflow.db)). The Gateway is constructed with new Gateway(opts), then you register() workflows and listen().

startServer

Boot a listening http.Server exposing REST run lifecycle, SSE streams, and approval routes. Synchronous: it returns the bound server immediately.
function startServer(opts?: ServerOptions): import("node:http").Server;
opts
ServerOptions
http.Server
object
A listening Node http.Server. headersTimeout and requestTimeout are applied to it to bound slow header/body uploads. The full route table (run start/resume/cancel, SSE events, frames, approvals, signals, /metrics) lives in Server Mode.
const server = startServer({
  port: 7331,
  authToken: process.env.SMITHERS_API_KEY,
  rootDir: process.cwd(),
});
Source index.js · ServerOptions.ts · Tests server.test.js · See also Server Mode, Control-plane deployment

createServeApp

Build a Hono app for a single, already-loaded workflow and run. Returns a standard Hono app: mount it with Bun.serve, route it into another Hono app, or drive app.fetch directly in tests. This backs bunx smithers-orchestrator up --serve.
function createServeApp(opts: ServeOptions): import("hono").Hono;
opts
ServeOptions
required
Hono
object
A Hono app. Routes (/health, run status, SSE events, approvals, signals, /metrics) are documented in Serve Mode.
import { SmithersDb, createServeApp } from "smithers-orchestrator";

const abort = new AbortController();
const app = createServeApp({
  workflow,
  adapter: new SmithersDb(workflow.db),
  runId: "RUN_ID",
  abort,
  authToken: process.env.SMITHERS_API_KEY,
});
Bun.serve({ port: 7331, fetch: app.fetch });
Source serve.js · ServeOptions.ts · Tests serve.test.js · See also Serve Mode, Server Mode

Gateway

The multi-run control plane. Construct it, register() one or more workflows, then listen(). It serves RPC over POST /v1/rpc/<method> (and POST /rpc) and over WebSocket on the same origin, with a /health, /metrics, /workflows, and per-workflow webhook endpoints. The RPC methods (launchRun, getRun, listRuns, submitApproval, submitSignal, cron, time-travel, and more) are documented per method; see launchRun for the request/response and scope shape they share.
class Gateway {
  constructor(options?: GatewayOptions);
  register(key: string, workflow: SmithersWorkflow, options?: GatewayRegisterOptions): this;
  extend(namespace: string, definition: unknown): this;
  listen(options?: { port?: number; host?: string; path?: string }): Promise<import("node:http").Server>;
  close(): Promise<void>;
}
register, extend, and the constructor are chainable. listen defaults to port 7331; pass path for a Unix socket. close aborts active runs, drains inflight work, and tears down connections and the scheduler.
import { Gateway } from "smithers-orchestrator";

const gateway = new Gateway({
  heartbeatMs: 15_000,
  auth: {
    mode: "token",
    tokens: { "operator-token": { role: "operator", scopes: ["*"] } },
  },
});

gateway.register("deploy", deploy, { schedule: "0 8 * * 1-5" });
await gateway.listen({ port: 7331 });

GatewayOptions

options
GatewayOptions

GatewayAuthConfig

A discriminated union on mode. Runs started through an authenticated gateway expose ctx.auth = { triggeredBy, role, scopes, createdAt }.

UI config

defaults

register

Register a workflow under key. Wires up its DB tables, optional cron schedule, webhook config, and embedded UI bundle. Returns this, so calls chain. A schedule writes a cron row keyed gateway:<key>; cron-fired runs get ctx.auth.role = "system", triggeredBy = "cron:gateway", scopes = ["*"].
key
string
required
Workflow key. Becomes the path segment for workflow-level UI and webhooks.
workflow
SmithersWorkflow
required
The loaded workflow instance.
options
GatewayRegisterOptions

listen / close

options
object
listen
Promise<http.Server>
Resolves once the server is bound and the scheduler and event bridge have started.
close
Promise<void>
Aborts active runs, awaits inflight work, closes connections, and stops the scheduler and watchers.
Source gateway.js · GatewayOptions.ts · GatewayAuthConfig.ts · Tests gateway.test.jsx · See also Gateway, Control-plane deployment, launchRun, Gateway client
For the full route tables and wire shapes, see Server Mode, Serve Mode, and Gateway. The exact type definitions are mirrored in the Types reference.