SWIRLS_
Language

Swirls Language

Learn to build workflows with .swirls files.

.swirls files are the primary way to define workflows in Swirls. They use a domain-specific language (DSL) designed for declaring forms, webhooks, schedules, graphs, and triggers in a single, readable file.

Why .swirls files

  • Versionable. Store workflows alongside your code. Review changes in pull requests, roll back with git.
  • Declarative. Describe what your workflow does, not how to build it in the Portal UI.
  • Type-safe. The LSP parses your .swirls file and provides IntelliSense inside embedded @ts { } blocks. The context object is fully typed against your node schemas.
  • Single source of truth. One file captures resources, graph structure, node code, and trigger wiring together.

Editor support

Install the VS Code extension to get:

  • Completions for keywords, resource names, and node types
  • Hover documentation for fields and blocks
  • Inline diagnostics for syntax errors and unknown references

The LSP also types the context object inside @ts { } blocks based on the schemas defined in the same file.

A complete example

The example below defines a form, a graph with one code node, and a trigger that connects them.

form contact {
  label: "Contact"
  enabled: true
  schema: @json {
    {
      "type": "object",
      "required": ["email"],
      "properties": { "email": { "type": "string" } },
      "additionalProperties": false
    }
  }
}

graph process_contact {
  label: "Process Contact"

  root {
    type: code
    label: "Entry"
    inputSchema: @json {
      {
        "type": "object",
        "required": ["email"],
        "properties": { "email": { "type": "string" } },
        "additionalProperties": false
      }
    }
    outputSchema: @json {
      {
        "type": "object",
        "required": ["email"],
        "properties": { "email": { "type": "string" } },
        "additionalProperties": false
      }
    }
    code: @ts {
      const email = context.nodes.root.input.email ?? ""
      return { email: email.toLowerCase() }
    }
  }
}

trigger on_contact {
  form:contact -> process_contact
  enabled: true
}

When on_contact fires (a contact form submission), Swirls runs process_contact with the form payload as input to the root node.

Language sections

  • Syntax: Comments, identifiers, values, and @ts / @json / @sql blocks.
  • Resources: Forms, webhooks, and schedules.
  • Graphs: Graph blocks, node declarations, and edges.
  • Node types: Configuration fields for each node type.
  • Triggers: Wiring resources to graphs.
  • Context: The context object available inside @ts { } blocks.
  • Persistence: Streams and persistence conditions.
  • Reviews: Human-in-the-loop review nodes.

On this page