SkillAgentSearch skills...

Reaction

A lightweight, header-only, high-performance reactive programming framework for C++20.

Install / Use

/learn @lumia431/Reaction
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Reaction: Modern C++ Reactive Programming Framework

🇨🇳 中文文档 | 🇬🇧 English

C++20 Header-only CMake ReactiveX TMP MVVM

Reaction is a blazing-fast, modern C++20 header-only reactive framework that brings React/Vue-style dataflow to native C++ – perfect for UI Dataflow, Game logic, Financial Services, Real-time calculation and more.

🚀 Performance Optimized

  • Zero-cost abstractions through compile-time calculation
  • Minimal runtime overhead with smart change propagation
  • Propagation efficiency at the level of millions per second

🔗 Intelligent Dependency Management

  • Automatic DAG detection and cycle prevention
  • Fine-grained change propagation control
  • Optimize multiple calls due to duplicate dependencies

🛡️ Safety Guarantees

  • Compile-time type checking with C++20 concepts
  • Safe value semantics throughout the framework
  • Framework manages node lifetime internally

🔄 Multi-threading Support

Reaction supports multi-threading with automatic thread safety detection and zero-overhead in single-threaded mode.


🔍 Comparison: QProperty vs RxCpp vs Reaction

| Feature / Metric | 🟩 QProperty (Qt6) | 🟨 RxCpp | 🟥 Reaction | | ------------------------------ | -------------------------------------------- | ------------------------------------------------ | ------------------------------------------------------------ | | Expression Support | ✅ setBinding(), but only single-layer | ✅ Supports chained map, combine_latest, etc. | ✅✅ Fully supports deep nested expressions | | Expression Nesting Depth | ❌ Limited to one layer | ⚠️ Supports nesting, but verbose | ✅ Unlimited depth with automatic dependency tracking | | Update Propagation | Manual propagation per layer | Reactive push chain per layer | Automatic DAG-based propagation with pruning | | Dependency Tracking | ❌ Manual | ⚠️ Manual via operator chaining | ✅ Automatic via lazy evaluation capturing dependencies | | Performance (Update Delay) | ✅ Fast (O(1) propagation) | ❌ Slow (heap allocations and nested chaining) | ✅✅ Fast (pruned update, lazy eval, diffing) | | Memory Usage | ✅ Very low (stack + signals) | ❌ High (many heap-allocated observables) | ⚠️ Moderate (DAG storage, optimized with small object opt.) | | Syntax Simplicity | ✅ Simple (setBinding, value()) | ❌ Verbose template syntax | ✅ Clean expression templates, close to natural syntax | | Type Support | ✅ Built-ins and registered custom types | ✅ Template-based, supports any type | ✅ Type-erased or templated support for any combination | | Container Support | ✅ Can be used in containers | ✅ Can compose multiple observables | ✅ Supports container expressions (e.g. map/filter outputs) | | Threading Model | UI-thread default, manual safety for signals | ✅ Multi-threaded pipelines | ✅ Main thread default, pluggable lock strategies | | Error Handling | ❌ None | ✅ Robust error flow (on_error_resume_next) | ✅ Error node propagation, pluggable failure strategy | | Debuggability | ⚠️ Lambdas harder to trace | ❌ Difficult due to complex types | ✅ Trackable dependencies, observable IDs, chain tracing | | Template Instance Size | ✅ Small | ❌ Huge (template explosion) | ✅ Optimized with type-erasure or instance deduplication | | Build Time | ✅ Fast | ❌ Very slow for large expressions | ✅ Separated headers, controllable instantiation | | Learning Curve | ✅ Low (Qt-style usage) | ❌ Steep (functional style) | ⚠️ Medium (understanding type deduction + expression design) | | Use Case Fit | UI property binding, light state syncing | Asynchronous pipelines, stream logic | UI + state modeling + expression trees with complex logic |


📊 Performance Benchmarks

Comparative performance results against rxcpp and folly (tested on 2025-06-14):

Deep Dependency Test (Tree Structure, Depth=13)

| Framework | Avg. Time (μs) | Iterations | Relative Speed | |--------------------|---------------:|-------------:|---------------:| | reaction | 765 | 901 | (baseline) | | rxcpp | 1664 | 412 | 2.17x slower | | folly | 8760 | 603 | 11.45x slower |

Wide Dependency Test (10,000 Nodes)

| Framework | Avg. Time (μs) | Iterations | Relative Speed | |--------------------|---------------:|-------------:|---------------:| | reaction | 261 | 2,626 | (baseline) | | rxcpp | 721 | 960 | 2.76x slower | | folly | 3769 | 523 | 14.45x slower |

Key Findings:

  1. Deep dependency scenarios: ~2.17x faster than rxcpp, ~11.45x faster than folly
  2. Wide dependency scenarios: ~2.76x faster than rxcpp, ~14.45x faster than folly
  3. Outstanding performance: Reaction demonstrates superior performance across different dependency patterns
  4. Test Environment:
    • 8-core CPU @ 2.8GHz
    • 32KB L1 Data Cache
    • 4MB L2 Unified Cache
    • Linux 5.15.0-78-generic

📦 Requirements

  • Compiler: C++20 compatible (GCC 10+, Clang 12+, MSVC 19.30+)
  • Build System: CMake 3.15+

🛠 Installation

1. From source (manual installation)

To build and install the reaction reactive framework manually:

git clone https://github.com/lumia431/reaction.git && cd reaction
cmake -S . -B build
cmake --install build/ --prefix /your/install/path

After installation, you can include and link against reaction in your own CMake-based project:

find_package(reaction REQUIRED)
target_link_libraries(your_target PRIVATE reaction)

2. Using vcpkg (recommended)

You can also install reaction via vcpkg, which handles dependencies and CMake integration automatically.

  1. Install reaction via vcpkg:
cd /path/to/vcpkg
./vcpkg install reaction
  1. Integrate vcpkg with your CMake project:

When configuring your project, specify the vcpkg toolchain file:

cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=/path/to/vcpkg/scripts/buildsystems/vcpkg.cmake
cmake --build build
  1. Use reaction in your CMakeLists.txt:
find_package(reaction CONFIG REQUIRED)

add_executable(my_app main.cpp)

# Link against the vcpkg-provided target
target_link_libraries(my_app PRIVATE reaction::reaction)

Uninstall

To uninstall the framework:

cmake --build build/ --target uninstall

If you want to run example or test units:

cmake -S . -DBUILD_EXAMPLES=TRUE -DBUILD_TESTS=TRUE -B build
cmake --build build/

🚀 Quick Start

#include <reaction/reaction.h>
#include <iostream>
#include <iomanip>
#include <cmath>

int main() {
    using namespace reaction;

    // 1. Reactive variables for stock prices
    auto buyPrice = var(100.0).setName("buyPrice");      // Price at which stock was bought
    auto currentPrice = var(105.0);                      // Current market price

    // 2. Use 'calc' to compute profit or loss amount
    auto profit = calc([&]() {
        return currentPrice() - buyPrice();
    });

    // 3. Use 'expr' to compute percentage gain/loss
    auto profitPercent = expr(std::abs(currentPrice - buyPrice) / buyPrice * 100);

    // 4. Use 'action' to print the log whenever values change
    auto logger = action([&]() {
        std::cout << std::fixed << std::setprecision(2);
        std::cout << "[Stock Update] Current Price: $" << currentPrice()
                  << ", Profit: $" << profit()
                  << " (" << profitPercent() << "%)\n";
    });

    // Simulate price changes
    currentPrice.value(110.0).value(95.0);  // Stock price increases
    buyPrice.value(90.0);                   // Buy price adjusted

    return 0;
}

📖 Basic Usage

1. Reactive Variables: var

Define reactive state variables with var<T>.

auto a = reaction::var(1);         // int variable
auto b = reaction::var(3.14);      // double variable
  • get value:
auto val = a.get();
  • assignment:
a.value(2);

2. Derived Computation: calc

Use calc to create reactive computations based on one or more var instances.

  • Lambda Capture Style:
auto a = reaction::var(1);
auto b = reaction::var(3.14);
auto sum = reaction::calc([=]() {
    return a() + b();  // Retrieve current values using a() and b()
});
View on GitHub
GitHub Stars618
CategoryDevelopment
Updated41m ago
Forks76

Languages

C++

Security Score

100/100

Audited on Mar 31, 2026

No findings