---
title: Integrate with Chronicle
description: Add Chronicle's event-sourced write path to an Arc application while keeping Arc's commands, queries, identity, tenancy, and generated proxies.
---


`Cratis.Arc.Chronicle` connects Arc's command pipeline to [Cratis Chronicle](https://github.com/Cratis/Chronicle). Commands can return events for automatic appending, resolve projected state as dependencies, and use tenant context to select an event-store namespace. Arc continues to generate TypeScript clients from the command and query contracts.

Arc does not require Chronicle, and Chronicle does not require Arc. That independence is useful for adoption and bounded current-state slices. In a full Cratis information system, though, this integration is the natural pairing: Arc gives the CQRS boundary and Chronicle keeps the event-sourced facts underneath it.

## How the two fit together

The frameworks meet at one seam: an Arc **command** appends a Chronicle **event**, a Chronicle **projection** folds events into a **read model**, and an Arc **query** serves that read model back — with the generated TypeScript proxy carrying both ends to React.

```mermaid
flowchart LR
    UI[React] -->|command| CMD["[Command] record · Handle()"]
    CMD -->|returns an event| EV[(Chronicle event log)]
    EV -->|projection| RM["[ReadModel] · materialized to the sink"]
    RM -->|query| UI
```

Reading that loop in code:

- **A command writes by _returning_.** A `[Command]` record carries the command's inputs as its **properties**, and the decision lives in a `Handle()` method on the record. Whatever `Handle()` **returns** is what Chronicle does with it — return an `[EventType]` event and it's appended; the [return signature](/arc/backend/csharp/chronicle/commands/events/) (a single event, several, a tuple, a `Result<,>`, or nothing) decides the outcome. Returning events is the recommended path; [transactional commands](/arc/backend/csharp/chronicle/commands/transactional-commands/) documents explicit append alternatives and their boundaries.
- **The event source id picks the stream.** Every event belongs to one **event source** — one entity's stream of history. Chronicle resolves that id from the command: a `[Key]` parameter, an `EventSourceId` or `EventSourceId<T>`-derived property, or `ICanProvideEventSourceId`. See [Resolving EventSourceId](/arc/backend/csharp/chronicle/resolving-event-source-id/).
- **The read model is projected, then queried.** A `[ReadModel]` record declares the shape you want; `[FromEvent<T>]`, `[SetFrom<T>]`, and `[SetValue<T>]` map events onto its properties and Chronicle keeps it **materialized** in the configured sink (MongoDB by default). An Arc query — a static method on the read model, often returning an observable so the UI stays live — serves it through the generated proxy. See [Read Models](/arc/backend/csharp/chronicle/read-models/).
- **The loop closes: a command can read the state it helped build.** When a decision depends on what's already true, the command doesn't query for it — Arc resolves the read model for the command's key and hands it to the validator, `Provide()`, or `Handle()` as a parameter. See [Use current state in a command](/arc/scenarios/use-current-state-in-a-command/).

So the round-trip is: a fact happens (command → event), it's folded into state (projection → read model), and the UI reads it (query → proxy) — and the next command can read that same state to decide. Each piece is one of the topics below.

## What it provides

Without this package, Arc and Chronicle are independent. With it:

- **Commands return events** — `Handle()` methods on commands can return event records directly; the package appends them to the correct event log automatically.
- **Event source resolution** — command input metadata selects the stream identity; authenticated identity and ordinary query binding are separate.
- **Read models backed by projections** — Chronicle backing artifacts supply materialized or passive state. A materialized query can lag behind an append.
- **Tenant-aware event stores** — each tenant's event log and projections are namespaced automatically, matching Arc's tenancy model.
- **Compliance integration** — read-model interception requests PII release; append subjects come from command/event metadata, not automatically from authenticated identity. See the compliance reference for failure and passive-path limits.
- **Aggregate support** — aggregate roots are discoverable and invocable via the standard command pipeline, with Chronicle managing the event stream and rehydration.
- **Current state as a command dependency** — a command's `CommandValidator<>`, `Provide()`, and `Handle()` can each take the read model Chronicle projected for the command's key as an ordinary parameter, so a state-dependent decision needs no query round-trip.

## Topics

| Topic | Description |
| --- | --- |
| [Aggregates](/arc/backend/csharp/chronicle/aggregates/) | Working with aggregate roots and event sourcing. |
| [Add event sourcing to an Arc slice](/arc/backend/csharp/chronicle/add-event-sourcing/) | Move one database-backed slice to Chronicle while keeping its query and React screen in place. |
| [Cratis Package](/arc/backend/csharp/chronicle/cratis-package/) | The convenience package for Arc + Chronicle applications. |
| [React to an event](/arc/backend/csharp/chronicle/react-to-an-event/) | Run side effects or follow-up commands from Chronicle events with reactors. |
| [Commands](/arc/backend/csharp/chronicle/commands/) | Returning events from commands, event source id resolution, and concurrency scoping. |
| [Resolving EventSourceId](/arc/backend/csharp/chronicle/resolving-event-source-id/) | Command identity selection, dependency timing, and the separate query-binding boundary. |
| [Read Models](/arc/backend/csharp/chronicle/read-models/) | What makes a read model injectable into a command, how it is resolved by key, and what happens when it does not exist. |
| [Tenancy](/arc/backend/csharp/chronicle/tenancy/) | Tenant-aware namespaces for event stores and projections. |
| [Validation](/arc/backend/csharp/chronicle/validation/) | Validating a command against the state Chronicle already projected for its key. |
| [Compliance](/arc/backend/csharp/chronicle/compliance/) | PII decryption on read models and compliance subject resolution on commands. |
| [Code Analysis](/arc/backend/csharp/chronicle/code-analysis/) | Diagnostics and analyzers specific to the Chronicle integration. |
