Dashboards, internal tools, customer portals: real frontends your users describe and an agent builds, wired to their workflows through a typed contract. Every button press can trigger a durable run. You can even build app builders with it.
// The app calls workflows through a typed, JSON-safe contract.
// A Date that types as a Date but arrives as a string is exactly
// the bug this catches at compile time.
export interface ListOrders {
input: { status: "open" | "all" };
output: Order[];
}
export interface AppContract {
listOrders: PlainWorkflow<ListOrders>;
reconcileLedger: DurableWorkflow<ReconcileLedger>;
}
// why apps
A workflow without a UI is a tool for operators. Give it a frontend and it becomes a product your users hand to their own teams and customers.
One conversation produces the frontend and the workflows behind it, in the same project, in the same git history. Change the UI and the logic together, from a prompt.
Apps call workflows through a typed contract with compile-time JSON safety: a Date, a Map, or a function that would not survive the boundary is a build error naming the offender, not a runtime surprise.
User-built apps render in an isolated frame and reach the outside world only through the contract. They get exactly the workflows the project exposes, and nothing else.
A button press can trigger a plain call or a long-running durable workflow with retries, pauses, and signals. The app observes run state through the same protocol; nothing is faked.
An app is files in the project repo: reviewable, diffable, versioned, portable. No proprietary builder format to be trapped in.
Embed the whole surface in your SaaS and your product grows an app platform: your users building tools for their users, with AI doing the heavy lifting. Catamorphic is the substrate, you own the experience.
Workflows give your users durable automation. Apps give that automation a front door. Both are TypeScript in the same git repo, built by the same agent, embedded in your product.