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.