Explore the Library sample
What does an event-sourced Arc feature look like when it reaches a browser? The Library sample takes the authors and books from the shared tutorial and makes the whole path visible: a command returns an event, Chronicle appends it and projects the read model, and an observable query updates the React view.
Open your library
Section titled “Open your library”With Node.js 22.19 or later, Yarn 4, and Docker installed, run from the repository root:
yarn installdocker compose -f Samples/Library/docker-compose.yml up -dyarn workspace @cratis/arc.sample.library devVisit http://127.0.0.1:5173. Register an author, select their name, and add a book. After Chronicle projects the event, the author count and list update without a refresh. The book appears on the selected author’s shelf. Stop the dev process with Ctrl+C, then stop this sample’s kernel with docker compose -f Samples/Library/docker-compose.yml down --volumes. That removes the container and the volumes of its bundled MongoDB, and with them the development data.
Vite sends /api and /.cratis requests to Express on loopback. If the ports are occupied, free ports 3000, 5173, and 35000 before starting.
Trace one feature
Section titled “Trace one feature”Start with Registration.ts. RegisterAuthor.handle() returns new AuthorRegistered(this.name); Arc appends it to the event source marked by @key(). UniqueAuthorName defines a Chronicle append-time constraint across author streams, while the concept validator beside AuthorName checks the name’s shape. @roles('Librarian') requires an authenticated librarian. The local Express host supplies a fixed, trusted demonstration principal, not an authentication mechanism.
Next read Listing.ts: @fromEvent(AuthorRegistered) builds the projected read model, allAuthors watches Chronicle changes, and authorsPage loads a snapshot. Arc handles paging for that small list. In AuthorCatalog.tsx, DataPage receives the generated AllAuthors observable query and provides paging, sorting, and selection. AuthorsPage is a separate snapshot-query example; it does not drive this page. The book slices sit under Features/Books/. See Vertical slices for the TypeScript layout alongside the C# version.
The source generator produces both server metadata and browser proxies. When you change a command or query, regenerate rather than editing generatedMetadata.ts or the co-located *.proxy.ts files by hand. The sample README explains configuration and verification.
What the kernel does
Section titled “What the kernel does”appsettings.json configures Cratis.Chronicle with the Library event store and a local development connection string. The compose image bundles MongoDB as Chronicle’s event store and read-model sink; the application never writes to MongoDB directly. A successful append may precede the projected query update. The sample loads the small catalog before Arc pages it, so do not use that query for an unbounded production list. bash Samples/Library/run-integration.sh starts its own Chronicle container and tests the generated proxy HTTP round trip, including uniqueness and an observable update. It does not exercise the browser UI.
You have now traced a typed React hook through Express into Chronicle and back through a projected observable query. To build the same loop in a project of your own, create an application and then add event sourcing to it. Your first command walks the smaller, infrastructure-free Tasks sample if you want to isolate the Arc decorators.