# ⚡ Aria **Modern C++20 MVVM framework** · cross-platform · layered · coroutine-first One shared core: Windows / macOS / Linux / iOS / Android / Web [![C++20](https://img.shields.io/badge/C%2B%2B-20-blue.svg)](https://en.cppreference.com/w/cpp/20) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Platform](https://img.shields.io/badge/Platform-Windows%20%7C%20macOS%20%7C%20Linux%20%7C%20iOS%20%7C%20Android%20%7C%20Web-lightgrey.svg)](#) [![Build](https://img.shields.io/badge/Build-MSYS2%20%7C%20MSVC%20%7C%20Clang-success.svg)](#) [![Tests](https://img.shields.io/badge/Tests-75%2B%20passed-brightgreen.svg)](#) [English](README.en.md) | [简体中文](README.md) | [HTML Version](README.en.html)
--- ## 🎯 How it compares | | **Aria** | Qt | Flutter | React Native | SwiftUI | |---|---|---|---|---|---| | **Language** | C++20 | C++ / QML | Dart | JS / TS | Swift | | **Core size** | Header-only, ~0 | 100+ MB | ~50 MB SDK | ~200 MB node_modules | Built-in | | **Reactive engine** | ✅ Auto dep-tracking (`Computed`, zero-config) | ❌ Manual `connect` | ✅ but locked to Flutter | ✅ but locked to React | ✅ but locked to Apple | | **C++20 coroutines** | ✅ `Task` + `co_await` | ⚠️ `QCoroutine` (limited) | — | — | — | | **ABI stable** | ✅ Type-erased layer, stable within major | ⚠️ Partial | — | — | — | | **UI toolkit** | ✅ Any (Qt / AppKit / UIKit / JNI / Web / WASM) | ❌ Qt only | ❌ Flutter only | ❌ React only | ❌ SwiftUI only | | **Cross-platform ViewModel** | ✅ One C++ codebase, 6 platforms | ❌ Rewrite QML per platform | ⚠️ Dart cross-plat, non-native UI | ⚠️ JS cross-plat, non-native UI | ❌ Apple only | | **Web** | ✅ HTTP/SSE + WASM (planned) | ❌ | ✅ Web | ❌ | ❌ | | **Macro dependency** | Zero macros | Heavy `Q_OBJECT` / `SIGNAL` / `SLOT` | — | — | — | | **License** | MIT | LGPL / Commercial | BSD | MIT | Apple proprietary | > In short: **aria extracts the reactive engine from the UI framework and makes it a pure C++20 header-only library. Pick any UI toolkit — one ViewModel runs on six platforms.** ## ✨ Core features - 📦 **Header-only core** — `Property` / `Computed` / `Effect` / `Command<>` / `ObservableList` / `Validator` share one reactive dependency-graph engine. `Computed` auto-tracks deps; `reactive::batch` / `reactive::untracked` for fine control. - 🔌 **Type-erased ABI layer** — `aria-abi` / `aria-runtime` / `aria-binding` are ABI-stable within a major version; template layers are source-compatible only. - ⚡ **C++20 coroutines** — `Task`, executors, `co_await schedule_on(pool)`. Async code reads like sync code. - 🖥 **Adapter abstraction** (`IViewAdapter`) — Qt6 / AppKit / UIKit / JNI / HTTP / WASM. Any UI toolkit, same business logic. ## 🏗 Architecture (10 modules) ``` ┌────────────────────────────────────────────────────────────────────────┐ │ Application │ └────────────────────────────────┬───────────────────────────────────────┘ ┌──────────────────┼──────────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ Qt6 adapter │ │ JNI adapter │ │ HTTP adapter │ (optional │ (Win/Mac/Lin)│ │ (Android) │ │ REST/SSE Web │ modules; │ AppKit/UIKit │ │ │ │ WASM planned │ opt-in) └──────┬───────┘ └──────┬───────┘ └──────┬───────┘ └───────────────────┴───────────────────┘ ▼ ┌─────────────────────────────────┐ │ aria-binding (SHARED) │ │ BindingEngine + IViewAdapter │ └────────────────┬────────────────┘ │ ┌──────────────────────┴───────────────────────┐ ▼ ▼ ┌───────────────────┐ ┌────────────────────┐ │ aria-runtime │ │ aria-async │ │ (SHARED .dylib) │ │ (header-only) │ │ EventBus │ │ Task │ │ Container │ │ Scheduler │ │ Dispatcher │ │ Executor │ │ Logger │ │ schedule_on │ └───────┬───────────┘ └─────────┬──────────┘ └──────────────────┬─────────────────────────—┘ ▼ ┌─────────────────────────────┐ │ aria-core (header-only) │ │ Property / Computed / Cmd │ │ ObservableList / Validator │ │ Subscription │ └──────────────┬──────────────┘ ▼ ┌─────────────────────────────┐ │ aria-abi (STATIC .a) │ │ Type-erased Signal/Slot │ │ ABI-stable, no templates │ └─────────────────────────────┘ ``` | Module | Type | Depends on | Notes | |--------|------|-----------|-------| | `aria-abi` | `STATIC` | none | Type-erased signal/slot. No templates. **ABI-stable.** | | `aria-core` | header-only | abi | All the templates: `Property`, `Computed`, `Command`, `ObservableList`, `Validator`. Source-compatible only (not ABI-stable). | | `aria-async` | header-only | core | C++20 `Task`, executors. Source-compatible only. | | `aria-runtime` | `SHARED` | core, abi | EventBus / Container / Dispatcher / Logger — singletons live in **one** dylib. **ABI-stable** (non-template exports). | | `aria-binding` | `SHARED` | core, runtime | `BindingEngine`, `IViewAdapter`. **ABI-stable** (non-template exports). | | Adapters | `SHARED`/`STATIC` | binding | Qt6 / AppKit / UIKit / JNI / HTTP (each opt-in); WASM is planned. | ## 📋 Requirements - **CMake** >= 3.20 - **Compiler** with full C++20 support: - GCC >= 12 (the MSYS2 UCRT64 toolchain on Windows) - Clang >= 15 (AppleClang 15+ on macOS/iOS) - **MSVC v143 / Visual Studio 2022** (Windows, see below) - *(optional)* **Qt6** >= 6.4 (for Qt6 adapter and GUI examples) > **Windows is supported on two toolchains: MSYS2 UCRT64 (GCC) and > MSVC / Visual Studio 2022.** Pick whichever fits your team's existing > stack — both build the full framework + tests + adapters from a single > tree, no source forks. See ["Windows toolchains"](#windows-toolchains) below. ## 🚀 Quick start ```bash git clone https://github.com/dqsjqian/Aria.git cd Aria cmake -B build/flavors/release -DCMAKE_BUILD_TYPE=Release cmake --build build/flavors/release -j ctest --test-dir build/flavors/release --output-on-failure ``` > `build/` is a *container* for build trees — never configure straight into > it. The unified layout (flavors / ide / platforms / examples / dist) is > documented at the top of [`scripts/build.sh`](scripts/build.sh); the > per-flavor script `scripts/build.sh [release|debug|asan|tsan]` picks the > right directory for you. > First configure pulls [doctest](https://github.com/doctest/doctest) via the > bundled `CPM.cmake`. After that everything is offline. ### One-liner build scripts ```bash # macOS / Linux scripts/build.sh # release scripts/build.sh tests # release + ctest scripts/build.sh asan # debug + AddressSanitizer + UBSan scripts/build.sh tsan # debug + ThreadSanitizer scripts/build.sh clean # Windows — MSYS2 UCRT64 (GCC + Ninja) scripts\build.ps1 # release scripts\build.ps1 tests scripts\build.ps1 asan # Windows — MSVC / Visual Studio 2022 scripts\build-msvc.ps1 # release (build/flavors/msvc/ tree) scripts\build-msvc.ps1 tests scripts\build-msvc.ps1 debug scripts\build-msvc.ps1 asan # /fsanitize=address (no UBSan on MSVC) ``` ### Windows toolchains Aria ships with **two parallel build scripts** for Windows. They live side-by-side in `scripts/`, write to separate build directories, and neither one needs to know about the other. | Toolchain | Script | Build dir | Notes | |---|---|---|---| | **MSYS2 UCRT64** (GCC 14+ / Clang 18+) | `scripts\build.ps1` | `build/` | Lightweight (~300 MB). Pre-installed on most CI images. Auto-detected from `C:\msys64\ucrt64\bin` and a few other common paths. | | **MSVC v143** (VS 2022) | `scripts\build-msvc.ps1` | `build/flavors/msvc/` | Auto-detects the VS install via `vswhere`, scrubs MSYS2 env vars (`INCLUDE` / `LIB` / `CPATH` / ...) before running CMake, and uses the `Visual Studio 17 2022` generator. | You can switch back and forth without `clean` — the two trees are isolated. CI runs both nightly to make sure neither regresses. #### MSVC one-time setup ```powershell # 1. Install Visual Studio 2022 Build Tools (or the full IDE) with # workload "Desktop development with C++" + "C++ CMake tools". # 2. (Optional) install Qt 6 with the msvc2022_64 kit if you need the # Qt6 adapter / Qt showcase. # 3. From any PowerShell window: scripts\build-msvc.ps1 tests ``` #### MSYS2 one-time setup ```powershell # 1. Install MSYS2 from https://www.msys2.org # 2. Open the "MSYS2 UCRT64" shell: pacman -Syu pacman -S --needed mingw-w64-ucrt-x86_64-toolchain ` mingw-w64-ucrt-x86_64-cmake ` mingw-w64-ucrt-x86_64-ninja git # 3. (Optional) Add C:\msys64\ucrt64\bin to your PATH. # 4. From any shell: scripts\build.ps1 tests ``` Rationale for shipping both: aria is coroutine-heavy C++20 code that libstdc++, libc++, **and** the MSVC STL all handle cleanly. Pinning a single Windows toolchain artificially excluded a large chunk of users in the .NET / Visual Studio ecosystem — we now validate against MSVC v143 on the same release gate as macOS, Ubuntu, and MSYS2. ### Use it from your own project **Option A — `find_package` after install** (recommended for production): ```bash # In the aria tree: cmake -S . -B build/flavors/release -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr/local cmake --build build/flavors/release -j && sudo cmake --install build/flavors/release ``` ```cmake # In your project's CMakeLists.txt: find_package(aria 1.0 REQUIRED) add_executable(my_app main.cpp) target_link_libraries(my_app PRIVATE aria::aria) # or pick individual modules: aria::core / ::async / ::runtime / ::binding ``` **Option B — vendored (no install)**: ```cmake add_subdirectory(third_party/aria EXCLUDE_FROM_ALL) target_link_libraries(my_app PRIVATE aria::core aria::async) ``` A ready-to-copy template lives in [`templates/quickstart/`](templates/quickstart/). ### Examples aria ships runnable examples covering **every supported UI toolkit**, plus headless console examples that exercise the core with no GUI. **UI showcases — one per toolkit:** | # | Project | Toolkit | Build | What it shows | |----|--------------------------|--------------------|-------|---------------| | 1 | **qt-showcase** | Qt6 (Widgets) | CMake (`ARIA_BUILD_QT6=ON`) | The **flagship demo**: one app, nine tabs, every public feature of the framework — reactive Property/Computed/Effect, Commands, ObservableList + QAbstractListModel, Validator, `Task` + executors, cancellation, retry, `when_all`, EventBus, DI Container, Dispatcher, navigation, two-way binding. | | 2 | **macos-appkit-mvvm** | macOS AppKit (ObjC++) | Xcode | Self-contained Xcode project using `aria` from Objective-C++: an `IViewAdapter` over `NSTextField`/`NSButton`, the same ViewModel driving native AppKit controls. | | 3 | **ios-oc-uikit-mvvm** | iOS UIKit (ObjC++) | Xcode | Self-contained iOS Xcode project: an `IViewAdapter` over `UILabel`/`UITextField`/`UIButton` (Masonry layout), the same ViewModel on iPhone/iPad. | | 4 | **web-mvvm** | Web (HTTP/REST/SSE) | CMake (`ARIA_BUILD_HTTP=ON`) | A C++ ViewModel exposed to the browser via `HttpAdapter` — SSE-pushed state + REST-driven commands, two-way binding, plus a vanilla-JS client (`aria_client.js`). Optional HTTPS. | | 5 | **android-jni-mvvm** | Android (JNI + Compose/View) | Gradle (NDK r26+) | An Android Studio / Gradle project driving the same C++ ViewModel from Kotlin through the `aria-jni` adapter. | **Headless / console examples** (built with `ARIA_BUILD_EXAMPLES=ON`, no GUI): | Project | What it shows | |---------|---------------| | **inspector-demo** | CLI reactive-graph flush tracer — prints the push/pull trace of a live graph (diagnostics / `TraceSink`). | | **plugin-property-demo** | Cross-dylib ABI smoke: a host exe + plugin shared library driving a `Property` purely through the stable, non-template `aria::IProperty` interface across a DSO boundary. Runs as the `cross_dylib_abi_smoke` test. | | **todomvc** | Headless TodoMVC: `ObservableList` + two live `FilteredList` views (active/completed) + `Selection`, all reacting incrementally. Runs as the `todomvc_smoke` test. | Build & run example 1 (Qt): ```bash cmake -S . -B build/flavors/qt-demo -DARIA_BUILD_QT6=ON cmake --build build/flavors/qt-demo -j ./build/flavors/qt-demo/bin/ex_qt_showcase ``` Example 4 (web) needs the HTTP adapter; see [`examples/4-web-mvvm/README.md`](examples/4-web-mvvm/) for run instructions: ```bash cmake -S . -B build/flavors/web-demo -DARIA_BUILD_HTTP=ON cmake --build build/flavors/web-demo --target example_4_web_mvvm ``` The headless examples build by default (`ARIA_BUILD_EXAMPLES=ON`) and run via `ctest` (`cross_dylib_abi_smoke`, `todomvc_smoke`) or directly from `build/flavors//bin/`. Examples 2 and 3 are **not** part of the CMake tree — open the Xcode project and hit Run; example 5 is an Android Studio / Gradle project (NDK r26+): - [`examples/2-macos-appkit-mvvm/mac-oc-mvvm.xcodeproj`](examples/2-macos-appkit-mvvm/) — macOS AppKit - [`examples/3-ios-oc-uikit-mvvm/ios-oc-mvvm.xcodeproj`](examples/3-ios-oc-uikit-mvvm/) — iOS UIKit - [`examples/5-android-jni-mvvm/`](examples/5-android-jni-mvvm/) — Android (Gradle) ### Build options | Option | Default | Description | |--------|--------|-------------| | `ARIA_BUILD_TESTS` | ON | Build unit tests + ctest registration. | | `ARIA_BUILD_EXAMPLES` | ON | Build all examples (console + Qt6 when enabled). | | `ARIA_BUILD_BENCHMARK` | ON | Build the micro-benchmark suite. | | `ARIA_BUILD_SHARED` | ON | Runtime/binding as `.dylib`/`.so`/`.dll` instead of `.a`. | | `ARIA_BUILD_QT6` | OFF | Build Qt6 adapter and GUI examples (requires `Qt6Widgets`). | | `ARIA_BUILD_APPKIT` | OFF | **(production-grade)** macOS AppKit adapter as a first-class CMake module — built as `STATIC` + `.mm`, ships `aria::adapters::appkit`, passes the full `adapter_conformance` test battery. Requires `APPLE`. The standalone AppKit example in `examples/2-macos-appkit-mvvm/` now consumes this adapter via `BindingEngine::bind_text_oneway` / `bind_command`. | | `ARIA_BUILD_UIKIT` | OFF | **(production-grade)** iOS UIKit adapter as a first-class CMake module — built as `STATIC` + `.mm`, ships `aria::adapters::uikit`, passes the in-app conformance battery (25/25 on iPhone 17 Pro Max). Requires `APPLE`. The standalone UIKit example in `examples/3-ios-oc-uikit-mvvm/` now consumes this adapter via `BindingEngine::bind_text_oneway` / `bind_command`. | | `ARIA_BUILD_JNI` | OFF | Build Android JNI adapter as a first-class CMake module — built as `STATIC`, ships `aria::adapters::jni`, implementing the same `IViewAdapter` contract as Qt/AppKit/UIKit via reflective JNI dispatch (text / bool / int / double / visibility / click). Requires an Android NDK toolchain (**NDK r26+** — the C++20-concepts core does not build under NDK r25's libc++). | | `ARIA_BUILD_WASM` | OFF | *(planned)* Build WebAssembly adapter. | | `ARIA_ENABLE_ASAN` | OFF | AddressSanitizer. | | `ARIA_ENABLE_UBSAN` | OFF | UndefinedBehaviorSanitizer. | | `ARIA_ENABLE_TSAN` | OFF | ThreadSanitizer. | ## 👋 Hello, world ```cpp #include "aria/aria.hpp" using namespace aria; Property count{0}; // No explicit dependency list — every Property::get() inside the lambda // is auto-tracked on first evaluation. Computed label([&]{ return "count = " + std::to_string(count.get()); }); Command<> increment([&]{ count = count.get() + 1; }); auto sub = label.bind([](const std::string& s) { std::cout << s << '\n'; }); increment(); // → "count = 1" increment(); // → "count = 2" ``` ## ⚡ Async (C++20 coroutines) ```cpp #include "aria/async/task.hpp" #include "aria/async/executor.hpp" using namespace aria::async; Task fetch_user(int id) { co_await schedule_on(network_pool); // jump to worker thread auto raw = http::get("/users/" + std::to_string(id)); co_await schedule_on(main_dispatcher); // jump back to UI thread co_return parse(raw); } ``` ## 🌍 Cross-platform mapping | Platform | UI host | Adapter | |------------|----------------|------------------------------------| | Windows | Qt6 / WinUI | `aria-qt6` ✅ ready (MSYS2 UCRT64 + MSVC 2022) | | macOS | AppKit / Qt6 | `aria-qt6` ✅ ready; AppKit ✅ ready (example 2) | | Linux | Qt6 / GTK | `aria-qt6` ✅ ready | | iOS | UIKit / SwiftUI bridge | UIKit ✅ ready (example 3); `aria-uikit` module planned | | Android | Compose / View | `aria-jni` ✅ ready (NDK r26+) | | **Web (server-driven)** | **HTML/JS in browser** | **`aria-http` ✅ ready (REST + SSE; example 4)** | | Web (in-browser C++) | DOM via WASM | `aria-wasm` planned | The HTTP adapter ships a small server (`HttpAdapter`) that exposes any ViewModel over a JSON REST + Server-Sent-Events protocol, plus a vanilla-JS browser SDK (`aria_client.js`). The server is built on the vendored single-header **cpp-httplib** (HTTP/1.1 + SSE) and **nlohmann::json** (encode/decode) — both committed under `third_party/`, so the adapter adds no new external build dependency; aria itself owns the wire protocol, view registry, subscription dispatch and SSE fan-out. It is the right shape for desktop apps that want a web UI on the side, headless services, and local debug dashboards. The WASM adapter — which compiles C++ business logic into the browser sandbox — solves a different, more constrained problem and remains on the roadmap. See [RFC 0001](docs/rfc/0001-http-adapter.md) for the design. The **current release** ships the platform-agnostic core, runtime, async, and binding layers — fully unit-tested. Qt6, AppKit, UIKit, JNI, and HTTP are first-class opt-in adapters in the CMake tree (subject to their platform requirements). WASM remains planned; the `IViewAdapter` interface is stable. ## 🧪 Test status ``` $ ctest --test-dir build/flavors/release --output-on-failure Test project /…/aria/build/flavors/release Start 1: abi_tests ✅ Passed Start 2: core_tests ✅ Passed Start 3: fuzz_tests ✅ Passed Start 4: async_tests ✅ Passed Start 5: runtime_tests ✅ Passed Start 6: binding_tests ✅ Passed Start 7: qt6_tests ✅ Passed (when ARIA_BUILD_QT6=ON) Start 8: appkit_conformance ✅ Passed (Apple-only) Start 9: appkit_table_source ✅ Passed (Apple-only) 100% tests passed, 0 tests failed (up to 9 suites, depending on options) ``` 75+ individual test cases across the suites, including dedicated regression tests for the lifecycle / re-entrancy / exception-safety invariants pinned in `docs/reference/lifecycle.md` and `docs/reference/error-model.md`. ## 📊 Benchmark (Apple M-series, -O3 -DNDEBUG) | Operation | ns/op | |-----------|-------| | `Property::get()` | 10.4 | | `Property::set()` no observers | 28.5 | | `Property::set()` 1 observer | 29.3 | | `Property::set()` 10 observers | 45.9 | | Subscribe + auto-unsubscribe cycle | 54.9 | | Computed chain x5 (set + recompute + get) | 289.1 | | `EventBus::publish` (1 subscriber) | 13.4 | | `Container::resolve` | 7.6 | | 10 sets wrapped in `reactive::batch` (notify once) | 156.1 | | Batch update speedup vs individual | **1.91×** | ## 📋 Framework contracts Every non-trivial behaviour Aria promises is pinned in a numbered contract document. Each contract item carries an ID (e.g. `L-13`, `E-22`, `LD-7`, `D-4`, `S-31`) so a failing assertion or PR review comment can point straight at the canonical description. | Document | Prefix | Scope | |---|---|---| | [`docs/reference/api-style.md`](docs/reference/api-style.md) | `S-N` | Naming, namespace, error and async-entry style | | [`docs/reference/lifecycle.md`](docs/reference/lifecycle.md) | `L-N` | Threading, subscription, reactive flush, view-destroy, async cancel/dtor invariants | | [`docs/reference/error-model.md`](docs/reference/error-model.md) | `E-N` | `aria::Error` / `ErrorKind` taxonomy and per-subsystem error contracts | | [`docs/reference/list-diff-contract.md`](docs/reference/list-diff-contract.md) | `LD-N` | `Insert / Remove / Replace / Move / Reset / ItemChanged` semantics | | [`docs/reference/diagnostics.md`](docs/reference/diagnostics.md) | `D-N` | `aria::TraceEvent` + `aria::TraceSink` protocol | | [`docs/reference/performance.md`](docs/reference/performance.md) | `PERF-N` | Complexity bounds and per-operation baselines for every public API | The P0 hard-bedrock pass (see CHANGELOG → *Latest framework-grade hardening*) closed every open contract above; the seven framework-level fuzzers in `modules/core/fuzz/` stress-verify the lifecycle invariants (default 50k iterations / fuzzer; nightly runs set `ARIA_FUZZ_ITERS=1000000`). ## 🗺 Capabilities | Capability | Type | Where | |---|---|---| | Reactive state | `Property` / `Computed` / `Effect` | `aria/reactive/reactive.hpp` | | Commands | `Command` (reactive `can_execute`) | `aria/command.hpp` | | Collections | `ObservableList` + derived `Filtered/Sorted/Mapped/Distinct/Grouped/Paged` | `aria/observable_list.hpp`, `aria/derived/*` | | Selection | `Selection` / `MultiSelection` (SE-1..SE-5) | `aria/selection.hpp` | | Validation | `Validator` / `FormValidator` / `ValidationState` + async rules | `aria/validator.hpp`, `aria/binding/form.hpp`, `aria/async/async_validator.hpp` | | Async | `Task` / `AsyncCommand` / `with_timeout` / `when_any` / `when_all` / `CancellationToken` | `aria/async/*` | | Data fetching | `AsyncResource` (SWR + dedupe) / `Loadable` (5-state) | `aria/async/async_resource.hpp`, `aria/loadable.hpp` | | Navigation | `Navigator` (`push`/`pop`/`push_for_result`, route patterns) | `aria/binding/navigation.hpp` | | Binding | `BindingEngine` / `IViewAdapter` / `IView` / `Converter` / `bind_view_lifetime` | `aria/binding/*` | | Diagnostics | `TraceEvent` / `TraceSink` / `GraphInspector` (zero-overhead off) | `aria/diagnostics.hpp` | **Learn it:** the [documentation index](docs/index.md) links the guides, the [Cookbook](docs/cookbook/README.md) (task-oriented recipes), and the contract references. Build the symbol-level **API reference** with `cmake -B build/flavors/docs -DARIA_BUILD_DOCS=ON && cmake --build build/flavors/docs --target aria_docs`. ## 🗺 Roadmap Aria is open source (MIT License), hosted on [GitHub](https://github.com/dqsjqian/Aria). The single source of truth for what is *not yet done* (and what has been deliberately deferred) lives in [`docs/ROADMAP.md`](docs/ROADMAP.md). For the current capability snapshot, see [`CHANGELOG.md`](CHANGELOG.md). ## 🤝 Contributing Contributions are welcome! Please open an issue first to discuss design changes. - Code style is enforced by `.clang-format` and `.clang-tidy`. - All changes must pass `ctest --output-on-failure`. - New features require tests in the matching `modules/*/tests/` suite. ## 🙏 Acknowledgments - [doctest](https://github.com/doctest/doctest) — lightweight test framework - [nlohmann_json](https://github.com/nlohmann/json) — JSON for Modern C++ - [cpp-httplib](https://github.com/yhirose/cpp-httplib) — HTTP/HTTPS server - [OpenSSL](https://www.openssl.org/) — TLS 1.2/1.3 (3.5 LTS) - [CPM.cmake](https://github.com/cpm-cmake/CPM.cmake) — CMake dependency management ## 📄 License [MIT](LICENSE) © 2026 aria contributors ---
**📖 Alternative Formats** [HTML Version](README.en.html) · [Chinese](README.md) · [Chinese HTML](README.html)