Skip to content

Why EventFlow? ​

The Problem with Traditional Approaches ​

Documentation Drift ​

In traditional development, documentation and code inevitably diverge:

Week 1:  Docs ←→ Code  (in sync)
Week 4:  Docs ... Code (starting to drift)
Week 12: Docs ??? Code (what does this even do?)

The Cascade of Drift ​

When documentation drifts from code, problems cascade through the organization:

  • Developers update code but forget to update docs
  • Product managers write requirements that never make it to implementation
  • QA writes tests based on outdated specs ← This breaks everything
  • Support teams answer questions from wrong documentation
  • New developers learn the wrong behavior during onboarding
  • Auditors review inaccurate process descriptions

Each person trusts a different "source of truth" - and none of them are actually true.

The Translation Problem ​

Every translation step introduces errors:

Business Requirement → Technical Spec → Code → Tests
         ↓                   ↓           ↓       ↓
    "User can checkout"  PRD doc     if/else   mocks

Each arrow is a potential source of misunderstanding.

State Machine Complexity ​

Traditional state machine implementations require:

  • Complex configuration files (JSON/YAML)
  • Verbose class definitions
  • Separate test suites
  • Manual diagram maintenance
json
{
  "id": "order",
  "initial": "idle",
  "states": {
    "idle": {
      "on": {
        "CHECKOUT": {
          "target": "awaiting_payment",
          "guards": ["isCartNotEmpty"],
          "actions": ["emitPaymentRequest"]
        }
      }
    }
  }
}

Compare this to EventFlow:

flow
on :checkout from @customer (api)
  ? cart is not empty
    order moves to #awaiting_payment
    emit :payment_request to @payment

How EventFlow Solves This ​

Single Source of Truth ​

One file defines everything:

flow
// order.flow - This IS the documentation, tests, and runtime

machine: @order

scenario: checkout flow

  given:
    @customer is logged in
    cart has items

  on :checkout from @customer (api)
    ? cart is not empty
      order moves to #awaiting_payment
      emit :payment_request to @payment

  expect:
    = order is in #awaiting_payment

Readable by Everyone ​

Non-developers can read and validate the logic:

flow
? payment is verified
  order moves to #confirmed
  emit :confirmation_email to @customer
otherwise
  order moves to #payment_failed
  emit :retry_payment to @customer

Product managers can verify: "Yes, that's exactly what should happen."

Self-Documenting Tests ​

Every scenario with assertions is an executable test:

flow
scenario: expired cart items

  given:
    cart has expired items

  on :checkout from @customer (api)
    ? cart has expired items
      emit :cart_invalid to @customer

  expect:
    = @customer received :cart_invalid
    = order is not in #awaiting_payment

Run with:

bash
eventflow test order.flow

Auto-Generated Diagrams ​

Visualizations are generated from the same source:

bash
eventflow diagram order.flow --type=lane
eventflow diagram order.flow --type=state

No manual diagram maintenance. Diagrams always match the code.

The Actor Model Advantage ​

EventFlow is built on actor model principles:

Isolated State ​

Each machine manages its own state:

flow
machine: @order
  // Only @order can change order state

machine: @payment
  // Only @payment can change payment state

Message Passing ​

Machines communicate through events, not shared state:

flow
// @order sends to @payment
emit :payment_request to @payment

// @payment responds
emit :payment_success to @order

Automatic Correlation ​

The runtime handles event routing automatically:

flow
on :checkout from @customer (api)
  emit :payment_request to @payment   // Starts conversation

on :payment_success from @payment     // Automatically routed back
  order moves to #paid

No correlation IDs to manage. No message queues to configure.

Event Sourcing Built-In ​

Every machine instance is an aggregate:

┌─────────────────────────────────────────────────────────────┐
│                      Event Store                            │
├─────────────────────────────────────────────────────────────┤
│  aggregate_id  │  event_type       │  data          │ seq  │
│  ──────────────┼───────────────────┼────────────────┼───── │
│  order-123     │  :checkout        │  {customer}    │  1   │
│  order-123     │  :payment_success │  {txn_id}      │  2   │
│  order-123     │  :shipped         │  {tracking}    │  3   │
└─────────────────────────────────────────────────────────────┘

State is rebuilt by replaying events. Full audit trail. Time-travel debugging.

Living Documentation for Everyone ​

Host It, Share It, Trust It ​

EventFlow's interactive HTML output can be hosted anywhere - Confluence, SharePoint, or simple static hosting. Non-developer team members can check current system behavior whenever they need:

  • Product Manager: "How does the payment flow work right now?" → Open the diagram, see it
  • Designer: "In which states do we show messages to users?" → Check the flow
  • QA: "What are the edge cases?" → Review the test scenarios
  • Support: "Why did this order fail?" → Trace through the states

No meetings needed. No asking developers. Always up-to-date documentation.

In the old world, the "real documentation" was always the code itself - only developers could read it. In EventFlow, the .flow file is both code and documentation - everyone can read it.

Automate with CI/CD ​

Trigger interactive HTML generation in your CI/CD pipeline on every production deploy. Documentation stays up-to-date automatically - no manual steps, no drift.

bash
# In your deployment script
eventflow export *.flow --format=html --output=docs/
# Deploy docs/ to your internal documentation site

Every deploy refreshes the documentation. The diagrams always reflect what's actually running in production.

No AI Doc Generation Needed ​

Some teams invest in expensive AI-powered tools to:

  • Generate documentation from code
  • Update docs when code changes
  • Keep specs in sync with implementation
  • Extract API documentation automatically

EventFlow eliminates this need entirely. The .flow file IS the documentation - there's no generation step, no sync issues, no AI costs. The same file that runs in production is the file everyone reads.

Build on What Exists ​

New feature development starts with understanding what exists. In EventFlow, you can see current flows and say "we can add a branch right here":

  1. Open the existing flow
  2. See the flow in the diagram
  3. Write the new scenario
  4. Watch the diagram update in real-time

Feature meetings become concrete, not abstract - everyone looks at the same visualization. Product managers can point to a specific state and say "after this, we need to check inventory." Developers can immediately write the guard.

When to Use EventFlow ​

EventFlow is ideal for:

  • Business workflows with clear state transitions
  • Multi-step processes involving multiple actors
  • Event-driven architectures with async communication
  • Collaborative teams where non-developers need to understand the logic
  • Regulated industries requiring audit trails

EventFlow may not be the best fit for:

  • Simple CRUD operations without complex state
  • Real-time computation (use purpose-built tools)
  • Low-level system programming

Released under the MIT License.