Getting started with the Cratis templates
This tutorial takes you from an empty folder to a running Cratis application: an ASP.NET Core backend with Arc commands and queries, Chronicle storing events locally, and a React page that registers an item and shows it in a list.
Before you begin
Section titled “Before you begin”The C# path below needs:
- The .NET 10 SDK. Every .NET template targets
net10.0, andnet10.0is its only--Frameworkchoice. - Docker with the Compose plugin (
docker compose). The generateddocker-compose.ymlruns the Chronicle development image and an Aspire dashboard. - Node.js
^20.19.0or>=22.12.0(what Vite 8 accepts) and a package manager: yarn (the default), pnpm, or npm.
The Kotlin and Java variants need a JDK 17 instead of the .NET SDK to build. See the Kotlin template and the Java template.
Install the templates
Section titled “Install the templates”dotnet new install Cratis.TemplatesTo install a specific version, append it: dotnet new install Cratis.Templates::<version>.
See what is available
Section titled “See what is available”dotnet new list cratisYou should see four rows: cratis, cratis-aspire, cratis-chronicle-console, and cratis-chronicle-web. The cratis row lists [C#],Java,Kotlin because the package carries all three languages of the web application; --language picks one. Each template documents its own options:
dotnet new cratis --helpScaffold your first application
Section titled “Scaffold your first application”dotnet new cratis -n MyStorecd MyStoreThe post-creation actions add the Cratis NuGet packages at their current release (the generated .csproj records the exact versions), restore them, and install the frontend dependencies with yarn. dotnet new asks before it runs the yarn step; accept it. To choose the package manager or database up front, pass them as options:
dotnet new cratis -n MyStore --packageManager npm --Database MongoDBIn a script, CI job, or dev container where there is no interactive terminal, opt in to the yarn step explicitly with --allow-scripts yes. Without it, dotnet new keeps waiting for a yes or no answer it cannot receive.
The project includes a .yarnrc.yml that sets nodeLinker: node-modules, so Yarn 2 and later install into node_modules instead of Plug’n’Play, which the TypeScript 7 compiler cannot resolve. npm, pnpm, and Yarn 1 ignore the file.
Two ways to scaffold: dotnet new and cratis new
Section titled “Two ways to scaffold: dotnet new and cratis new”The Cratis CLI can scaffold the same templates with its own template engine:
cratis new # interactive wizardcratis new list # list the templatescratis new cratis --language csharp -n MyStore -o MyStoreThe differences that matter on a first run:
--language(csharp,kotlin, orjava) is required when you name a template.--allow-scriptsdefaults tono, so pass--allow-scripts yesto install frontend dependencies.cratis newsets up the project’s AI guidance itself, so you skip thecratis ai updatestep below.
See Creating projects with cratis new for the full command reference.
Set up AI assistance
Section titled “Set up AI assistance”Every template ships a .cratis/ai.json that selects the Cratis AI profiles, languages, and coding-agent harnesses for that template. After dotnet new, install the Cratis CLI and run this from the project root:
cratis ai updateIt installs the Cratis-managed rules, skills, and harness integration (AGENTS.md plus .claude/, .cursor/, .github/, .opencode/, and .pi/) and records every installed file in .cratis/ai.manifest.json. Commit the result so your team shares the same guidance. Running it again later refreshes only files Cratis installed; cratis ai status reports whether a newer revision is available.
Start the infrastructure
Section titled “Start the infrastructure”docker compose up -dThis starts the cratis/chronicle:latest-development image, which bundles Chronicle with MongoDB, and an Aspire dashboard at http://localhost:18888. Chronicle is ready when this prints Healthy:
curl --insecure https://localhost:35000/healthRun it
Section titled “Run it”Start the backend:
dotnet runIt listens on http://localhost:5000; Swagger UI is at http://localhost:5000/swagger. In a second terminal, start the frontend dev server:
yarn devVite serves the frontend on http://localhost:9000, opens it in your browser, and forwards /api, /.cratis, and /swagger to the backend. Open Demo, select Register, and enter a name. The backend terminal logs Registered: <name> from the sample reactor, and the name appears in the list.
You can also register from the terminal:
curl -X POST http://localhost:5000/api/some-module/some-feature/registration \ -H "Content-Type: application/json" \ -d '{ "name": "Cratis" }'A successful call returns "isSuccess":true and, in response, the identity the event was appended under.
To see the event itself, open the Chronicle Workbench at https://localhost:35000, accept the self-signed development certificate, and sign in with the development account described in Workbench — Development.
Stop and clean up
Section titled “Stop and clean up”Stop the backend and the Vite server with Ctrl+C, then stop the containers and keep their data:
docker compose stopTo remove the containers instead, run docker compose down. With the default MongoDB setup, events and read models live inside the Chronicle container, so this deletes them. With --Database SQLite, Chronicle writes its files to the chronicle-data folder in your project instead, which docker compose down leaves in place; delete the folder to start over.
Troubleshooting
Section titled “Troubleshooting”yarn buildreportsCannot find module. Yarn 2 or later installed with Plug’n’Play, usually because.yarnrc.ymlis missing (projects scaffolded from earlier template versions do not have one). Add a.yarnrc.ymlcontainingnodeLinker: node-modulesand runyarn installagain.docker compose upreports that a port is already allocated. Another Chronicle, MongoDB, or dashboard is using 35000, 27017, or 18888. Stop it, or change the host side of the mapping indocker-compose.ymland updateCratis:Chronicle:ConnectionStringandCratis:MongoDB:Serverinappsettings.jsonto match.docker-compose: command not found. Projects scaffolded from older template versions print the standalonedocker-composespelling. The Compose plugin’sdocker composeaccepts the same arguments.- The backend cannot reach Chronicle. Check that the health command above prints
Healthy. The firstdocker compose updownloads the image, which can take several minutes.
Keep the templates current
Section titled “Keep the templates current”dotnet new updateThis updates every installed template package. To remove the templates, run dotnet new uninstall Cratis.Templates.
Next steps
Section titled “Next steps”- The Cratis Web Application template walks through the sample slices and the generated TypeScript proxies.
- The Chronicle documentation explains events, projections, and reactors.