Workflow Orchestration Markup Language

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

Describe triggers, steps, branches, approvals, and runtime policy in familiar HTML-inspired markup, then write the work in real JavaScript. WOML runs it through a durable, self-hosted engine built for workflows that need to survive retries, restarts, and long-running execution.

npm install --global woml-cli

What WOML is

The workflow has a shape. Keep that shape visible.

Visual tools make small automations approachable, but large canvases become difficult to review and reuse. Code-first engines are powerful, but the workflow shape often disappears inside an SDK. WOML keeps structure in readable markup and business logic in real JavaScript.

The idea in one file

The graph gets crowded. The source stays clear.

Each WOML tag adds a node to the canvas. As the workflow grows, connections compete for space while the source remains an ordered document you can search, diff, and review.

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 canvasWaiting for workflow structure
Every node adds another position and connection to navigate.

Why WOML

Readable when you write it. Dependable when you run it.

01

Read the workflow as a document

Triggers, steps, branches, approvals, and runtime policy stay visible without tracing framework calls or navigating a canvas.

02

Use JavaScript without hiding the flow

Write normal expressions, loops, modules, Fetch, and managed service calls inside a step. WOML handles the durable structure around that code.

03

Review automation in Git

A .woml file is ordinary text with meaningful diffs. Teams can review workflow changes through the same pull-request process as application code.

04

Own the runtime and the data

Run WOML on your machine or infrastructure. Durable history stays in a state store you control instead of a required hosted automation platform.

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