Get started
The fastest way to understand Chronicle is to watch one fact travel through it. So that’s what we’ll do here: install a template, scaffold a tiny app, and run it. In a couple of minutes you’ll have appended an event and seen it ripple out into both a read model and a live reaction — the loop that every Chronicle application is built on.
We won’t write much code yet — the template gives us a working example to read. Once it’s running and the shape makes sense, the tutorial picks up the thread and has you build a real domain from scratch.
Prerequisites
Section titled “Prerequisites”- The .NET SDK — .NET 8 or newer.
- Docker with Compose. Chronicle runs as a small kernel next to your app, and the template wires it up with a
docker-compose.ymlso you don’t have to install anything else.
Scaffold and run it
Section titled “Scaffold and run it”-
Install the Cratis templates. This adds a family of
dotnet newstarters — a console one for learning the core, and a full-stack web one with a React frontend.Install the templates dotnet new install Cratis.Templates -
Scaffold a project. Start with the console template — it’s the smallest thing that exercises the entire event-sourcing loop, and it’s the one the tutorial builds on.
Scaffold the console starter dotnet new cratis-chronicle-console -o Librarycd LibraryScaffold a full-stack app dotnet new cratis -o Librarycd LibraryThis gives you an Arc + Chronicle backend with a React frontend and generated, type-safe proxies. The event-sourcing concepts are identical — there’s just a UI on top. When it’s running, continue with Build a full-stack feature.
-
Start Chronicle. The template ships a
docker-compose.ymlfor the Chronicle kernel and its storage. Bring it up in the background:Start the Chronicle kernel docker compose up -d -
Run the app.
Run it dotnet runThe scaffolded program appends one event and reacts to it. You’ll see the reaction print, then the app waits for a keypress:
Output Received event with message: Hello world!
That one line of output is the whole point — let’s unpack how it got there.
What you just ran
Section titled “What you just ran”That one line came out of a complete Chronicle loop. Here it is as an event model — a fact is appended, a projection folds it into a read model, and a reactor acts on it:
The template’s Program.cs is about twenty lines, and it wires up exactly those three blocks. Here’s the heart of it:
using var client = new ChronicleClient();var eventStore = await client.GetEventStore("ChronicleConsole");
await eventStore.EventLog.Append("some-event-source", new TestEvent("Hello world!"));Reading top to bottom: a ChronicleClient connects to the kernel you just started with Docker, you ask it for an event store by name, and you append a TestEvent to its event log. That Append is the only thing that changes anything — everything below reacts to it.
The event itself is just a record marked as a fact:
[EventType]public record TestEvent(string Message);And two artifacts sit waiting for that fact to happen. A projection folds the event into a read model — state you can query — declaratively, with no update code:
[FromEvent<TestEvent>]public record TestProjection( string Message, [SetFromContext<TestEvent>(nameof(EventContext.EventSourceId))] string EventSource);A reactor does something when the event arrives — here, it writes the line you saw:
public class TestReactor : IReactor{ public Task React(TestEvent @event) { Console.WriteLine($"Received event with message: {@event.Message}"); return Task.CompletedTask; }}Notice what you didn’t write: no registration, no wiring, no “on startup, subscribe this handler to that event”. Chronicle discovers the event, projection, and reactor by convention — the [EventType] attribute, the IReactor marker, the [FromEvent<>] attribute — and routes the appended fact to each. That convention-over-configuration discovery is what keeps a growing Chronicle app from drowning in plumbing.
See it in the workbench
Section titled “See it in the workbench”The Docker image includes the Chronicle workbench — a web UI for poking at your event store. Open http://localhost:8080, choose the ChronicleConsole event store, and look at Sequences: there’s your TestEvent, sitting at sequence number 0, permanent and in order. Append more and watch the log grow. This is the source of truth your projection and reactor were both reading from.
Where to go next
Section titled “Where to go next”- Build something real, step by step — the tutorial builds a small library system one concept at a time, and explains each as you go. It’s the best next stop.
- Wire Chronicle into an existing app — choose a hosting model, run the kernel, then follow the guide for ASP.NET Core, a Worker Service, or a bare Console.
- Understand the model — Why Event Sourcing makes the case, and the Concepts section defines every term you just met.
- Go full-stack — put commands and a React UI on top with Build a full-stack feature.