Skip to content

Why developers choose Cratis

Why developers choose Cratis

Build the system you modeled

Developers choose Cratis when they want the domain model, backend, frontend, identity boundary, UI, and operations view to line up. Chronicle, Arc, Components, AuthProxy, the CLI, and the AI tooling are opinionated in the same direction: write the behavior once, keep the contract typed, choose the right storage, handle the hard cross-cutting concerns, and make the running system inspectable. Get started → · Build a full-stack feature →

The pieces fit together

Chronicle, Arc, Components, AuthProxy, Studio, and the tools use the same domain language and conventions, so the stack feels designed as one platform.

Less glue between layers

Commands and queries become HTTP endpoints and generated TypeScript proxies. You do not hand-write controllers, DTO mirrors, or fetch wrappers for every feature.

A compiler-enforced boundary

The frontend imports code generated from the backend. If C# changes, TypeScript changes with it, and drift becomes a build error.

Predictable by convention

Cratis is opinionated about names, folders, attributes, and discovery. The conventions make codebases consistent, and analyzers catch convention drift at build time.

A feature you can read top to bottom

A slice keeps intent, state, screen, and specs together. You change one behavior without spelunking through layers.

End-to-end foundations

Authentication, tenant resolution, identity enrichment, authorization, and tenant-isolated data are first-class parts of the platform, not scattered application boilerplate.

History you can trust

We treat event sourcing as the default for information systems. Chronicle records immutable facts and derives read models from them, so audit and replay are part of the design.

Screens that follow the model

Components renders generated commands and observable queries as forms, dialogs, and tables, so UI code stays close to the model.

AI can work with it

The same conventions that help developers navigate the codebase are packaged as AI skills, rules, and diagnostics, so agents build with the grain of the framework.

Specs read like the model

Given/when/then specifications line up with event modeling: existing facts, a command, and the facts or read models that should result.

Operations without guesswork

Inspect events, observers, read models, replay, and diagnostics from the CLI and Workbench instead of guessing what the runtime is doing.

The point is not that Cratis has many packages. The point is that the packages agree about how an application is shaped. A command, an event, a read model, a tenant, an identity, a React form, and an operating tool are not separate islands with separate conventions. They are parts of one model.

ConcernWhere Cratis carries it
Domain behaviorStudio models it, Arc turns it into commands and queries, Chronicle records the facts as the default source of truth for information systems
Frontend contractArc generates TypeScript proxies from C#, and Components renders those proxies as forms, dialogs, and live tables
Chronicle client boundaryChronicle exposes gRPC/protobuf contracts, with .NET as the first-class client and TypeScript and Elixir clients/contracts for other runtimes
Chronicle storageMongoDB, PostgreSQL, Microsoft SQL Server, and SQLite implementations let the event store fit the deployment
Runtime scaleChronicle runs its kernel on .NET Orleans, so event sequences, observers, jobs, and long-running processing live on a distributed actor runtime
Authentication and tenant resolutionAuthProxy handles the edge and forwards trusted identity and tenant context into the app
AuthorizationArc gates commands and queries at the boundary, with identity details available in backend and React
Tenant isolationArc tenancy and Chronicle namespaces keep one tenant’s state away from another’s by construction
Operations and observabilityWorkbench, CLI, OpenTelemetry, recommendations, replay, jobs, failed partitions, and diagnostics expose what the runtime is doing
TestingCratis Specifications, Arc command scenarios, and Chronicle in-process scenarios turn an event-model column into executable given/when/then specs
AI assistance.ai skills, editor rules, analyzers, the CLI catalog, and the Chronicle MCP server give agents the same rails developers use

That is why the opinions matter. They make codebases consistent. Consistency makes onboarding faster, reviews sharper, and AI assistance far less speculative.

Chronicle is more than a .NET package. It is a client-server event platform with an open protocol boundary and a kernel built for long-running event processing.

Cratis is not just a set of libraries. It changes the shape of the work:

Instead of…You work with…
Duplicating request and response shapes in C# and TypeScriptOne C# command/query model, generated into typed frontend proxies
Spreading one feature across controllers, handlers, clients, and UI foldersA vertical slice organized by behavior
Rebuilding screens by hand after a writeObservable queries and components that follow the read model
Rebuilding authentication, tenancy, and identity plumbing per serviceAuthProxy at the edge, Arc identity and tenancy inside the app, Chronicle namespaces underneath
Teaching every developer and AI assistant a project-specific architecture from scratchStrong conventions, analyzers, and .ai guidance that make each feature look like the rest
Locking event history to one application language or database engineChronicle’s gRPC boundary, .NET/TypeScript/Elixir clients/contracts, and MongoDB/PostgreSQL/SQL Server/SQLite storage implementations
Debugging from logs aloneEvents, observers, read models, and replay visible through the tools
Treating CQRS and event sourcing as the same decisionArc for the command/query boundary, Chronicle for the event-sourced backbone — independent, but strongest together

The result is a workflow that stays close to the language developers already use: “what happened?”, “what state does this screen need?”, “what command changes it?”, and “what did the runtime do with it?”

The core pieces are built to stand alone. Each solves a complete problem by itself, so you can adopt exactly the part you need and nothing more:

  • Chronicle on its own is an event-sourcing engine you can run from any .NET host — a worker, a console app, a different web framework. The .NET client is the most mature path, but the kernel boundary is gRPC/protobuf and the repo also ships TypeScript and Elixir clients/contracts. Append events, build projections, react to them. No Arc, no React required.
  • Arc on its own is a full-stack CQRS framework with generated, typed C# → TypeScript proxies. Its commands and queries can persist straight to MongoDB or EF Core / SQL when you deliberately want CQRS without an event log (here’s the standalone shape). You still get the typed frontend, the command forms, and live queries.
  • Components on its own is a React library that renders Arc’s generated proxies as forms, tables, and dialogs.
  • AuthProxy on its own is a gateway for authentication, tenancy, identity enrichment, routing, and invites in front of any backend and frontend you point it at.

We think event sourcing is the default architecture for information systems. We also think CQRS is the right way to shape information going into and out of a system. Those ideas fit extremely well together and are often associated, but they are not co-dependent: you can use Chronicle without Arc, and Arc can run without Chronicle.

The dependency only runs one way. Arc is a layer that can sit on top of Chronicle — but Chronicle never knows Arc exists, which is why each works without the other. AuthProxy sits at the edge and can front the app whether Arc is backed by MongoDB, EF Core, or Chronicle. What the full combination changes is how much of the application is handled by one coherent set of conventions.

Arc

command / query

+ typed proxies

MongoDB

EF Core / SQL

Chronicle

event sourcing

You want…Reach forEvent sourcing?
History as the source of truth, from any backend or client runtimeChronicle on its ownYes
An event store over MongoDB, PostgreSQL, Microsoft SQL Server, or SQLiteChronicle with the matching storage backendYes
A typed full-stack app over a traditional databaseArc + Components over MongoDB / EF CoreNot required
Authentication, tenancy, identity enrichment, and routing at the edgeAuthProxy in front of your servicesOptional
A typed full-stack app and a full event historyArc + Chronicle + Components — the domain loopYes
A product-grade SaaS shape with edge, identity, tenant isolation, typed UI, history, and operationsAuthProxy + Arc + Components + Chronicle + CLIDefault

The last row is where Cratis is at its best, and it is the default recommendation for a new information system. New to the stack? Choosing where to start walks through how to start there, or how to adopt one piece at a time in an existing system.

Put AuthProxy at the edge, pick Chronicle as Arc’s persistence, and add Components. A single user action now carries identity and tenant context through the whole stack with no manual API layer in between:

typed proxy via AuthProxy

tenant + identity

appends

projected into

served by query

typed proxy

Browser

AuthProxy

auth + tenant + identity

React UI

(Components)

Command

(Arc)

Event

(Chronicle)

Read model

(Chronicle)

Query

(Arc)

You write the command, the event, and the projection once in C#. AuthProxy resolves identity and tenant. Arc generates the typed client and enforces authorization at the boundary. Components renders it. Chronicle keeps the facts and tenant isolation underneath. When the command’s shape changes, the frontend types change with it — the compiler tells you what to fix instead of production telling your users.

Cratis is opinionated on purpose. The opinions are what make it productive:

  • Events are facts. Immutable, past-tense, single-purpose. We use them as the default source of truth for information systems; if you reach for a nullable field on an event, you need a second event.
  • Open boundaries keep options open. Chronicle is a kernel with gRPC/protobuf contracts. .NET is first-class, but the protocol lets other client runtimes participate.
  • Storage is a deployment choice. Chronicle supports MongoDB, PostgreSQL, Microsoft SQL Server, and SQLite without changing the domain model.
  • High cohesion through vertical slices. Everything for one behavior — command, events, projection, UI, specs — lives in one folder, backend and frontend together.
  • Full-stack type safety. Models flow from C# through proxy generation to TypeScript, with no manual synchronization — the proxy boundary is what keeps the two languages honest.
  • Cross-cutting concerns are first-class. Identity and access, authorization, tenancy, AuthProxy, and Chronicle namespaces are part of the platform story.
  • Operability is architecture. Workbench, CLI, OpenTelemetry, recommendations, replay, jobs, and failed-partition recovery are part of how you run the event store.
  • Specifications are executable models. Testing with Cratis maps event modeling’s given/when/then flow to Arc command specs and Chronicle event/read-model/reactor scenarios.
  • Easy to do the right thing. Convention over configuration and artifact discovery by naming mean less boilerplate and fewer ways to get it wrong.
  • Predictable code helps humans and AI. The conventions are documented, packaged as AI tooling, and enforced by code analysis, so a new feature looks like the rest of the system.

When Cratis is a good fit — and when it isn’t

Section titled “When Cratis is a good fit — and when it isn’t”

Because the products are separable, “is Cratis a good fit?” is really a set of connected questions.

Is Arc a good fit? Reach for it whenever you’re building a .NET backend with a TypeScript/React frontend and you’re tired of hand-writing the layer between them — controllers, DTOs, fetch wrappers, validation duplicated on both sides. Arc is the CQRS boundary: commands for things entering the system, queries for information leaving it, with generated contracts between C# and TypeScript.

Is event sourcing a good fit? For information systems, our default answer is yes. Reach for Chronicle when the system records decisions, process, responsibility, tenant state, compliance, integrations, or any place where “how did we get here?” will become a real question. The exception is a genuinely current-state-only slice — reference data, settings, small admin surfaces — where Arc over a database can be the simpler boundary. Why Event Sourcing explains why we think the default pays off.

When neither fits — a couple of static pages, a non-.NET backend, or a throwaway prototype — Cratis is more than you need, and that’s fine.