Swirls Docs
Define, run, and deploy AI-powered workflows.
Swirls is a workflow engine for AI applications. Define workflows in .swirls files, run them locally or in the cloud.
A complete workflow in one file
This workflow accepts a contact form submission, summarizes it with an LLM, and sends a confirmation email.
form contact_form {
label: "Contact Form"
enabled: true
schema: @json {
{
"type": "object",
"required": ["name", "email", "message"],
"properties": {
"name": { "type": "string", "title": "Name" },
"email": { "type": "string", "title": "Email" },
"message": { "type": "string", "title": "Message" }
}
}
}
}
graph process_form {
label: "Process Form"
root {
type: code
label: "Normalize"
code: @ts {
const { name, email, message } = context.nodes.root.input
return { name: name.trim(), email: email.toLowerCase(), message: message.trim() }
}
}
node summarize {
type: ai
label: "Summarize"
model: "google/gemini-2.5-flash"
kind: object
schema: @json {
{ "type": "object", "required": ["text"], "properties": { "text": { "type": "string" } } }
}
prompt: @ts {
const { name, email, message } = context.nodes.root.output
return `Summarize in one sentence:\n\nFrom: ${name} <${email}>\n\n${message}`
}
}
node notify {
type: email
label: "Send confirmation"
to: @ts { return context.nodes.root.output.email }
subject: @ts { return "We received your message" }
text: @ts {
return `Thanks for reaching out. Summary: ${context.nodes.summarize.output.text}`
}
}
flow {
root -> summarize
summarize -> notify
}
}
trigger on_contact {
form:contact_form -> process_form
enabled: true
}What you get
.swirlsfiles: declarative, versionable workflow definitions with full editor support- AI-native nodes:
ai,code,http,email,switch,stream, and more - Type-safe TypeScript blocks with LSP-powered IntelliSense
- Triggers: connect forms, webhooks, and schedules to graphs
- Streams: persist and query graph outputs with SQL
- Human-in-the-loop: pause workflows at any node for review and approval
- Local execution: run graphs on your machine with the CLI
- Cloud deployment: managed infrastructure, no ops required
When to use Swirls
- AI content pipelines: draft, review, and publish content with LLM nodes and human review gates
- Lead enrichment and scoring: enrich form submissions via HTTP, score with an LLM, route to CRM
- Support ticket triage: classify urgency with a switch node, draft responses with an LLM
- Automated reporting: schedule graphs to query data streams and deliver formatted summaries
- Form-driven workflows: collect structured input, process it with AI, notify via email or webhook
Quick reference
Code node: run TypeScript, read upstream outputs via context.nodes.
node normalize {
type: code
label: "Normalize email"
code: @ts {
const { email } = context.nodes.root.input
return { email: email.trim().toLowerCase() }
}
}AI node: prompt an LLM and get a typed response.
node classify {
type: ai
label: "Classify intent"
model: "google/gemini-2.5-flash"
kind: object
schema: @json {
{ "type": "object", "required": ["intent"], "properties": { "intent": { "type": "string" } } }
}
prompt: @ts {
return `Classify the intent of: ${context.nodes.root.input.message}`
}
}Switch node: route execution based on a TypeScript expression.
node route {
type: switch
label: "Route by urgency"
cases: ["urgent", "normal", "low"]
router: @ts {
const body = context.nodes.root.output.body.toLowerCase()
if (body.includes("urgent")) return "urgent"
if (body.length > 500) return "normal"
return "low"
}
}
flow {
root -> route
route -["urgent"]-> handle_urgent
route -["normal"]-> handle_normal
route -["low"]-> handle_low
}Next steps
- Quickstart: get a workflow running in 5 minutes
- Language: learn the
.swirlsfile format - Platform: run locally or deploy to the cloud