Domain-First Approach
Starting development by building the domain layer with in-memory storage, deferring database and infrastructure decisions.
The domain-first approach means you start building your application by writing the domain layer, using an in-memory repository instead of a real database. You focus entirely on business rules, entities, and value objects. The database decision comes later.
In practice, this looks like spending the first iteration (or iterations) working only on domain types, backed by unit tests and a simple in-memory storage implementation. You explore the problem space, iterate on the model, and validate assumptions without committing to a specific database. Because there's no database to set up, feedback loops are fast: you run unit tests in seconds.
This approach works because Clean Architecture and the Repository Pattern let you swap storage implementations behind an interface. Your domain code doesn't know or care whether data lives in a map, PostgreSQL, or Firestore. When you're ready to pick a database, you implement the repository interface against it. The domain layer stays untouched.
The practical benefit goes beyond deferring a decision. When you start with the database, your domain types tend to mirror database tables. Fields, types, and relationships get shaped by what's easy to store, not by what the business needs. Starting with the domain avoids this trap. Your types are shaped by business rules, and the database model adapts to them, not the other way around.
The trade-off is that this requires trust from the business side. Spending weeks without a "real" database can feel uncomfortable if stakeholders expect visible infrastructure progress. Setting a timebox helps: agree on some time for domain-only work, then integrate a database. Once you get the domain part right, the rest can be surprisingly easy to implement.
Domain-first also works well with Mob Programming. Modelling the domain layer from scratch is easier when the whole team thinks through it together. Just keep in mind this needs even more trust from the business, since there won't be anything to show for a while. It pays off in the long run, since everyone is on the same page and you don't need the usual code review.
The domain-first approach pairs naturally with API-First Design. While domain-first defers storage decisions, API-first defers implementation decisions by starting with the contract. Both share the same idea: focus on the core problem before committing to infrastructure.
References
- Introduction to DDD Lite: When microservices in Go are not enough — Introduces the Domain-First approach as a tip for complex projects: spend 2-4 weeks working on the domain layer with an in-memory database, deferring the database choice. All implementation is based on unit tests.
- The Repository pattern in Go: a painless way to simplify your service logic — Shows how the Domain-First approach leads to starting with an in-memory repository implementation. Explains that deferring the database decision saves time and leads to better database models shaped by the domain, not the other way around.
- Combining DDD, CQRS, and Clean Architecture in Go — Applies the Domain-First approach to refactor an existing application. Starts by introducing a domain layer so implementation details don't affect domain code, noting the approach works for both rescue and greenfield projects.