Build

The default backend, end to end

Follow the reference app end-to-end to map every subsystem to a real project structure.

Heads-up: this chapter is a guided tour of the framework's reference app, which lives in the damatjs/damat monorepo. You don't need it to build your own app — but reading it is the fastest way to see every pattern in this guide working together in one place.

@damatjs/default is a complete reference app demonstrating the whole framework: user and organization modules, file-based routes under /api (/api/posts, /api/users/:userId, /api/workflows) plus a top-level /health, cross-module links/, a user-onboarding saga workflow, Redis usage, durable jobs and events, a durable pipeline composing them, headless inspection, process roles, and a same-image Docker setup. Most patterns in this guide are taken directly from it. Its README has the full route and feature list.

To explore it, clone the repo (see Getting started → Option B) and open backend/default/src/. Then trace one feature end to end across the code and the matching chapter:

What to traceWhere it livesChapter
The users table definitionsrc/modules/user/models/Defining models
The user service & generated CRUDsrc/modules/user/service.tsModules & services
GET /api/users/:userIdsrc/api/routes/users/[userId]/Building HTTP APIs
The user-onboarding sagasrc/workflows/Workflows
The cross-module linksrc/links/Composing & linking
reports.generatesrc/jobs/Events & jobs
user.created + two consumerssrc/events/Events & jobs
user.onboard-and-reportsrc/pipelines/Durable pipelines
Atomic enqueue and publishsrc/examples/transactionalWork.tsEvents & jobs
Headless operational inspectionsrc/examples/inspectWork.tsEvents & jobs
Migration/API/jobs/events/pipeline rolesdocker-compose.ymlDeployment

If you can follow one row of that table through the code, you understand the framework — everything else is more of the same.

The five Compose roles use the same built image. The one-shot migration role finishes first; API runs HTTP only, while jobs and events run as headless workers and pipelines runs its router/internal worker, all selected by environment variables.