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 mocksEach 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
{
"id": "order",
"initial": "idle",
"states": {
"idle": {
"on": {
"CHECKOUT": {
"target": "awaiting_payment",
"guards": ["isCartNotEmpty"],
"actions": ["emitPaymentRequest"]
}
}
}
}
}Compare this to EventFlow:
on :checkout from @customer (api)
? cart is not empty
order moves to #awaiting_payment
emit :payment_request to @paymentHow EventFlow Solves This
Single Source of Truth
One file defines everything:
// 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_paymentReadable by Everyone
Non-developers can read and validate the logic:
? payment is verified
order moves to #confirmed
emit :confirmation_email to @customer
otherwise
order moves to #payment_failed
emit :retry_payment to @customerProduct managers can verify: "Yes, that's exactly what should happen."
Self-Documenting Tests
Every scenario with assertions is an executable test:
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_paymentRun with:
eventflow test order.flowAuto-Generated Diagrams
Visualizations are generated from the same source:
eventflow diagram order.flow --type=lane
eventflow diagram order.flow --type=stateNo 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:
machine: @order
// Only @order can change order state
machine: @payment
// Only @payment can change payment stateMessage Passing
Machines communicate through events, not shared state:
// @order sends to @payment
emit :payment_request to @payment
// @payment responds
emit :payment_success to @orderAutomatic Correlation
The runtime handles event routing automatically:
on :checkout from @customer (api)
emit :payment_request to @payment // Starts conversation
on :payment_success from @payment // Automatically routed back
order moves to #paidNo 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.
# In your deployment script
eventflow export *.flow --format=html --output=docs/
# Deploy docs/ to your internal documentation siteEvery 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":
- Open the existing flow
- See the flow in the diagram
- Write the new scenario
- 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