Engine
Browser automations run when you press a key against a live page. The Engine is the other half: it runs workflows — @tranquil/sdk programs — headless, on a
schedule, a webhook, an event, or on demand, with no tab open and no one watching.
Not yet available. The Engine is in design; this page describes where it’s headed, not something you can run today. Browser automations (the in-app kind) work now.
Automations vs. workflows
Both are Deno TypeScript, sandboxed the same way, and surface their runs in the same Automation Runs panel. The difference is what starts them and how long they live:
| Browser automation | Workflow | |
|---|---|---|
| Starts on | a keystroke / the ▶ Run button | a schedule, webhook, event, or manual call |
| Runs | while you watch, against a tab | headless, in the background |
| Lives | one shot | durable — survives restarts, resumes where it left off |
| Built with | tranquil/automation | @tranquil/sdk (workflow(), step.*) |
A browser automation graduates into a workflow by moving code, not rewriting it — the step primitives are the same module in the same runtime.
Local-first, in the app
The Engine is a component of Tranquil, not a server you deploy. It lives in the running app: up whenever a Tranquil window is open, with a durable journal on your own disk. There are no accounts, no cluster, and nothing to install — a schedule that comes due while the app was closed simply fires on the next launch (catch-up). If cross-device or always-on execution is ever needed, the same workflows retarget to a bundled local server or a hosted service without changing how they’re written.
Triggers
A workflow declares how it starts:
schedule('cron')— fires on a cron expression; catches up on launch for schedules missed while closed.webhook({ path })— a stable local URL that starts a run when it’s hit.event('name')/emit()— one workflow wakes another.manual()— run it yourself from the palette or CLI.
Durable execution
Workflow code is journaled step by step. Each step.do(...) persists its result before the run
advances, so an app quit or crash mid-run resumes from where it left off — finished steps are
replayed, not re-run. step.sleep(...) is a durable timer that survives restarts, and step.waitForEvent(...) parks a run until something external resolves it. The surface is the common
subset of Cloudflare Workflows and Restate, kept deliberately small.
See also: Writing Automations — the in-app kind you can run today.