Why Are Event and Action Different Types?

It is tempting to think an Event and an Action are the same kind of thing — both are "stuff that happens around a transition." They are not, and conflating them is the most common source of confusion. They are opposite ends of one edge:

Event Action

Input — arrives from the outside world.

Output — emitted by the machine.

You push it: machine.transition(event).

You receive it: transition.getAction().

The cause ("payment succeeded").

The effect ("charge the card", "ship the parcel").

Often a bare signal with no data.

Usually carries data the downstream doer needs.

Past tense — it already happened.

Imperative — go do this.

A quick test when you are unsure which one you are holding: ask who produced it. If the outside world produced it (a callback fired, a timer elapsed, a user clicked), it’s an Event. If the machine produced it as a consequence of moving, it’s an Action.

What the separation buys you

Keeping them as separate type parameters buys real things:

  1. Compile-time direction safety. transition(EventT) cannot accept an Action, so you can never accidentally feed an output back in as an input.

  2. Different shapes. An event like PaymentSucceeded is a bare signal; the action it triggers, ShipParcel(address), needs a payload — and that payload often comes from the State, not the event (the ★ edge in the example). Forcing both into one type would lose that.

  3. Decoupling decision from doing. The machine decides and emits a command — it never runs the command itself. Some other code (the call site, a listener, or a worker on another host) interprets the action and performs it (see Handling Actions). That separation keeps the machine pure and is what makes the async pattern possible — the machine never blocks on the side effect.

The Action payload is optional. A transition that emits nothing — sb.transitionTo(nextState) — is perfectly valid (the PaymentFailed → Cancelled edge). If your machine never emits actions, give ActionT a wildcard: Hydra<MyState, MyEvent, ?>.