---
title: Getting Started with ddd_cqrs_es
description: Welcome to the lightweight, infrastructure-light Domain-Driven Design (DDD), CQRS, and Event Sourcing framework for Rust.
---

Welcome to **ddd_cqrs_es**! This library is a lightweight, high-performance Rust framework designed to help you construct highly reliable, testable, and maintainable software systems using the combined power of **Domain-Driven Design (DDD)**, **Command Query Responsibility Segregation (CQRS)**, and **Event Sourcing (ES)**.

The distinguishing design philosophy of this framework is that it is completely **infrastructure-light**. Your core domain logic—the rules that govern how your business operates—is kept entirely free of dependencies on databases, serialization formats, web frameworks, or asynchronous runtimes.

---

## 🚀 Installation

Add the crate as a dependency in your `Cargo.toml`:

```toml
[dependencies]
ddd_cqrs_es = "0.2.3"
```

### Feature Flags

Our framework is highly modular. You can enable specific adapters and engines depending on your production requirements.

#### Enabling Durable Database Adapters:
* **SQLite Support:** Enable the `"sqlite"` feature (uses the `rusqlite` driver under the hood).
* **PostgreSQL Support:** Enable the `"postgres"` feature (uses the `postgres` driver under the hood).
* **MySQL Support:** Enable the `"mysql"` feature (uses the `mysql` driver under the hood).
* **WASI MySQL Helper:** Enable `"wasi-mysql"` for raw TCP MySQL query execution from generic Wasmtime/WASI runtimes.
* **Spin MySQL Helper:** Enable `"spin-mysql"` for Spin SDK MySQL query execution.

#### Supported Backends:
* **SQLite / Local File:** Standard local embedded SQL.
* **PostgreSQL:** Stable high-performance relational database.
* **MySQL:** High-performance relational database with native stores plus runtime query helpers for Wasmtime (`"wasi-mysql"`) and Spin (`"spin-mysql"`).
* **LibSQL / Turso:** Supported for distributed edge SQL via the `"wasi-libsql"` query helper.
* **Redis:** Supported for async event store, checkpoints, and pub/sub notifications via `"redis"` / `"wasi-redis"` / `"spin-redis"`.

#### Realtime and Notification Support:
The root crate provides durable stores, checkpoints, idempotency stores, and notification primitives. HTTP streaming is application-owned.

* **PostgreSQL / SQLite / MySQL:** Use durable events and checkpoints to drive polling, SSE, WebSocket, or worker pipelines in your application.
* **Redis:** Provides experimental async persistence plus notification-only pub/sub wake messages. Durable replay remains the source of truth.
* **MySQL:** MySQL does not provide a built-in pub/sub stream in this library; pair it with Redis, an outbox worker, binlog CDC, NATS, Kafka, or WebSocket fan-out when low-latency push notifications are required.

#### API Notes:
* Aggregates are loaded by the repository using the external stream ID; the `Aggregate` trait does not require an `id()` method.
* `EventType` is a serde-transparent newtype. Convert it with `as_str()` or `into_string()` when a database, UI, or protocol needs a plain string.
* `SqlSchemaConfig` table-name builders validate eagerly and return `Result`.
* Process managers can be coordinated by `ProcessManagerRunner` or `AsyncProcessManagerRunner`.
* `execute_idempotent(...)` is portable but not crash-atomic across separate stores. Use `execute_idempotent_atomic(...)` with native SQL stores for production request idempotency.

| Feature | Description | Third-Party Dependencies |
| :--- | :--- | :--- |
| **`default`** | Standard local, thread-safe in-memory event store and memory projection runners. | None |
| **`sqlite`** | Stable SQLite event store, checkpoint store, idempotency store, snapshot store, and atomic idempotent append. | `rusqlite` |
| **`postgres`** | Stable PostgreSQL event store, checkpoint store, idempotency store, snapshot store, and atomic idempotent append. | `postgres` |
| **`mysql`** | Stable MySQL event store, checkpoint store, idempotency store, snapshot store, and atomic idempotent append. | `mysql` |
| **`wasi-mysql`** | Experimental raw TCP MySQL query helper for generic Wasmtime/WASI runtimes. | `rsa`, `sha1`, `sha2`, `getrandom` |
| **`spin-mysql`** | Experimental Spin SDK MySQL query helper. | `spin-sdk` |
| **`redis`** | Experimental async Redis event store, checkpoint store, pub/sub publisher, and command executor trait. | None |
| **`wasi-redis`** | Experimental raw RESP Redis client for generic Wasmtime/WASI runtimes. | `redis` |
| **`spin-redis`** | Experimental Spin SDK Redis client. | `spin-sdk` |
| **`wasi-http`** | Experimental outbound HTTP helper foundation for WASI runtimes. | `wasip3`, `http`, `http-body-util`, `bytes` |
| **`wasi-neon`** | Experimental Neon HTTP SQL query helper. | `wasi-http` |
| **`wasi-libsql`** | Experimental LibSQL/Turso Hrana HTTP query helper. | `wasi-http` |
| **`wasi-postgres-tcp`** | Experimental raw PostgreSQL TCP query helper for WASI-style runtimes. | `md5`, `base64`, `pbkdf2`, `hmac`, `sha2`, `rustls` |
| **`spin-sqlite`** | Experimental Spin SQLite host-call query helper. | `spin-sdk` |
| **`spin-postgres`** | Experimental Spin PostgreSQL host-call query helper. | `spin-sdk` |
| **`wasi-supabase-rpc`** | Experimental Supabase RPC query helper. | `wasi-http` |

---

## ⚡ Quick 10-Second Example

Here is how simple it is to initialize our write path, tie it to an in-memory event ledger, and execute a transactional command:

```rust
use ddd_cqrs_es::{InMemoryEventStore, Repository, Metadata};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. Initialize a thread-safe, local, in-memory event ledger
    let store = InMemoryEventStore::<BankAccount>::new();
    
    // 2. Bind the ledger to the repository coordinator
    let repo = Repository::new(store);
    let account_id = "account_abc123".to_owned();

    // 3. Execute a transactional command with audit tracking metadata!
    repo.execute(
        &account_id,
        BankAccountCommand::DepositMoney { amount: 100 },
        Metadata::new().with_actor_id("user_alice"),
    )?;

    // 4. Rebuild aggregate state instantly by replaying its historical facts
    let loaded = repo.load(&account_id)?;
    assert_eq!(loaded.state.balance(), 100);
    
    println!("Transaction committed! Balance is: ${}", loaded.state.balance());
    Ok(())
}
```

---

## 🗺️ How to Navigate This Documentation

We structured our guides as a structured, chronological path designed to take you from a complete beginner to building full-scale, distributed production applications:

### Start with the CLI: [ddd CLI](./cli)
* **What you'll learn:** Install the `ddd` command, scaffold a new app with `ddd init`, add domain events and commands with `ddd add`, enable Redis/gRPC/tracing capabilities, run Spin-focused apps, and use dry-run JSON for agent/MCP workflows.

### Module 1: [The Patterns](./theory/ddd) (Theory)
* **What you'll learn:** The architectural foundations. Read about [Domain-Driven Design](./theory/ddd) (aggregate boundaries, Ubiquitous Language), [CQRS](./theory/cqrs) (separating write vs read pipelines), [State Changes](./theory/state-changes) (command validation vs event application), [Queries](./theory/queries) (read models), and [Event Sourcing mechanics](./theory/event-sourcing).

### Module 2: [Domain Modeling (Tutorial)](./tutorial/commands)
* **What you'll learn:** Build a fully validated Bank Account domain step-by-step. Implement [Commands](./tutorial/commands), [Events](./tutorial/events) (implementing `DomainEvent`), [Errors](./tutorial/errors) (handling invariants), and the core [Aggregate Root](./tutorial/aggregate) struct.

### Module 3: [Domain Tests](./testing/complex-logic)
* **What you'll learn:** Write bulletproof business validations in microseconds. Learn why Event Sourcing is a unit-testing superpower and write elegant Given-When-Then tests using the [Aggregate Test Fixture](./testing/complex-logic) API.

### Module 4: [Configuring an Application](./config-app/event-store)
* **What you'll learn:** Assemble your domain parts. Wire up the local [InMemoryEventStore](./config-app/event-store), write a custom [Query Projection](./config-app/simple-query), and [Assemble them together](./config-app/assembly) into a working execution loop.

### Module 5: [Building an Application](./production/persisted-store) (Production)
* **What you'll learn:** Move to production. Start with [Production Guarantees](./production/guarantees), define [Error Handling and Transport Mapping](./production/error-handling), deploy durable [SQLite, PostgreSQL, and MySQL stores](./production/persisted-store), configure asynchronous [Projections with Checkpoint tracking](./production/persisted-views), review production [Database Query Patterns](./production/db-query-patterns), use experimental [Redis persistence and realtime notifications](./production/redis), attach [Metadata trace headers](./production/metadata), write custom [Event Upcasters](./production/upcasters) for schema evolution, and [Integrate with Web Frameworks (Axum)](./production/axum-integration).

### Module 6: [Leptos WASM SSR + Spin CQRS](./tutorial/leptos-ssr) (Production Implementation)
* **What you'll learn:** Put everything together across focused implementation pages. Build the pure domain, Spin/WASI storage adapters, checkpointed projections, Leptos server APIs, reactive UI, runtime backend configuration, and execution playbook for a production-grade full-stack CQRS application.

### Module 7: [Runtimes & Cloud Deployment (Spin vs. Wasmtime)](./wasmtime-vs-spin-comparison)
* **What you'll learn:** Production runtimes and connection engineering. Understand the performance differences between Wasmtime CLI and Fermyon Spin connection pooling. Read our best practice architectural recommendations for database proximity, and learn how to deploy serverless WASM applications to Fermyon Cloud and SpinKube on AWS EKS, GCP GKE, and Azure AKS.

For documentation site indexing details (including where `PRD` and full tutorial pages are registered), see `docs/docs.json`.
