Documentation
Summary. This is the index of the long-form documentation of ddd-ts-kit. Four entries are normative, two short reference documents first: the architecture reference (the canonical tree, the rule ids, the tactical and clean code conventions, the test levels) and the configuration reference; then the pipeline README (the quality gates) and the README of each package. Everything else explains and teaches: the concepts behind the rules, the tool decisions with their comparisons and limits, and guides for working on such a project as a team and with coding agents. When a page here and the architecture reference disagree, the reference is right.
In French. Every page listed here has a French translation next to it (X.fr.md), reached
by the link on its first line; the French index is README.fr.md. Its diagrams
have French labels, and its code samples are compiled by the pipeline like the English ones.
On the web. These pages, the README of every package and the documents of the example are also published as a website, with search, in English and in French: https://gbourgeat.github.io/ddd-ts-kit/. The Markdown files here stay its only source.
Reference (normative)
Section titled “Reference (normative)”| Page | What it holds |
|---|---|
| Architecture reference | the canonical tree, every rule id, the tactical rules, tests, clean code |
| Configuration | every key of ddd-ts-kit.config.json |
| Pipeline | the quality gates, the git hooks, GitHub and GitLab side by side |
Package READMEs under packages/ |
what each package does, its limits and what was verified |
Concepts: one page per idea
Section titled “Concepts: one page per idea”Ordered as a reading path in concepts/README.md.
| Page | In one line |
|---|---|
| Domain and subdomains | core, supporting, generic: how to classify and what it changes |
| Bounded context | what a boundary is, and the language, autonomy and consistency tests |
| Ubiquitous language | the glossary-first rule and how a glossary is written |
| Context map | the relationship patterns, when each fits and what it costs |
| Context map: a worked example | the scheduling application, from a statement of needs to its map |
| Entities and value objects | identity versus value, and primitive obsession |
| Aggregates | consistency boundary, one transaction, reference by id, sizing |
| Domain building blocks | domain event, domain service, repository, factory |
| State machines | the lifecycle of an aggregate: states, transitions, guards, refusals, its diagram |
| Invariants, permissions, validation | three different things in three places |
| Anemic model | how to recognise one, and when a thin model is fine |
| Layers and the dependency rule | hexagonal, onion, clean: what they share, where they differ |
| Ports and composition | ports as abstract classes, the composition root, declared or explicit wiring |
| The presentation layer | one controller class per route, route groups, guards at the edge and permissions on the use case, mapper and serializer |
| Representations, field access and forms | one schema in JSON, XML or CSV by content negotiation, fields reserved to a permission, forms described by the server for each caller |
| CQRS | command and query buses, and event sourcing as a separate choice: what it buys and what it does not |
| Modular monolith | one deployable, contexts kept extractable |
| Domain and integration events | the two kinds of events and the translation between them |
| Transactional outbox | the dual write problem, the outbox, relay strategies |
| Delivery and idempotency | at-least-once, idempotent consumers, ordering |
| Eventual consistency | explained to a product person |
| Sagas and process managers | long-running processes: what the kit provides and what it does not |
| Event versioning | evolving a published event |
| Event sourcing, per aggregate | when to keep an aggregate as its events, what it costs, upcasters, crypto-shredding, projections fed by the store, migrating to it and back |
| Authentication and authorization | RBAC, ABAC, ReBAC compared, with a decision table |
| Authorization in practice | @Requires, the bus middleware, the Authorizer port and policies, followed through one command |
| Actor and execution scope | the explicit actor, and what every unit of work carries |
| Multitenancy | the tenant from the edge to the storage: isolation strategies, propagation, elevation of platform staff, the proof |
| Audit trail | tamper-evident history recorded around the use cases |
| Observability | tracing, logs, metrics, error reporting, the correlation id |
| Resilience | retry, timeout, circuit breaker, bulkhead, cache and their failure modes |
| HTTP caching | what to cache at which layer, cache policies, never a decision of authorization across actors |
| File storage | files in a storage, never in the database: staged before the transaction, moved to their key with the commit, served by short signed links |
| Scheduled jobs | jobs that trigger use cases, several instances, idempotence |
| Background jobs | work enqueued in the transaction of a command, run by a worker at least once, leases, checkpoints |
| File import and export | a design, not built: a large file read or written by a background job, batch by batch, between the queue and the file storage |
| Clean code | naming, small functions, stepdown, comments, with before and after |
| Testing strategy | fakes versus mocks, builders, contract tests, the four levels |
Tools: one page per decision
Section titled “Tools: one page per decision”Each page has a comparison table, selection criteria, what the kit supports and verified, the limits, and a recommendation by situation.
| Page | The decision |
|---|---|
| HTTP frameworks | Express, Fastify, Hono or NestJS, and what framework-agnostic routes cost with Nest |
| Validation | zod, class-validator, TypeBox or a Standard Schema library; shared schemas |
| Contract pairs | which framework with which validation library, by team: the four pairs proven end to end, measured; why not oRPC |
| Representations and forms | XML and CSV without a library, and why; JSON Forms renderers for React, Angular and Vue, and the alternatives |
| Dependency injection | tsyringe with the kit's declarations, NestJS, or manual wiring |
| Persistence | Drizzle, Knex, Prisma or TypeORM; PostgreSQL versus others |
| Message brokers | in-process, RabbitMQ, Kafka, NATS JetStream or Redis Streams |
| Cache and coordination | Redis, Dragonfly or Valkey; what the lock does and does not guarantee |
| HTTP caches | Varnish, Souin, nginx, Fastly, Cloudflare or Bunny in front of the API: how each purges by tag, what the kit verified |
| File storage connectors | memory, local directory or S3 compatible (AWS, MinIO, OVHcloud, Scaleway, R2); how to write one for Google Cloud Storage or Azure |
| Identity | Keycloak or plain OIDC and JWT |
| Authorization engines | in-process models versus OpenFGA, SpiceDB, Cedar, OPA |
| Observability | OpenTelemetry with Jaeger or Tempo; loggers; Sentry or GlitchTip |
| Static analysis and pipeline | the checker, the ESLint plugin, dependency-cruiser, knip, TypeScript 6 and 7; GitHub or GitLab |
| Quality baseline | what every project gets and what each tool answers: type check, lint, format, dead code, import graph, architecture check, tests |
| Test runners | Vitest or Jest |
| Client SDK | openapi-typescript with openapi-fetch, hey-api or orval, measured on the example contract, against the client ddd-ts-kit sdk writes: typed error codes, no dependency; how it is checked and published |
| Import aliases | @/, declared once under tsconfig paths and rewritten into relative paths by the build; imports without an extension by default, and why the build writes the .js Node needs; why not a Node subpath import; what each tool reads |
Guides
Section titled “Guides”| Page | For |
|---|---|
| Methodology | the end-to-end path from a statement of needs to running code, step by step: the supported path |
| Which command, when | the command or skill for each moment of a project, a first feature from zero, and the reference of every command and flag |
| One slice, end to end | the request POST /orders through the four layers of a generated slice, and its domain and application code once filled |
| The plugin for coding agents | installing the plugin in Claude Code, Codex and Copilot, its twenty-two skills, four agents and hook, and what each host runs |
| Team workflow | ownership per context, the glossary, contracts first, review, decisions, onboarding |
| Parallel work | several people or agents at once: what is safe, what is sequenced, a concrete plan |
| Commit discipline | commit and pull request size, generated files, what hooks and CI enforce |
| When to extract microservices | the signals, the costs, a readiness checklist, the steps, when to merge back |
| Bootstrap with well-designed contexts | a generic context written whole with --preset identity: what it writes, what it asks of the stack, how it composes with each access model and with tenants |
| Choosing access control | five questions that pick roles, attributes or relationships (Zanzibar), worked presets for each, the combined model of the example, scopes and refusals at the edge |
| Token economy | spending fewer tokens with coding agents, and complementary tools |
| The French documentation | contributors: how every page keeps its French translation current, the glossary, the style of the diagrams, the code samples the pipeline compiles |
Proposals
Section titled “Proposals”| Page | Status |
|---|---|
| Which contexts deserve a preset | the criteria, then notification next, personal data requests as a guide; files (a capability of the platform), audit, billing and settings no |
| The read side | criteria, representations, forms, read models and projections; the page says, part by part, what is built in the runtime packages, what the CLI does not generate yet and what is not built |
Start from a question
Section titled “Start from a question”| Your question | Where the answer is |
|---|---|
| Where does this file go, and what may it import? | the architecture reference, 2. Canonical tree and 3. Dependency rules |
| Why was this reported, and how do I fix it? | npx ddd-ts-kit explain <rule-id>, then When something is refused |
| Which command, or which skill, now? | Which command, when |
| Does this rule belong in the aggregate, the handler or the schema? | Invariants, permissions, validation |
| Why does the generator refuse my name? | Ubiquitous language: a name comes from the glossary of its context |
| How does one context react to another? | Domain and integration events, then Transactional outbox |
| How do I test a handler without a mock? | Testing strategy |
Which value for a stack key? |
the tools page of the decision, then Configuration |
| A rule does not fit this project | Deviations: a recorded decision, never a silent off |
| What changes after an upgrade of the kit? | Migrate after a kit upgrade and a key left out of stack |
Part of the reference also answers in the terminal of a project, from the installed version of the kit, so it never disagrees with the code you run:
npx ddd-ts-kit rules # every rule id, its severity and what it holdsnpx ddd-ts-kit explain imports/alias-only # why a rule exists, a bad and a good example, how to suppress itnpx ddd-ts-kit generate --help # every kind of file the generator writes, and its flagsnpx ddd-ts-kit describe billing # one context as facts: use cases, routes, events, portsSuggested reading order
Section titled “Suggested reading order”New to DDD. Follow the reading path of concepts/README.md in order, at least sections 1 and 2, then:
- Layers and the dependency rule
- Domain and integration events and Eventual consistency
- Testing strategy
- Methodology, to see the ideas as steps
- the architecture reference, which will now read as a summary
Tech lead adopting the kit.
- the root README and the architecture reference
- Methodology
- the tools pages for the decisions you have to take, starting with Persistence, Message brokers and Static analysis and pipeline
- Modular monolith and When to extract microservices
- Team workflow, Parallel work, Commit discipline
- Token economy, if the team works with coding agents
- Configuration
Contributor to the kit.
CONTRIBUTING.mdat the root, then the architecture reference: a change of rule starts there- Ports and composition and Layers and the dependency rule
- the README of the package you change, and of the CLI and the ESLint plugin, which hold the rules
- Static analysis and pipeline and Testing strategy
- the tools page of the area you touch: it states what was verified and what was not, which is where a contribution is most useful
- The French documentation, before changing a page: its French translation changes in the same pull request