Quick Start

Get up and running with ReactiveESP32 in 5 minutes!

Your First Reactive Program

Let’s create a simple 3 reactive node chain to notice how ReactiveESP32 works (SignalComputed ⟶ and Effect).

Step 1: Include the library

#include <ReactiveESP32.h>
using namespace RxESP32;

Step 2: Create reactive signals

// Signal (source of data): current number
Signal<int> number(0);

// Computed (derived data): double the number
Computed<int> doubled([]() { return number.get() * 2; });

// Effect (side effect): print the doubled value
Effect<>([]() { Serial.printf("Doubled: %d\n", doubled.get()); });

This would create the following reactive graph:

graph LR
   S[Signal]
   C[Computed]
   E[Effect]
   S --> C
   C --> E

Step 3: Setup and loop

void setup() {
   Serial.begin(115200);

   // Start the ReactiveESP32 dispatcher
   if (!Dispatcher::start()) {
      Serial.println("Failed to start ReactiveESP32 Dispatcher!");
      while (true)
         delay(1000);
   }
}

void loop() {
   static int count = 1;
   number.set(count++);
   delay(1000);
}

Complete Example

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <ReactiveESP32.h>
using namespace RxESP32;

// Signal (source of data): current number
Signal<int> number(0);

// Computed (derived data): double the number
Computed<int> doubled([]() { return number.get() * 2; });

// Effect (side effect): print the doubled value
Effect<>([]() { Serial.printf("Doubled: %d\n", doubled.get()); });

void setup() {
   Serial.begin(115200);

   // Start the ReactiveESP32 dispatcher
   if (!Dispatcher::start()) {
      Serial.println("Failed to start ReactiveESP32 Dispatcher!");
      while (true)
         delay(1000);
   }
}

void loop() {
   static int count = 1;
   number.set(count++);
   delay(1000);
}

Serial output:

Doubled: 2
Doubled: 4
Doubled: 6
Doubled: 8
...

How It Works

1. Signals store state

Signal<int> number(0);

Think of Signals as reactive variables that notify when they change.

2. Computed derives new state

Computed<int> doubled([]() { return number.get() * 2; });

Computed automatically re-runs when dependencies change (number).

3. Effects handle side effects

Effect<>([]() { Serial.printf("Doubled: %d\n", doubled.get()); });

Effects automatically re-execute when dependencies change (doubled).

Key Concepts

Reactive Updates

When you update a signal:

number.set(20);   // 1. Signal updates
                  // 2. Computed re-evaluates
                  // 3. Effects re-run automatically

All dependents update automatically in the correct order!

Dependency Tracking

ReactiveESP32 tracks dependencies automatically when you call .get() inside Computed/Effect:

Computed<int> doubled([]() {
    return count.get() * 2; // Automatically tracks `count`
});

Effect<>([]() {
    Serial.println(doubled.get()); // Automatically tracks `doubled`
});

No manual subscriptions needed!

Next Steps

  • Core Concepts - Understand Signals, Computed, and Effects before diving deeper

  • Core - Core API reference