Mental model

tflo vs React state, Signals, RxJS, XState

Where does authority over time live?

Every reactive tool has an implicit answer to this question. The answer shapes what questions you can ask, what bugs you can prevent, and what you can prove after the fact.

RxJS: time = when a value arrived at the scheduler. The debounceTime, bufferTime, windowTime, and throttleTime operators all read the wall clock at call time. The scheduler owns time.

XState: time = how long you have been in a state, measured from the machine's own wall clock. The after transitions use setTimeout under the hood. The machine owns time.

tflo: time = what the record itself says happened, in what order, at what instant — and that clock is an injected input, not a runtime assumption. The data owns time. The engine is a function of the event log, the rule, and a pluggable clock; given the same three inputs you get the same output, always.

Side by side

Tool Mental model Best at Models time? History & time-travel
React state Current snapshot, manual propagation Rendering now No — only "now" None
Signals (JS reactivity) Current snapshot, automatic fine-grained propagation Reactivity / derived values No — still only "now" None
RxJS Values over processing-time streams Async composition, transport Time = arrival Ephemeral, no replay
XState Finite states + events Lifecycle / orchestration Time = wall-clock delay Per-entity snapshot, no event-time replay
tflo Timestamped events + temporal rules What happened, in what order, within what time, and what did not Time = first-class axis of the data Event-sourced: replay, what-if, roll back/forward

Disambiguation: two things called "signal"

Important: "Signals" in this page means JS reactivity signals — the Preact, Angular, Solid, and TC39 proposal model for fine-grained reactive current values. It does not mean tflo's typed Signal<Mode, Payload> output type, which is a timestamped, typed verdict emitted by a tflo detector. They share a word and nothing else.

JS Signals are reinforcement, not competition

The TC39 Signals proposal explicitly defers async and time: the proposal text notes that "async is omitted for now." This is a deliberate scope decision, not an oversight. Signals standardize the current-value layer and leave the temporal layer to be composed on top.

tflo and JS signals compose cleanly: tflo runs its temporal rule over a timestamped event log and emits a verdict; a JS signal holds the latest verdict for rendering. Each does what it is good at. Neither is a replacement for the other.

Ergonomics boundaries

Pick the tool that matches the question you are actually asking:

Next: Event-time vs processing-time — why the assumption "time = now" is invisible until it isn't — or Provable temporal logic for the testability story. See also Positioning for the broader project framing.