Skip to main content

Introduction to Angzarr

⍼ Angzarr is a polyglot framework for building event-sourced systems. You write business logic in any language with gRPC support—the framework handles event persistence, saga coordination, projection management, and all the infrastructure complexity that typically derails CQRS/ES projects.

The symbol ⍼ (U+237C, "angzarr") has existed in Unicode since 2002 without a defined purpose. The right angle represents the origin point—your event store. The zigzag arrow represents events cascading through your system. We gave it meaning.

Project Status

This codebase uses AI-generated code under human supervision. The implementation has been reviewed, but with an emphasis on velocity over thoroughness.

This is not AI slop. The gRPC/protobuf definitions were hand-written and have evolved with heavy oversight. The architecture and code derive from an earlier human-written Go codebase—ported to Rust and used as the starting point—when the author switched for performance, binary size, and cleaner deployment mechanisms. Polyglot support has always been a core design goal—world domination requires meeting developers where they are. Architecturally, it's sound—the framework design reflects years of thinking about CQRS/ES patterns.

Approaching production-ready, but not there yet. The code is stabilizing and mostly working, but plan for additional testing and hardening before production deployment.

Contributors are welcome. There are a few rough edges, but mostly the project needs code review, test coverage expansion, and developers willing to build on it and report what breaks. If you're interested in CQRS/ES tooling and want to be an early adopter, jump in.


What Angzarr Provides

Angzarr inverts the typical framework relationship. Rather than providing libraries that applications import, Angzarr provides infrastructure that applications connect to via gRPC.

Your data model lives in .proto files, not code. Commands, events, and state are defined as Protocol Buffer messages—language-neutral, versionable, and shared across all implementations. This is what enables true polyglot support: the same event stream can be produced by a Rust aggregate and consumed by a Python projector.

You DefineYou ImplementWe Handle
Commands in .protoAggregate handlersEvent persistence
Events in .protoProjector handlersOptimistic concurrency
State in .protoSaga handlersSnapshot management
Event upcasting
Event distribution
Saga coordination
Schema evolution

Your business logic receives commands with full event history and emits events. No database connections. No message bus configuration. No retry logic. Pure domain logic.


Architecture Preview

⍼ Angzarr stores aggregate history as an EventBook—the complete event stream for a single aggregate root: its identity (the Cover), an optional Snapshot for efficient replay, and ordered EventPages representing domain events.

The dashed Domain B represents any additional domain(s)—sagas bridge events from one domain to commands in another. Real systems have multiple domains, each with its own aggregate.

Each component type runs in its own pod with an ⍼ Angzarr sidecar. Your code handles business logic; the sidecar handles persistence, messaging, and coordination.


Language Support

Any language with gRPC support works. Your business logic communicates with ⍼ Angzarr coordinators via gRPC—the framework doesn't care what's behind the endpoint. If your language appears on the gRPC supported languages matrix, you can use it with Angzarr. This includes C#, C++, Dart, Go, Java, Kotlin, Node.js, Objective-C, PHP, Python, Ruby, Rust, and more.

Client libraries are optional and minimal. For six languages (the top TIOBE languages), we provide thin client libraries that reduce boilerplate—protobuf packing/unpacking, state reconstruction, router registration. These libraries are intentionally kept lightweight; the real contract is just gRPC + protobuf. You can always work directly with the proto bindings if you prefer:

LanguageClient LibraryExample
Pythonangzarr-clientexamples/python/
Gogithub.com/benjaminabbitt/angzarr/clientexamples/go/
Rustangzarr-clientexamples/rust/
Javadev.angzarr:clientexamples/java/
C#Angzarr.Clientexamples/csharp/
C++header-onlyexamples/cpp/

All six implementations share the same Gherkin specifications, ensuring identical behavior across languages.


Quick Example

Two styles, same behavior: Functional (pure functions) and OO (class-based with decorators).

Free functions following guard → validate → compute. Easy to unit test—call directly with state, assert on output.

def deposit_guard(state: PlayerState) -> None:
"""Check state preconditions before processing deposit."""
if not state.exists:
raise CommandRejectedError("Player does not exist")


# docs:end:deposit_guard


# docs:start:deposit_validate
def deposit_validate(cmd: player.DepositFunds) -> int:
"""Validate deposit command and extract amount."""
amount = cmd.amount.amount if cmd.amount else 0
if amount <= 0:
raise CommandRejectedError("amount must be positive")
return amount


# docs:end:deposit_validate


# docs:start:deposit_compute
def deposit_compute(
cmd: player.DepositFunds, state: PlayerState, amount: int
) -> player.FundsDeposited:
"""Build FundsDeposited event from validated inputs."""
new_balance = state.bankroll + amount
return player.FundsDeposited(
amount=cmd.amount,
new_balance=poker_types.Currency(amount=new_balance, currency_code="CHIPS"),
deposited_at=now(),
)


No database code. No message bus code. Just business logic.


For Decision Makers

If you're evaluating Angzarr for your organization:

  • Technical Pitch — Complete architectural pitch with detailed rationale
  • Architecture — Core concepts: data model, coordinators, sync modes
  • Why Poker — Why our example domain exercises every pattern

For Developers

Ready to build:

  • Getting Started — Prerequisites, installation, first aggregate
  • Components — Aggregates, sagas, projectors, process managers
  • Examples — Code samples in all six languages

Next Steps

  1. Understand the patternsCQRS & Event Sourcing Explained
  2. See the architectureArchitecture
  3. Get hands-onGetting Started