Workflow Orchestration Markup Language

If you can read HTML, you can use WOML to automate anything, literally anything.

WOML is an open, executable format for durable workflow applications. Write workflow structure like HTML, use JavaScript whenever you need real logic, and run it anywhere—with reliable execution, deployment, inspection, control, and recovery built in.

curl -fsSL https://woml.org/install | bash

What WOML is

Workflow applications as readable documents.

WOML is an HTML-inspired language and self-hosted runtime for durable automation. Open a .woml file and its triggers, steps, decisions, approvals, and execution policy read from top to bottom. Run that same file and WOML turns it into an operational workflow backed by real JavaScript and a durable engine.

The source is not an export of the workflow. It is the workflow.

How WOML works

From readable workflow to durable execution.

Write the structure in a .woml file, start it from a trigger or command, and let WOML execute each step while preserving the decisions and results needed to inspect, control, and continue the run.

workflow.womlWriting workflow
Readable sourceReal JavaScriptOne executable document
TerminalWaiting for source
$
ValidateActivateExecute durably

The document you write is the workflow WOML validates, activates, and executes.

The idea in one file

The graph gets crowded. The source stays clear.

A visual builder looks clean in the demo and turns into spaghetti in production. The same workflow in WOML is just text, linear, searchable, and diffable no matter how big it gets. Growth adds lines to a file, not tangles to a canvas.

process-order.womlwriting WOML
<woml>
  <workflow id="process-order">
    <triggers>
      <webhook id="order" path="/orders" auth="none" />
    </triggers>
    <steps>
      <step id="normalize">
        <script>return { total: context.payload.total };</script>
      </step>
      <parallel id="checks">
        <step id="stock">
          <script>return { available: true };</script>
        </step>
        <step id="risk">
          <script>return true;</script>
        </step>
        <step id="fraud">
          <script>return { clear: true };</script>
        </step>
      </parallel>
      <choose id="route">
        <when test="{{context.steps.risk}}">
          <step id="fulfill">
            <script>return { status: "accepted" };</script>
          </step>
          <result value="{{context.steps.fulfill}}" />
        </when>
        <otherwise>
          <step id="reject">
            <script>return { status: "rejected" };</script>
          </step>
          <result value="{{context.steps.reject}}" />
        </otherwise>
      </choose>
      <parallel id="aftercare">
        <step id="notify">
          <script>return { sent: true };</script>
        </step>
        <step id="audit">
          <script>return { recorded: true };</script>
        </step>
        <step id="metrics">
          <script>return { counted: true };</script>
        </step>
      </parallel>
      <step id="finish">
        <script>return context.steps.route;</script>
      </step>
      <fork id="distribution" join="all">
        <branch id="emailLane">
          <step id="emailReceipt">
            <script>return { queued: true };</script>
          </step>
          <step id="trackEmail">
            <script>return { tracked: true };</script>
          </step>
        </branch>
        <branch id="warehouseLane">
          <step id="reserveShipment">
            <script>return { reserved: true };</script>
          </step>
          <step id="updateInventory">
            <script>return { updated: true };</script>
          </step>
        </branch>
        <branch id="analyticsLane">
          <step id="publishMetric">
            <script>return { published: true };</script>
          </step>
          <step id="archiveOrder">
            <script>return { archived: true };</script>
          </step>
        </branch>
      </fork>
    </steps>
  </workflow>
</woml>
Visual workflow builderWaiting for workflow structure
With every node, readability drops and maintenance multiplies.

Beyond the connector catalog

Your workflow shouldn't stop at “integration unavailable.”

Sooner or later, every no-code platform tells you "not supported" and your automation stops at the edge of someone else's roadmap. WOML has no edge. Any API, any library, any custom logic becomes a capability you define yourself and call like it shipped with the tool. Your workflow's limits are yours, not the platform's.

local module · explicit import
<woml>
  <imports>
    <module name="googleMaps" from="./google-maps.ts" />
  </imports>

  <workflow id="locate-delivery">
    <triggers>
      <webhook
        id="delivery"
        path="/deliveries"
        method="POST"
        auth="bearer"
        secret="{{secrets.WEBHOOK_TOKEN}}"
      />
    </triggers>

    <steps>
      <step id="normalize">
        <script>
          return { address: context.payload.address.trim() };
        </script>
      </step>

      <step id="geocode">
        <script>
          return services.googleMaps.geocode(
            context.steps.normalize.address,
            secrets.GOOGLE_MAPS_API_KEY
          );
        </script>
      </step>

      <step id="result">
        <script>return context.steps.geocode;</script>
      </step>
    </steps>
  </workflow>
</woml>
Visual workflow builderChoose the next node
    Google Maps isn't available yet.

    Request this integration and wait for a future release. We'll notify you when it's ready.

    Waiting for the platform
    Only available integrations become nodes. Google Maps never reaches the canvas, while the WOML files beside it already contain the missing capability.

    In this workflow, google-maps.ts becomes services.googleMaps. The source names the dependency, the graph keeps its vertical sequence, and the third step no longer depends on someone else's integration roadmap.

    Not just a syntax

    One file. The whole workflow system.

    WOML keeps the definition, execution, and operation of a workflow connected. Describe it once in a readable .woml file, then let the engine run it and the runtime give you the controls to operate it reliably.

    Source of truthWOML

    One readable, executable definition.

    1. 01Describe

      Readable language

      Describe workflow structure like a document. Use JavaScript wherever the logic needs real code.

    2. 02Execute

      Durable engine

      Execute the same file as a reliable workflow application—not as a diagram or static configuration.

    3. 03Operate

      Operational runtime

      Deploy, inspect, control, and recover workflows through a runtime that understands their definition.

    One file, many responsibilities

    The same artifact remains useful from the first idea to production operation.

    • ProgramWhat executes
    • Architecture diagramHow work connects
    • Automation configurationWhat the workflow needs
    • Execution policyHow it runs
    • DocumentationWhat people understand
    • Shared artifactWhat developers and AI agents create, review, and run

    The diagram, the code, the configuration, and the production workflow never drift apart. In WOML, they are the same artifact.

    Built to grow

    Start with one workflow. Grow into a system.

    Begin with one .woml file and one useful automation. As the work expands, add decisions, concurrent work, approvals, state, and services inside the workflow—or compose it with other WOML workflows that return results, continue independently, or react to durable events. The system gets bigger without hiding its structure.

    Primary workflowcustomer-onboarding.woml
    1. 01
      TriggerNew customer
    2. 02
      Validate customerCheck required data
    3. 03
      Parallel checksCall two workflows for results
    4. 04
      Choose onboarding routeBranch from customer context
    5. 05
      Wait for approvalPause for a durable decision
    6. 06
      Store progressKeep durable workflow state
    7. 07
      Coordinate workflowsStart work and publish an event
    Call · returns resultrisk-assessment.woml
    Risk score returned
    Call · returns resultidentity-verification.woml
    Identity result returned
    Start · independentwelcome-sequence.woml
    Continues on its own
    Event · customer.readycrm-sync.woml
    Subscriber activated
    Event · customer.readycustomer-analytics.woml
    Subscriber activated

    Scale by adding structure when it belongs together, and new workflows when it does not.

    A workflow can call another for a result, start it independently, or publish an event to multiple subscribers. Every part remains a readable .woml document.

    Executable examples

    See these applications take shape as readable source.

    Explore complete .woml files that combine workflow structure, JavaScript, services, state, decisions, and human input.

    01.woml
    BusinessParallelApproval

    Orchestrate high-value order fulfillment

    Validate orders, check inventory and fraud concurrently, route risky purchases to a durable human decision, and publish one auditable outcome.

    View example
    02.woml
    AI agentTelegramState

    Build a Telegram support agent with durable memory

    Wrap an AI model with normalized messages, durable conversation memory, supervised replies, retries, and an asynchronous human escalation workflow.

    View example
    03.woml
    DataFor eachPostgreSQL

    Import thousands of customers with durable per-row progress

    Validate a dataset, process up to ten thousand customers with bounded concurrency, upsert valid rows, and preserve ordered results.

    View example
    04.woml
    Human operationsApprovalStorage

    Automate expense compliance without hiding the human decision

    Apply deterministic expense policy, archive receipts, share one approval across providers, and publish the accounting decision.

    View example
    05.woml
    BackendWebhookIdempotency

    Process payment webhooks into an idempotent ledger

    Turn repeated payment deliveries into an idempotent ledger, exact event routing, and independently durable fulfillment work.

    View example
    06.woml
    DevOpsApprovalModules

    Put a durable safety gate in front of production deployments

    Run parallel preflight checks, require production approval, call your infrastructure API, verify health, and roll back explicitly.

    View example
    07.woml
    CommunicationEventsSwitch

    Run one incident assistant across Slack, Telegram, and Discord

    Handle Slack, Telegram, and Discord with one provider-independent incident flow and broadcast critical events to responder workflows.

    View example
    08.woml
    ContentAIFork

    Research, approve, and distribute content from one workflow

    Research and draft with AI, wait for editorial approval, then publish through independent multi-step channel branches.

    View example
    09.woml
    LocalSQLiteSchedule

    Generate a local operations report with no cloud account

    Query local SQLite, calculate metrics in JavaScript, generate CSV, and store a versioned report without a cloud account.

    View example
    10.woml
    PlatformWorkflow callsAI

    Build a multi-workflow document processing API

    Expose one product endpoint and route tenant jobs to independently durable invoice, contract, and summarization workflows.

    View example
    11.woml
    IntervalParallelHTTP

    Monitor services in parallel

    Check several live endpoints on one durable interval, then turn their individual results into one readable health report.

    View example
    12.woml
    WebhookApprovalDurability

    Hold an order for human approval

    Accept a validated order webhook, pause durably for a decision, and make the approved and rejected paths explicit.

    View example
    13.woml
    Local moduleAPISecrets

    Add Google Maps as a local service

    Create the integration your workflow needs in TypeScript, import it as a service, and keep the orchestration readable in WOML.

    View example
    14.woml
    EventsSQLiteValidation

    Record customer events in SQLite

    Subscribe to an internal event, validate its payload, and write an auditable record through WOML’s supervised database service.

    View example

    WOML vs Alternatives

    Most workflow tools optimize for either visual simplicity or engineering power. WOML is designed to keep both: readable workflow structure for the whole team and real JavaScript whenever the automation needs it.

    ToolHow you build workflowsReadable by the whole teamSelf-hostedLogic without a ceiling
    WOMLMarkup + JavaScript✅ Clear, document-like structure✅ Inline JavaScript, modules, and services
    n8nVisual canvas⚠️ Easy at first; harder as the canvas grows⚠️ Code and custom nodes
    ZapierVisual canvas⚠️ Friendly for smaller automations⚠️ Platform actions and code steps
    TemporalCode with language SDKs❌ Primarily readable by engineers✅ Full programming languages
    AWS Step FunctionsJSON/YAML with ASL❌ Requires ASL and AWS knowledge⚠️ Extended through AWS services and functions
    Apache AirflowPython DAGs❌ Primarily readable by Python/data teams✅ Python and operators

    WOML's difference: it combines document-like readability, self-hosted ownership, and full JavaScript flexibility in the same workflow file.

    One readable file. A durable runtime behind it.

    Get started Read the documentation