---
url: /core/domain.md
description: >-
  The domain layer in Domain-Driven Design with TypeScript: the model of the
  business, its objects and rules, free of frameworks and infrastructure.
---

# Domain

The domain is the model of the business: its objects, its rules and what happens to them. It lives
in `domain/` and imports nothing but the domain and `@alveolus/core`.

## Why

When the rule "an order cannot be placed empty" sits in a controller, a SQL query and a cron job,
each copy drifts and nobody knows which one is right. When it imports an ORM or a framework, it
cannot be read or tested without them.

::: tip The fix
The rules live in one place, in plain TypeScript classes named after the business. Everything else
calls them.
:::

## How the blocks fit together

## The building blocks

| Building block | What it is | Use it when |
| --- | --- | --- |
| [Aggregates](./aggregates.md) | A group of objects changed together through one root, which keeps their rules. | Some rules must hold after every change. |
| [Entities](./entities.md) | An object defined by its identity, inside an aggregate. | A part of an aggregate changes over time and must be told apart. |
| [Value objects](./value-objects.md) | An immutable value compared by its attributes, and the typed identifiers. | A number or a string has rules or a unit: an amount, an email, an id. |
| [Domain events](./domain-events.md) | Something that happened in the domain, in the past tense. | Something else must react to a change. |
| [Domain errors](./domain-errors.md) | An expected business failure, returned as a value. | A business rule refuses a request. |
| [Domain services](./domain-services.md) | A stateless operation that belongs to no single object. | A rule needs several aggregates and belongs to none. |
| [Ports](./ports.md) | What the domain needs from the outside world, in its own words. | The domain needs the time, an id, a payment, another context. |
| [Repositories](./repositories.md) | How aggregates are loaded and saved, and how views are read. | An aggregate must be stored, or a query must read data. |
| [Views](./views.md) | What a query returns. | A screen or an API needs data shaped for reading. |

## See also

* [Application](../application/index.md), the use cases that call the domain
* [Strategic](../strategic/index.md), how contexts meet
* Rules: [`layers/no-impure-domain`](../../rules/layers/no-impure-domain.md), [`tactical/no-misplaced-class`](../../rules/tactical/no-misplaced-class.md)
