a general theory of reactivity, visualized

Promises, streams, signals and behaviors, all on one map.

Kris Kowal's gtor sorts reactive primitives by a few questions: one value or many, here now or arriving later, getter or setter. These pages run small, real implementations of each primitive in your browser. The reactor log at the bottom shows every get, set, acknowledgement, push and poll as it happens.

Two axes, two sides
Singular
Plural
Spatial
Temporal
temporal·plural
Stream
WriterReadermany values, arriving over timereader.next() → Promise<{value, done}>

Rotate an array from the space axis onto the time axis and it becomes a stream. A reader is an async iterator, a writer an async generator.

Rotate an array onto the time axis

“If you rotate an array from the space axis to the time axis, it would become a stream. The order is important, and every value is significant.”

Array<number>
space →
3
1
4
1
5
9
The twelve interfaces
InterfaceRoleNumberAxis
ValueValueSingularSpatial
GetterGetterSingularSpatial
SetterSetterSingularSpatial
ArrayValuePluralSpatial
IteratorGetterPluralSpatial
GeneratorSetterPluralSpatial
DeferredValueSingularTemporal
PromiseGetterSingularTemporal
ResolverSetterSingularTemporal
StreamValuePluralTemporal
ReaderGetterPluralTemporal
WriterSetterPluralTemporal
01 · Spatial→
Iterators

Lazy beats eager. Pull one value at a time through map, filter and reduce, and watch no array ever get built.

02 · Spatial→
Generator functions

Step through a generator paused at yield. next, throw and return send information back to the producer.

03 · Singular · temporal→
Promises & resolvers

A getter for one value in the future. Subscribe before or after it resolves; race resolvers and only one wins.

04 · Singular · temporal→
Tasks

A promise that only one consumer may observe, so it can be cancelled. Fork it, cancel the forks, watch the work stop.

05 · Singular · temporal→
Async functions

A generator plus promises becomes async/await. Step the trampoline that resumes your function.

06 · Plural · temporal→
Queues & semaphores

A queue where you can get before you put. Then use one as a non-blocking semaphore over a connection pool.

07 · Plural · temporal→
Streams & pressure

Two promise queues make a buffer: values go forward, acks come back. Tune producer and consumer rates to see pressure.

08 · Plural · temporal→
Async generators

Iteration<Promise<T>> or Promise<Iteration<T>>? Run an async generator and watch await yield wait for the reader.

09 · Time series→
Signals & observables

Discrete values pushed to any number of observers, with no back pressure. Late subscribers miss what came before.

10 · Time series→
Behaviors

Continuous values with no resolution of their own. The consumer decides when to poll.

11 · Cases→
Progress & ETA

Progress and ETA: a discrete signal per value, and a continuous behavior for smooth animation.

12 · Cases→
Choose a primitive

Broadcast or unicast? Cancelable? Push, pull or pressure? Answer a few questions to find the right primitive.