Lane Diagrams
Lane diagrams show event communication between actors. They're ideal for collaborative sessions and non-technical stakeholders.
What Lane Diagrams Show
- Actors as vertical lanes
- Events as arrows between lanes
- Actions as text within lanes
- Time flowing top to bottom
Basic Example
From this EventFlow:
machine: @order
scenario: checkout process
on> :checkout from @customer
validate cart
emit :payment_request to @payment
on :payment_success from @payment
order moves to #paid
emit :confirmation to @customerGenerates:
┌─────────────┬─────────────┬─────────────┐
│ @customer │ @order │ @payment │
├─────────────┼─────────────┼─────────────┤
│ │ │ │
│ :checkout │ │ │
│ ────────────┼──> │ │
│ │ validate │ │
│ │ cart │ │
│ │ │ │
│ │ :payment_ │ │
│ │ request │ │
│ │ ────────────┼──> │
│ │ │ │
│ │ │ (processes) │
│ │ │ │
│ │ :payment_ │ │
│ │ success │ │
│ │ <───────────┼─────────────│
│ │ │ │
│ :confirmation │ │
│ <───────────┼─────────────│ │
│ │ │ │
└─────────────┴─────────────┴─────────────┘Lane Inference
Lanes are automatically created from @actor references in your code:
on> :checkout from @customer // Creates @customer lane
emit :payment_request to @payment // Creates @payment lane
emit :notify to @admin // Creates @admin laneLane order is determined by first appearance.
Reading Lane Diagrams
Arrows
────────> Event sent (request)
<──────── Event received (response)Time
Time flows top to bottom. Events higher up happen before events below.
Actions
Text within a lane represents actions that machine performs:
│ @order │
│ │
│ validate │ ← Action
│ cart │
│ │
│ calculate │ ← Action
│ total │Multi-Machine Systems
Lane diagrams excel at showing multi-machine interactions:
system: e-commerce
machine: @order
on> :checkout from @customer
emit :check_inventory to @inventory
emit :process_payment to @payment
machine: @inventory
on :check_inventory from @order
? stock available
emit :inventory_ok to @order
machine: @payment
on :process_payment from @order
? payment successful
emit :payment_ok to @orderGenerates:
┌───────────┬───────────┬───────────┬───────────┐
│ @customer │ @order │@inventory │ @payment │
├───────────┼───────────┼───────────┼───────────┤
│ :checkout │ │ │ │
│ ──────────┼──> │ │ │
│ │ │ │ │
│ │ :check_ │ │ │
│ │ inventory │ │ │
│ │ ──────────┼──> │ │
│ │ │ │ │
│ │ :process_ │ │ │
│ │ payment │ │ │
│ │ ──────────┼───────────┼──> │
│ │ │ │ │
│ │ │(checking) │(processing)
│ │ │ │ │
│ │:inventory_│ │ │
│ │ok │ │ │
│ │<──────────┼───────────│ │
│ │ │ │ │
│ │:payment_ok│ │ │
│ │<──────────┼───────────┼───────────│
│ │ │ │ │
└───────────┴───────────┴───────────┴───────────┘Parallel Events
When multiple events are emitted simultaneously:
on> :checkout from @customer
emit :check_payment to @payment // Parallel
emit :check_fraud to @fraud // Parallel
emit :check_inventory to @inventory // ParallelShown at the same vertical level:
│ @order │ @payment │ @fraud │@inventory │
│ │ │ │ │
│ :check_pay │ │ │ │
│ ────────────┼──> │ │ │
│ :check_fraud│ │ │ │
│ ────────────┼────────────┼──> │ │
│ :check_inv │ │ │ │
│ ────────────┼────────────┼────────────┼──> │Conditional Flows
Guards and conditions can be shown:
on :payment_result from @payment
? payment successful
emit :ship_order to @warehouse
otherwise
emit :payment_failed to @customer│ │:payment_result │
│ │<─────────────────────────│
│ │ │
│ │ ┌─── if successful ────┐ │
│ │ │ │ │
│ │ │ :ship_order │ │
│ │ │ ────────────────────>│→@warehouse
│ │ │ │ │
│ │ └──────────────────────┘ │
│ │ ┌─── otherwise ────────┐ │
│ │ │ │ │
│:payment_ │ │ │ │
│failed │ │ │ │
│<────────────┼─┘ │ │
│ │ │ │Use Cases for Lane Diagrams
Event Storming Sessions
Print lane diagrams for collaborative design:
eventflow diagram order.flow --type=lane --format=pdfStakeholder Communication
Non-technical stakeholders can understand who does what:
- "Customer sends checkout"
- "Order asks Payment to process"
- "Payment responds with success"
API Documentation
Show external integrations:
│ External │ @order │ @stripe │
│ Client │ │ (webhook) │
├─────────────┼─────────────┼────────────┤
│ POST /order │ │ │
│ ────────────┼──> │ │
│ │ │ │
│ │ creates │ │
│ │ payment │ │
│ │ intent │ │
│ │ ────────────┼──> │
│ │ │ │
│ 202 Accepted│ │ │
│ <───────────┼─────────────│ │
│ │ │ │
│ │ │ webhook │
│ │ │ callback │
│ │ <───────────┼────────────│Best Practices
Limit Lanes
Too many lanes become hard to read. Consider splitting into multiple diagrams:
# Instead of one huge diagram
eventflow diagram system.flow
# Split by scenario
eventflow diagram system.flow --scenario="checkout"
eventflow diagram system.flow --scenario="returns"Name Events Clearly
Event names appear on arrows - make them readable:
// Good - clear in diagram
emit :payment_authorization_requested to @payment
emit :order_confirmation_sent to @customer
// Avoid - unclear in diagram
emit :req to @payment
emit :msg to @customerGroup Related Actors
In complex systems, group related actors:
┌────────────────────────┬───────────────────────┐
│ Customers │ Backend │
├───────────┬────────────┼───────────┬───────────┤
│@web_client│@mobile_app │ @order │ @payment │